bktr kann keinen Speicher allokieren

Wasp

Insektenspray-Gegner
Wenn ich nach längerer Laufzeit des Rechners versuche kldload bktr auszuführen, scheint dieser keinen Speicher belegen zu können obwohl laut top sogar noch 301 MB komplett frei und weitere 693 MB inaktiv sind -- also daran sollte es nicht liegen.

Dieses Problem habe ich erst seit einer (von cd, also frischen) Installation von FreeBSD 8.1 Release. Unter FreeBSD 6.2 stable ging das laden von bktr auch noch nach länger Laufzeit des Rechners noch problemlos und verfuhr dort auch immer so.

Code:
bktr_mem: memory holder loaded
bktr0: <BrookTree 848> mem 0xfdeff000-0xfdefffff irq 18 at device 8.0 on pci1
bktr0: [GIANT-LOCKED]
bktr0: [ITHREAD]
bktr0: Unable to allocate 1310720 bytes of memory.
bktr0: Unable to allocate 3555328 bytes of memory.
bktr0: Hauppauge Model 56304 C   
bktr0: Hauppauge WinCast/TV, Temic PAL tuner.

Das ich bktr nicht wieder entladen kann, fand ich immer schon etwas doof, aber es jetzt nicht mal mehr laden zu können... . Offensichtlich liegt etwas anderes schief, da es vor FreeBSD 8.x mit der selben TV-Karte noch ging.

Auf gute Ideen oder besser noch Lösungen hofft,
Wasp


PS: Nein, ich möchte bktr nicht mit dem Systemstart laden. ;) Das geht zwar, liegt aber wohl nicht im sinne des Erfinders.
 

nakal

Anfänger
Manche Module kann man nur ausschließlich zur Boot-Zeit laden (anderes bekanntes Beispiel: nvidia.ko). Ich weiß nicht mehr wie das mit bktr(4) früher bei mir war, aber ich habe es ziemlich sicher immer per loader.conf geladen.
 

Wasp

Insektenspray-Gegner
Weder nvidia.ko noch bktr.ko müssen zur laufzeit geladen werden. Bei nvidia kann ich hier allerdings nur von alten Versionen reden, bei neueren weiß ich es nicht, aber ich weiß, daß es bei bktr.ko geht/gehen sollte. Werde das gleich noch mal überprüfen, aber wenn ich X.org beende -- und damit gezwungenermaßen eigentlich auch alles andere was hier läuft -- kann ich den bktr laden. Manchmal ging es auch so später noch -- denke immer, wenn ich noch nicht so viel gemacht/geladen habe.
 

nakal

Anfänger
Sie müssen zur Boot-Zeit geladen werden. Wenn du das nicht machst mit DRM-Zeug, dann wird speziell gestalteter Speicher nicht alloziert werden können und dann flackert Xorg wie sau (keine 2D-Beschleunigung).
 

Yamagi

Possessed With Psi Powers
Teammitglied
bktr.ko ja, nvidia.ko nicht zwingend... Bei nVidia kommt es wohl auf die Kombination aus Karte, RAM-Menge und andere Hardware an. Auf meiner Workstation kann ich das Modul problemlos zur Laufzeit laden und entladen, auf der Ersatzkiste hingegen greift er die Karte nur zur Bootzeit.
 

nakal

Anfänger
Meine Vermutung ist, dass wenn der Speicher (physikalisch) zu fragmentiert ist, dann wird da nichts mit dem Laden von nvidia.ko. Genau weiß ich das nicht, aber ich kann mich erinnern, dass es da durchaus Probleme gibt.
 

Yamagi

Possessed With Psi Powers
Teammitglied
Ich will es jetzt nicht beschören, denn meine bktr-Zeiten sind schon lange her. Die Karte war schon zum Erscheinen von FreeBSD 7 durchgebrannt... Aber damals unter FreeBSD 5 und 6 ging es nur zur Bootzeit.
 

Wasp

Insektenspray-Gegner
Habe das jetzt noch einmal überprüft und ich kann (unter nicht bekannten Umständen/nach dem Zufallsprinzip?) bktr.ko definitiv auch nach längerer Laufzeit laden: Xorg gestartet, Opera (tausend Tabs), irssi und anderes Zeug .. Laufzeit (und Nutzung) von über 1 Stunde -- kldload bktr läd fehlerfrei.

Anderes mal erhalte ich den im ersten Beitrag genannten Fehler.
 
Zuletzt bearbeitet:

nakal

Anfänger
Versuch mal speicherintensive Sachen zu machen. Bring bitte einmal den verfügbaren RAM-Speicher auf 0, so dass Swap anspringt. Dann versuch's nochmal zu laden.

Bei geht zum Beispiel auch VirtualBox nicht mehr, wenn der Speicher einmal auf 0 war. Der Client startet gar nicht mehr weil das Modul beim Start offensichtlich Speicher am Stück braucht und allozieren will, was dann aber nicht geht. Und dabei ist sogar das Modul bereits geladen!
 
Ich hab' spasseshalber mal eben in den Source Code geschaut. Es ist wohl tatsächlich so wie nakal schreibt: Der Treiber will die genannte Zahl an Bytes allozieren, und zwar an kontinuierlichem physischem Speicher, der an einer Page Grenze ausgerichtet ist, wahrscheinlich als DMA Buffer. Letzteres ist recht einfach, aber 320 bzw. 868 Physical Pages am Stück sind halt irgendwann einfach nicht mehr da. Von daher hast Du in den Fällen, in denen das Laden funktioniert, wohl einfach Glück.
 

Wasp

Insektenspray-Gegner
Reden wir hier vom "normalen" Speicher? Denn wie ja auch schon im Eingangs-Beitrag erwähnt, ist es ja nun nicht so, dass ich keinen (freien) RAM hätte. Dieser wurde zu dem, aller Voraussicht nach, auch noch nicht gebraucht und dürfte somit nicht fragmentiert sein. Ich weiß nicht, wie viel 320 bzw. 868 Pages sind (vermute Du hast die Info aus dem Quelltext) aber 1,25 MB bzw. 3,39 MB (laut dmesg) sollten doch bei 2 GB RAM irgendwo -- ja auch unfragmentiert -- zu finden sein.

Aber ungeachtet dessen, glaube ich, daß dies unter FreeBSD 6.2 (und davor) immer ging. Werde es aber noch einmal prüfen.

Anbei ist mir aufgefallen, daß genau genommen nicht bktr.ko sondern bktr_mem.ko das Problem darzustellen scheint -- aber liegt ja auch nicht schon alleine auf Grund des Namens auf der Hand.

Besteht die Möglichkeit:
  1. das entladen von bktr_mem.ko zu implementieren, so daß man wenigstens die Möglichkeit hat bktr_mem.ko erneut zu laden und ggf. Speicher zu finden?
  2. das bktr_mem.ko keinen zusammenhängenden Speicher benötigt?

Der Quelltext zu bktr scheint echt nicht umfangreich zu sein, und so wie ich das sehe ist "MOD_UNLOAD" einfach nicht implementiert. Doch abgesehen davon, daß ich weder weiß wie man "MOD_UNLOAD" implementieren müßte, noch ob es überhaupt geht habe ich auch keine Ahnung, wie man bktr_mem.ko beibringt nicht nur zusammenhängenden Speicher zu allokieren.

Aber, da es echt nicht komplex scheint, vielleicht kann das ja jemand anders vielleicht sogar im Vorbeigehen...
 

dettus

Bicycle User
nein, es ist kein "normaler" speicher. "normaler" speicher wird vom kernel verwaltet, und muss nicht physikalisch die gleichen eigenschaften aufweisen; sprich, der muss nicht zusammenhaengend sein.
aus der embedded-programmierung weiss ich aber dass das fuer dma-prozesse lebensnotwendig ist.

ich wuerde dir daher raten deinen boot-prozess so umzumodeln dass bktr gleich als allererstes geladen wird.
 

nakal

Anfänger
FreeBSD hat ein kleines Problem mit der Speicherverwaltung, soweit ich das überblicken kann. Wenn ihr "top" startet, dann könnt ihr sehen, dass nach längerer Lauzeit der Speicher unter "free" immer weiter verschwindet. Er wird zwar freigegeben, aber taucht unter "inactive" auf.

Was nun passiert ist etwas seltsam. FreeBSD kann zum Beispiel kernelseitig nicht den Speicher für manche Module allozieren, der unter "inactive" steht. Ich habe das Problem unter VirtualBox. Das kann man nicht mehr starten, sobald mal Swap im Gebrauch war. Da sind oft mehrere GB Speicher als "inactive" und es geht trotzdem nicht.

Disclaimer: ich mag hier falsch liegen, denn diese Beobachtungen sind rein subjektive Feststellungen. Aber das ist irgendwo ein Problem, soweit ich das überblicken kann.
 

Yamagi

Possessed With Psi Powers
Teammitglied
Das Problem ist FreeBSDs nach wie vor recht primitives Kernelspeichermanagement. Im Prinzip gibt es stark vereinfacht gesagt in FreeBSD zwei Systeme zur Speicherverwaltung:
- UMA für den Kernel.
- VM für das Userland.
VM stellt klassischen virtuellen Speicher bereit und geht davon aus, dass der Kernel seine Speicherwünsche nach dem Boot weitgehend erfüllt hat. UMA arbeitet auf physikalischem Speicher und muss daher gewisse Bedingungen einhalten. Einmal müssen Speicherblöcke zusammenliegen, wie Dettus schon sagte. Dann muss der Speicher nicht selten an bestimmten Stellen liegen. Eine Karte mit 32bit DMA muss ihren Speicher z.B. unterhalb von 4GB haben.

Nun kommt Nakal in das Spiel. Seit 8.2 kann VM dem UMA Speicher entreißen (Back Pressuring), das geht aber nur unter bestimmten Umständen. Umgekehrt kann UMA dem VM aber nicht wirklich Speicher wegnehmen. Das Problem ist nun, dass das VM sich einmal gekrallten Speicher nur ungern wieder hergibt. Anstatt die Seiten sofort auszunullen und in den Pool zurückzugeben, lässt es sie blockiert. Der Gedanke ist, den Inhalt evtl. Recyclen zu können. Beispiel: OpenOffice startet beim zweiten Start wesentlich schneller als beim ersten, da die Programmdaten noch als "Inactive" im Speicher liegen und neu zugeordnet werden können, ohne von der Platte einzulesen.
Was man bräuchte wäre ein umgedrehtes Back Pressuring. UMA müsste dem VM nachdrücklich sagen können "Ich brauche mehr Speicher". Auch müssten beide besser Interagieren, um die Fragmentierung des Kernelspeichers - eines der Hauptprobleme von ZFS - besser zu verhindern. Wirklich sicherstellen, dass genügend Speicher in bestimmten Regionen verfügbar ist, könnte man aber nur indem man ihn von beginn an reserviert hält.
 

Wasp

Insektenspray-Gegner
Habe noch mal die alte Kiste mit FreeBSD 6.2 Stable gestartet; und wie ich sagte: dort läßt sich bktr.ko jederzeit nach dem Boot starten.

Auch wenn es nach euren Erläuterungen betr. Speicher (UMA/VM) keine Relevanz mehr haben sollte, so fällt mir doch auf, daß (mindestens) FreeBSD 6.2 und älter nicht so extrem Speicherfressend ist. Konnte mich auf den Kopf stellen wie ich wollte, ich bekam auch nach 3 Std. die andere Hälfte der 2 GB RAM einfach nicht voll. Es waren schlicht immer rund 1 GB RAM frei ("free" im Gegensatz zu "inactive").

Was mich irgendwie wieder zu der Grundidee dieses Themas führt: -- abgesehen davon, daß ich es gerne funktionierend würde haben wollen ;) -- ich glaube FreeBSD 8.1 Release macht irgendwas anders (evtl. "schlechter"?).
 
Zuletzt bearbeitet:

oenone

Well-Known Member
Von 6.2 auf 8.1 ist ein großer Sprung. Die kannst du nicht ohne weiteres miteinander vergleichen.

Deinen RAM willst du doch schließlich nutzen, oder? Und nicht einfach untätig rumsitzen lassen - dann könntest du ihn auch ausbauen.
 

Wasp

Insektenspray-Gegner
Das ist korrekt, doch wie dettus, als auch Yamagi bereits erläutert hatten, ist RAM ja nicht gleich RAM. Des weiteren wissen wir glaube ich auch alle, daß sich gerade am Umgang mit dem RAM von FreeBSD 7 zu 8 sehr viel getan bzw. geändert hat; ganz im Gegensatz zum Code von bktr_mem.c (als auch bktr_mem.h): "Modified Thu Jan 27 01:40:12 2005 UTC (6 years, 1 month ago) by imp" (vgl. FreeBSD SVN). Noch schnell einen Blick in die Tags, wann FreeBSD 6.1 Release erschien: vor 4 Jahren.

Also zusammengefaßt: von FreeBSD 6.2 stable zu FreeBSD 8.1 Release gab es beim RAM-Management jede menge Umstellungen, während sich bei bktr_mem rein gar nichts getan hat.

Ich denke also, daß sich in dieser Hinsicht 6.2 und 8.1 sehr gut vergleichen lassen; schließlich läßt dies im groben nur zwei Schlußfolgerungen zu: entweder wurde bei bktr_mem eine relevante Anpassung an das neue RAM-Managment versäumt -- schließlich haben viele andere Module dieses Problem nicht -- oder, was ich auf Grund Yamagis Erläuterung eher glaube, am RAM-Umgang sollte noch einiges getan werden. Wie kann es sein, daß sich VM Speicher vom UMA klauen kann, dies aber nicht umgekehrt geht, wenn sich im System mit kldload eine, wie ich finde, sehr sinnvolle Möglichkeit befindet auch nachträglich Kernelmodule zu laden.
 

Yamagi

Possessed With Psi Powers
Teammitglied
Aber selbst wenn UMA dem VM Speicher klauen könnte, würde es dir nicht viel bringen. Der Code vom Treiber ist - wohl auch aufgrund der Steinzeithardware - recht abenteuerlich, so nach schnellem durchscrollen. Da steht z.B. sogar drin:
Code:
 * bktr_mem : This kernel module allows us to keep our allocated
 *            contiguous memory for the video buffer, DMA programs and VBI data
 *            while the main bktr driver is unloaded and reloaded.
 *            This avoids the problem of trying to allocate contiguous each
 *            time the bktr driver is loaded.
Tatsächlich versucht das Modul auch zwischen Laden und Entladen den Speicher blockiert zu halten um zu verhindern, dass er abhanden kommt. Das Ding braucht mindestens 217*PAGESIZE Byte zusammenhängenden Speicher. Das sind etwas weniger als ein Megabyte und er muss unterhalb von 4GB liegen. Bei dir sind es dann konkret 3,5MB. So... Wenn er die nicht bekommen kann und contigmalloc() daher versagt, hast du wahrscheinlich deinen KVA (Kernel Virtual Adressspace) völlig fragmentiert. Nur, wie willst du das verhindern? Der einzige Weg wäre den Speicher beim Boot zu reservieren und dann wären all die Nutzer zurecht angepasst, die Teile ihres teuren Speichers für nichts und wieder nicht verlieren. Der logische Schritt wäre nun, herauszufinden wieso dein KVA fragmentiert.

Aber davon einmal abgesehen. Lade das Ding doch zur Bootzeit und Fall erledigt. Groß Rücksicht wird auf bktr(4) eh niemand mehr nehmen. Analoges TV ist faktisch tot, in vielen Teilen der Welt ist schon Realität, was uns auch bald endgültig einholen wird. Die neuesten Karten sind schon etliche Jahre alt und unter FreeBSD/amd64 ist der Treiber sicher nicht ohne Grund als Modul im Standard-Kernelbuild mit drin. Kurz um, große Hilfe und Entgegenkommen würde ich da nicht mehr erwarten. Wahrscheinlich ist, dass da im Zweifel die berüchtigte dänische Axt geschwungen wird und der Treiber rausfliegt.
 
Oben