Mam kłopotliwy problem. Mam bibliotekę, która używa sg do wykonywania niestandardowych CDB. Istnieje kilka systemów, które rutynowo mają problemy z alokacją pamięci w SG . Zwykle sterownik sg ma twardy limit około 4 MB, ale widzimy go w tych kilku systemach z żądaniami ~ 2,3 MB. Oznacza to, że CDB przygotowują się do alokacji na transfer 2,3 Mb. Nie powinno tu być żadnego problemu: 2.3 <4.0.
Teraz profil maszyny. Jest to 64-bitowy procesor, ale działa na 32-bitowym CentOS 6.0 (nie zbudowałem ich ani nie mam nic wspólnego z tą decyzją). Wersja jądra dla tej dystrybucji CentOS to 2.6.32. Mają 16 GB pamięci RAM.
Oto, jak wygląda użycie pamięci w systemie (ponieważ ponieważ ten błąd występuje podczas testów automatycznych, jeszcze nie sprawdziłem, czy odzwierciedla to stan, w którym to errno jest zwracane z sg ).
top - 00:54:46 up 5 days, 22:05, 1 user, load average: 0.00, 0.01, 0.21
Tasks: 297 total, 1 running, 296 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 15888480k total, 9460408k used, 6428072k free, 258280k buffers
Swap: 4194296k total, 0k used, 4194296k free, 8497424k cached
Znalazłem ten artykuł z Linux Journal, który dotyczy alokacji pamięci w jądrze. Artykuł jest datowany, ale wydaje się, że dotyczy 2.6 (niektóre komentarze na temat autora na czele). W artykule wspomniano, że jądro jest ograniczone do około 1 GB pamięci (choć z tekstu nie jest całkowicie jasne, czy ten 1 GB dla fizycznych i wirtualnych lub ogółem). Zastanawiam się, czy jest to dokładne stwierdzenie dotyczące wersji 2.6.32. W końcu zastanawiam się, czy te systemy osiągają ten limit.
Chociaż tak naprawdę nie jest to odpowiedź na mój problem, zastanawiam się nad prawdziwością roszczenia dotyczącego wersji 2.6.32. Zatem jaki jest rzeczywisty limit pamięci dla jądra? Może to wymagać rozważenia przy rozwiązywaniu problemów. Wszelkie inne sugestie są mile widziane. Co sprawia, że jest to tak zaskakujące, że systemy te są identyczne z wieloma innymi, które nie wykazują tego samego problemu.
źródło
Chcę dodać trochę do doskonałej odpowiedzi Warrena Younga , ponieważ rzeczy są w rzeczywistości gorsze, niż pisze.
Przestrzeń adresowa jądra 1 GB jest dalej podzielona na dwie części. 128 MB dla
vmalloc
i 896 MB dlalowmem
. Nieważne, co to właściwie oznacza. Podczas przydzielania pamięci kod jądra musi wybrać, który z nich chce. Nie można po prostu uzyskać pamięci z puli, która ma wolne miejsce.Jeśli wybierzesz
vmalloc
, masz ograniczenie do 128 MB. Teraz 1 GB nie wygląda tak źle ...Jeśli wybierzesz
lowmem
, jesteś ograniczony do 896 MB. Nie tak daleko od 1 GB, ale w tym przypadku wszystkie alokacje są zaokrąglane w górę do następnej potęgi 2. Tak więc alokacja 2,3 MB w rzeczywistości zużywa 4 MB. Ponadto nie można przydzielić więcej niż 4 MB na jedno połączenie podczas korzystanialowmem
.Wersja 64-bitowa jest naprawdę właściwą odpowiedzią.
źródło