Skip to content

Commit 92eac8f

Browse files
committed
Release 26.09.44: Control Center writes /sys in place (#93)
skillfish-cc-helper wrote every file through a .tmp and a rename. sysfs has no rename and no file creation, so every write to /sys failed with EACCES, even as root: Tuner > Cores > Apply ("Permission denied: .../cpu1/online.tmp"), the SMT switch, and the performance governor the CPU benchmark sets (that one was swallowed, so the benchmark silently ran on whatever governor was on). The old tuner helper wrote directly; this came with the Control Center. _wr now writes /sys and /proc in place and keeps the .tmp route for real files. The helper also keeps the core_id of every CPU it sees online in /var/lib/skillfish/cpu-topology.json, because an offline CPU has no topology in sysfs: the n // 2 guess is right on the BC-250 (threads 2k, 2k+1) and wrong on PCs numbered otherwise. Tested on the .32 by the other session: the installed helper reproduces the user's error on cpu6/online.tmp; the fixed one switched core 3 off and on (16, 14, 16 threads, cpu6/7 0 then 1) and recorded all sixteen core_ids as n // 2. The board was left as it was.
1 parent e8762bb commit 92eac8f

3 files changed

Lines changed: 58 additions & 2 deletions

File tree

‎SECURITY.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ report those to their respective projects.
1616
| Kernel | `7.2.6-skillfishos` (+ `-x64`) | yes |
1717
| Kernel | `7.2.0-skillfishos`, `7.1.7-skillfishos` | previous series, best effort |
1818
| Kernel | `7.0.11-skillfishos` and older | no |
19-
| Apps | `skillfish-*` `26.09.43` or newer | yes |
19+
| Apps | `skillfish-*` `26.09.44` or newer | yes |
2020

2121
Fixes are delivered through the signed APT repository — `sudo apt update && sudo apt upgrade`.
2222
The installed system does not point at a single address: it carries a mirror list

‎apps/control-center/os.skillfish.control-center.metainfo.xml‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,19 @@
6969
</screenshot>
7070
</screenshots>
7171
<releases>
72+
<release version="26.09.44" date="2026-09-22">
73+
<description>
74+
<p>Switching cores on and off in the Tuner works again. Every change to the processor settings ended in "Permission denied" and changed nothing: the cores, the SMT switch, and the governor the CPU benchmark sets. The window wrote those settings the way it writes a configuration file, and the kernel does not accept that for processor settings. Measured on a BC-250: one core switched off and back on, 16 threads, then 14, then 16 again.</p>
75+
<p xml:lang="it">Accendere e spegnere i core nel Tuner torna a funzionare. Ogni modifica alle impostazioni del processore finiva in «Permission denied» e non cambiava niente: i core, l'interruttore SMT e il governor che imposta il benchmark della CPU. La finestra scriveva quelle impostazioni come si scrive un file di configurazione, e il kernel per le impostazioni del processore non lo accetta. Provato su una BC-250: un core spento e riacceso, 16 thread, poi 14, poi di nuovo 16.</p>
76+
<p xml:lang="fr">Allumer et éteindre les cœurs dans le Tuner fonctionne de nouveau. Chaque changement des réglages du processeur finissait en « Permission denied » sans rien changer : les cœurs, l'interrupteur SMT et le gouverneur que règle le benchmark CPU. La fenêtre écrivait ces réglages comme un fichier de configuration, et le noyau ne l'accepte pas pour les réglages du processeur. Vérifié sur une BC-250 : un cœur éteint puis rallumé, 16 threads, puis 14, puis 16.</p>
77+
<p xml:lang="es">Encender y apagar núcleos en el Tuner vuelve a funcionar. Cada cambio en los ajustes del procesador acababa en «Permission denied» y no cambiaba nada: los núcleos, el interruptor SMT y el gobernador que pone la prueba de CPU. La ventana escribía esos ajustes como se escribe un archivo de configuración, y el kernel no lo acepta para los ajustes del procesador. Probado en una BC-250: un núcleo apagado y vuelto a encender, 16 hilos, luego 14, luego 16 otra vez.</p>
78+
<p xml:lang="pt">Ligar e desligar núcleos no Tuner volta a funcionar. Cada alteração às definições do processador acabava em «Permission denied» e não mudava nada: os núcleos, o interruptor SMT e o governador que o teste de CPU define. A janela escrevia essas definições como se escreve um ficheiro de configuração, e o kernel não aceita isso para as definições do processador. Testado numa BC-250: um núcleo desligado e religado, 16 threads, depois 14, depois 16 outra vez.</p>
79+
<p xml:lang="de">Kerne im Tuner ein- und ausschalten funktioniert wieder. Jede Änderung an den Prozessoreinstellungen endete mit „Permission denied“ und änderte nichts: die Kerne, der SMT-Schalter und der Governor, den der CPU-Test setzt. Das Fenster schrieb diese Einstellungen wie eine Konfigurationsdatei, und das nimmt der Kernel für Prozessoreinstellungen nicht an. Auf einer BC-250 geprüft: ein Kern aus- und wieder eingeschaltet, 16 Threads, dann 14, dann wieder 16.</p>
80+
<p xml:lang="pl">Włączanie i wyłączanie rdzeni w Tunerze znów działa. Każda zmiana ustawień procesora kończyła się komunikatem „Permission denied” i niczego nie zmieniała: rdzenie, przełącznik SMT i governor ustawiany przez test CPU. Okno zapisywało te ustawienia tak jak plik konfiguracyjny, a jądro tego dla ustawień procesora nie przyjmuje. Sprawdzone na BC-250: jeden rdzeń wyłączony i włączony ponownie, 16 wątków, potem 14, potem znów 16.</p>
81+
<p xml:lang="ru">Включение и выключение ядер в Tuner снова работает. Любое изменение настроек процессора заканчивалось «Permission denied» и ничего не меняло: ядра, переключатель SMT и регулятор, который выставляет тест CPU. Окно записывало эти настройки так же, как файл конфигурации, а ядро для настроек процессора так не принимает. Проверено на BC-250: одно ядро выключено и снова включено, 16 потоков, потом 14, потом снова 16.</p>
82+
<p xml:lang="uk">Увімкнення й вимкнення ядер у Tuner знову працює. Будь-яка зміна налаштувань процесора закінчувалася «Permission denied» і нічого не змінювала: ядра, перемикач SMT і регулятор, який виставляє тест CPU. Вікно записувало ці налаштування так само, як файл конфігурації, а ядро для налаштувань процесора так не приймає. Перевірено на BC-250: одне ядро вимкнено й знову ввімкнено, 16 потоків, потім 14, потім знову 16.</p>
83+
</description>
84+
</release>
7285
<release version="26.09.43" date="2026-09-21">
7386
<description>
7487
<p>The GPU test and the CU test work on every installation now. They run vkpeak, and until now they looked for it only in a folder that existed on our development boards, so on a normal system they answered that vkpeak was missing. vkpeak now comes as its own package, skillfish-vkpeak, built by us from its source, and it is installed with this update.</p>

‎apps/control-center/skillfish-cc-helper‎

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,18 @@ def _rd(path):
8484

8585

8686
def _wr(path, data):
87+
"""Write a whole file.
88+
89+
Configuration files go through a .tmp and a rename, so a crash never leaves
90+
half a file. Kernel attributes in /sys and /proc are written in place: no
91+
file can be created there, and the .tmp route failed with EACCES on every
92+
one of them (issue #93: cpuN/online, and with it smt/control and the CPU
93+
governor the benchmark sets).
94+
"""
95+
if path.startswith(("/sys/", "/proc/")):
96+
with open(path, "w") as f:
97+
f.write(data)
98+
return
8799
tmp = path + ".tmp"
88100
with open(tmp, "w") as f:
89101
f.write(data)
@@ -454,8 +466,36 @@ def persist_cpu():
454466
sh("systemctl enable bc250-smu-oc.service")
455467

456468

469+
# An offline CPU has no topology/ in sysfs, so its core can't be read back.
470+
# Every core_id seen while a CPU is online is kept here, and an offline CPU is
471+
# placed with what was recorded. Without it the guess was n // 2: right on the
472+
# BC-250, which pairs threads as (2k, 2k+1), wrong on a PC numbered otherwise,
473+
# where "switch core 1 back on" then found no core 1 to switch on.
474+
CPU_TOPO = "/var/lib/skillfish/cpu-topology.json"
475+
476+
477+
def _topo_load():
478+
try:
479+
with open(CPU_TOPO) as f:
480+
return {int(k): int(v) for k, v in json.load(f).items()}
481+
except (OSError, ValueError, AttributeError):
482+
# first run, or a file we can't read: start from what is online now
483+
return {}
484+
485+
486+
def _topo_save(topo):
487+
try:
488+
os.makedirs(os.path.dirname(CPU_TOPO), exist_ok=True)
489+
_wr(CPU_TOPO, json.dumps({str(k): v for k, v in sorted(topo.items())}) + NL)
490+
except OSError:
491+
# read-only or full disk: the guess below still works on the BC-250
492+
pass
493+
494+
457495
def cpu_cores_get():
458496
cores = {}
497+
topo = _topo_load()
498+
seen = dict(topo)
459499
for p in sorted(glob.glob("/sys/devices/system/cpu/cpu[0-9]*")):
460500
n = os.path.basename(p)[3:]
461501
if not n.isdigit():
@@ -465,6 +505,7 @@ def cpu_cores_get():
465505
core = int(_rd("%s/topology/core_id" % p).strip())
466506
except Exception:
467507
continue
508+
seen[n] = core
468509
online = True if not os.path.exists(p + "/online") else _rd(p + "/online").strip() == "1"
469510
cores.setdefault(core, {"core": core, "cpus": [], "online": False, "removable": True})
470511
cores[core]["cpus"].append({"cpu": n, "online": online, "removable": os.path.exists(p + "/online")})
@@ -479,9 +520,11 @@ def cpu_cores_get():
479520
n = int(n)
480521
if any(c["cpu"] == n for e in cores.values() for c in e["cpus"]):
481522
continue
482-
core = n // 2
523+
core = seen.get(n, n // 2)
483524
cores.setdefault(core, {"core": core, "cpus": [], "online": False, "removable": True})
484525
cores[core]["cpus"].append({"cpu": n, "online": False, "removable": True})
526+
if seen != topo:
527+
_topo_save(seen)
485528
smt = None
486529
try:
487530
smt = _rd("/sys/devices/system/cpu/smt/control").strip()

0 commit comments

Comments
 (0)