Ich sehe bei meinem Node 64287-tuccity hohe Last, typisch > 0.4, mit Spikes von 1-1.5, auch wenn fastd nicht viel zu tun hat.
Wenn in top/ps dhcpv6.script br-client ra-updated auftaucht, sind das in der Regel gleich 3-8 Instanzen auf einmal, z.B.
Das Ticket #1304 würde dazu passen, aber evtl. spielt auch etwas ffda-spezifisches rein und andere haben ähnliche Beobachtungen gemacht, deshalb das Posting hier.
(In meiner Nachbarschaft hat auch 64287-omnomcaek ähnlich hohe Loads, das ist aber ein 841er.)
Beobachtungen:
Nach einem Downgrade auf beta (1.2.6 / gluon-v2018.1.1-4-g51b7928a) sind mit top/ps ebenfalls mehrere Instanzen sichtbar, Load ist aber im normalen Rahmen (typisch < 0.2). Zum Vergleich der Load-Graph (vom 19.-26.11. lief beta, danach testing).
Wahrscheinlich macht die in #1304 genannte Verringerung des Update-Delays auf 3 Sekunden das Problem einfach offensichtlicher.
Ich hatte in dhcpv6.script einen Holzklotz-Limiter eingebaut, à la: wenn letzter Skript-Aufruf vor < 3 Sekunden => exit.
Der Load ging zwar etwas runter (s. 15.-18.11. im Graph), es gab aber immer noch mehrere Instanzen. Ich denke, dass das Locking versagt, weil die Skript-Aufrufe quasi gleichzeitig stattfinden.
script_call() in script.c killt bei einem neuen Aufruf das laufende Skript, k.A. was das für Nebenwirkungen hat. Jedenfalls kommen 10-15% der Instanzen, die es bis zum ersten echo "o-" >> test.log schaffen, nicht bis zum Ende des Skripts.
Weiss leider nicht, wie so ein RA-Update aufgebaut ist, oder was odhcp6c genau tut, kommt mir aber vor wie:
Ein Update mit n Einträgen wird geparst, aber im nächsten Schritt wie n einzelne Updates behandelt.
Die schlagen dann gleichzeitig auf, und das 3 Sekunden-Delay wird ausgehebelt.
HTH, Dustin
Firmware: 1.3~20181118 / gluon-v2018.1-127-g601f5df3 (gleiches Problem mit älteren Snapshots)
Geräte-Modell: TP-Link CPE210 v1.0
Wenn das erneut das Problem ist, dann können wir das leicht testen. Mein Vorschlag:
Ich bereite dir mal ein Testimage vor, wo ich den Delay wieder hochsetze. Das lässt du dann ein paar Tage laufen und dann sehen wir, ob das die Ursache der Load war.
Zeile 400: - if (diff > delay) + if (diff < delay)
, sonst ist delay immer <= 0, und der Child-Prozess rennt durch, ohne zu warten.
Zeile 398, kill() fork() usw.
Das laufende Skript zu killen und neu zu forken verbrennt IMHO unnötig Rechenzeit. Das Problem ist wohl, dass die DHCP-Einträge nur im Parent-Prozess aktualisiert werden, und die Einträge des Childs während des sleep(delay) veralten.
Evtl. könnte man auf sleep() verzichten, und statt dessen z.B. mit waitpid(.. WNOHANG ..) testen, ob das Skript noch läuft. Falls nein && (now - last_update >= delay): neu forken.
Trade-off: ein Update während des Delays wird nicht (gleich) umgesetzt.
Anscheinend will man für RA-Updates ein delay von mind. 1 Sekunde (script_accu_delay = 1). Das kann aber schiefgehen, weil mit ganzen Sekunden gerechnet wird.
(4.) 1.-3. erklären wahrscheinlich noch nicht, warum es überhaupt zu mehreren gleichzeitigen(?) Updates kommt. (Soll/muss das so sein?)
Edit: Mein Vorschlag zu 2. taugt nichts. Bin davon ausgegangen, dass nach ein paar Sekunden sowieso das nächste Update kommt, aber es gibt ja auch andere Setups.
Wenn eine hohe Update-Frequenz die Regel und nicht die Ausnahme ist, ist die jetzige Methode sehr ineffizient.
Das ist erstmal eine echte Verbesserung. Meine Befürchtung war auch, dass das jetzige Gluon-testing Nodes mit kleinerer Hardware ganz ausbremsen würde.
IMHO ist aber eher script_call() das Problem, evtl. auch die Verarbeitungsschritte davor. Bei einer anderen Implementierung wären Intervalle von 3 Sekunden wahrscheinlich unproblematisch.
Ich versuche erstmal, eine Firmware mit der geänderten Zeile 400 zu kompilieren, und schaue, was da rauskommt.
Das kill() müsste den Child-Prozess dann in der Regel schon bei sleep(delay) erwischen, nicht erst nach dem exec(). Das sollte schon jede Menge CPU-Zyklen einsparen.