Systemy Operacyjne : Pamięć : Przydział pamięci na potrzeby jądra kmalloc

Łukasz Bolikowski


Pamięć zawierająca obiekty alokowane na potrzeby jądra jest podzielona na schowki (ang. cache), po jednym na każdy "typ" obiektu. Schowki są kolekcją spójnych obszarów pamięci, tzw. tafli (ang. slab). Obiekty przechowywane są w taflach.

Tafle mają z reguły rozmiar jednej strony (chyba, że służą do przechowywania danych większych niż strona). W danym schowku na początku znajdują się tafle pełne, potem częściowo zapełnione, a na końcu puste.

Aby zaalokować obiekt we wskazanym schowku używamy funkcji kmem_cache_alloc, aby go usunąć ze schowka używamy kmem_cache_free.

Wszystkie schowki trzymane są w specjalnym schowku o nazwie cache_cache. Nie jest on widoczny "z zewnątrz", więc nie można w nim bezpośrednio alokować / zwalniać obiektów (w tym przypadku - schowków). Aby dodać lub usunąć schowek, używamy funkcji kmem_cache_create oraz kmem_cache_destroy.

Funkcje kmem_cache_grow i kmem_cache_shrink służą do dodawania/usuwania tafli do/ze schowka. Funkcja kmem_cache_reap oddaje systemowi strony, na których znajdowały się wcześniej tafle (używana przez kswapd gdy brakuje pamięci).

To, jakie schowki znajdują się w systemie zależy od innych części jądra. To one tworzą i usuwają schowki na własne potrzeby. Jest też jednak "rodzina" schowków tworzonych automatycznie przy inicjalizacji zarządzania pamięcią. Dowiązania do tych schowków są dodatkowo trzymane w (niedostępnej "z zewnątrz") tablicy cache_sizes.

Schowki z cache_sizes są przeznaczone do przechowywania obiektów o rozmiarach (do) 64, 128, 256, ..., 131072 bajtów. Mówiąc dokładniej, dla każdego wymienionego rozmiaru tworzona jest para schowków: jeden normalny i jeden przechowujący obiekty, do których można się odwołać za pomocą mechanizmu DMA. Jeśli rozmiar strony wyniosi 4096 bajtów, to dodatkowo mamy parę schowków dla obiektów do 32 bajtów.

Tradycyjną metodą alokowania / zwalniania pamięci na potrzeby jądra jest użycie funkcji kmalloc i kfree. Nie wymagają one podania konkretnego schowka, jak to jest w przypadku kmem_cache_alloc i kmem_cache_free. Odpowiedni schowek jest automatycznie wybierany spośród schowków z cache_sizes.

Podczas inicjalizacji jądra wywoływane są dwie funkcje związane z inicjowaniem przydziału pamięci na potrzeby jądra: kmem_cache_init i kmem_cache_sizes_init. Pierwsza inicjuje schowek cache_cache, druga schowki trzymane w cache_cache.



© 2001 Łukasz Bolikowski, Jakub Górski, Jakub Kowalski, Janusz Kuligowski, Tomasz Szymko