background image

Systemy Operacyjne – semestr drugi

Wyk ad dziesi ty

ł

ą

Zarz dzanie pami ci  w Linuksie

ą

ę ą

 

Podsystem zarz dzania pami ci  jest jedn  z najbardziej skomplikowanych cz

ci j dra Linuksa. Przyczyn  takiego stanu rzeczy jest to,  e system ten jest tworzony

ą

ę ą

ą

ęś

ą

ą

ż

z my l   o pracy  na  wielu   platformach,  w   których  obs uga   pami ci   mo e  diametralnie  si  ró ni .  Ró nice   nie   tylko  dotycz  wielko ci  adresu,  ale   równie   sposobu

ś ą

ł

ę

ż

ę

ż ć

ż

ą

ś

ż

zarz dzania ni . Cz

 procesorów, jak np.: procesory Intela wykorzystuje segmentacj , inne w ogóle nie korzystaj  z tej techniki, jak np.: procesory Alpha. Wi kszo

ą

ą

ęść

ę

ą

ę

ść

ze   wspó czesnych   popularnych   systemów   komputerowych   pozwala   na   korzystanie   z   pami ci   wirtualnej,   ale   dedykowane   systemy   czasu   rzeczywistego   i   systemy

ł

ę

wbudowane (ang. embedded) nie korzystaj  z niej, gdy  jest to technika za wolna jak na wymagania czasowe, które musz  spe nia . Te wszystkie cech poszczególnych

ą

ż

ą

ł

ć

architektur musz  uwzgl dnia  twórcy kodu j dra Linuksa. 

ą

ę

ć

ą

J dro Linuksa korzysta w zarz dzaniu pami ci  ze sprz towego mechanizmu stron, którego obecno  jest cech  wspóln  wi kszo ci architektur na których Linux jest

ą

ą

ę ą

ę

ść

ą

ą

ę

ś

dost pny. Adresowanie stron jest trójpoziomowe (czteropoziomowe od wersji 2.6.11) i u ywa Globalnego Katalogu Stron, Po redniego Katalogu Stron oraz Tablicy Stron.

ę

ż

ś

W architekturach 32 – bitowych Po redni Katalog Stron sk ada si  tylko z jednej pozycji. W przypadku procesorów Intela wykorzystywany jest cz

ciowo mechanizm

ś

ł

ę

ęś

segmentacji, g ównie do ochrony pami ci. Wykorzystywanych jest pi

 rodzajów deskryptorów opisuj cych segmenty pami ci: deskryptor kodu j dra, deskryptor danych

ł

ę

ęć

ą

ę

ą

j dra, deskryptor kodu u ytkownika, deskryptor danych u ytkownika i deskryptor lokalnej tablicy deskryptorów (LDT). Cztery pierwsze rodzaje deskryptorów s u

 do

ą

ż

ż

ł żą

zdefiniowania segmentów które obejmuj  ... ca  dost pn  pami ci. Segmenty ró ni  si  prawami dost pu do pami ci jakie przys uguj  j dru i procesom u ytkownika.

ą

łą

ę

ą

ę

ż ą

ę

ę

ę

ł

ą ą

ż

Z ka d  stron  fizyczn  (ramk ) w pami ci komputera jest zwi zana struktura typu 

ż ą

ą

ą

ą

ę

ą

struct page, zawieraj ca  dane o stronie umieszczone w tej ramce. Do tych danych

ą

nale

 mi dzy  innymi:  licznik   odwo a   do  strony,   flagi  okre laj ce  stan   strony,   wska nik  na  struktur  opisuj c  przestrze  adresow ,   na   któr  dana  strona  jest

żą

ę

ł ń

ś

ą

ź

ę

ą ą

ń

ą

ą

odwzorowywana, oraz adres wirtualny danej strony.  Nie wszystkie ramki

1

  i strony w pewnych architekturach s  traktowane jednakowo.  Linux wprowadza podzia

ą

ł

pami ci fizycznej na trzy strefy: ZONE_DMA – strefa grupuj ca  strony i ramki nadaj ce si  do realizacji operacji DMA (zasz o

 z czasów urz dze  ISA, obejmuje

ę

ą

ą

ę

ł ść

ą

ń

pierwsze 16MB pami ci fizycznej), ZONE_NORMAL – strefa zwyk ych odwzorowa , ZONE_HIGHMEM – strefa grupuj ca strony w wysokiej pami ci (dla architektur

ę

ł

ń

ą

ę

x86 jest to pami

 fizyczna powy ej 896MB, dla innych architektur ta strefa jest pusta), które nie s  domy lnie odwzorowywane w przestrzeni adresowej. J dro, je li

ęć

ż

ą

ś

ą

ś

nie jest to okre lone w wywo aniu, przydziela domy lnie pami

 ze strefy ZONE_NORMAL, chyba  e nie ma tam ju  wolnych stron. Wówczas strony s  przydzielane

ś

ł

ś

ęć

ż

ż

ą

z dowolnej z pozosta ych stref. Z ka d  stref  (jest ich maksymalnie trzy) skojarzone s  struktury typu 

ł

ż ą

ą

ą

struct zone. S  to stosunkowo du e struktury i zawieraj  takie

ą

ż

ą

informacje, jak: nazwa strefy: „DMA”, „Normal”, „HighMem” i liczba wolnych ramek w strefie (j dro stara si , aby ta liczba nie spad a poni ej warto ci, która jest

ą

ę

ł

ż

ś

umieszczona w polu pages_min). Struktura ta zawiera równie  rygiel p tlowy 

ż

ę

lock, który s u y do jej ochrony, nie blokuje natomiast dost pu do poszczególnych stron

ł ż

ę

znajduj cych si  w strefie.

ą

ę

Ze wzgl du na wymagania urz dze  maj cych dost p do pami ci za pomoc  DMA, oraz celem zminimalizowania zmian zawarto ci buforów TLB j dro Linuksa stara si

ę

ą

ń

ą

ę

ę

ą

ś

ą

ę

przydziela  pami

 obszarami ci g ymi, których rozmiar stanowi wielokrotno  rozmiaru strony wyra on  pot g  dwójki. Zarz dzaniem tym przydzia em i zwalnianiem

ć

ęć

ą ł

ść

ż

ą

ę ą

ą

ł

zajmuje si  mechanizm, dzia aj cy w oparciu o algorytm bli niaków (

ę

ł ą

ź

ang. buddy system). Algorytm ten grupuje w odpowiednich strukturach obszary wolnych ramek,

które  s  rozmieszczone  w

ą

 sposób  ci g y   w  pami ci i  stara  si  spe nia  

dania  przydzia u   pami ci   przydzielaj c  te  obszary  lub   w razie  konieczno ci   dziel c   je na

ą ł

ę

ę

ł

ć żą

ł

ę

ą

ś

ą

mniejsze. Je li w

ś

 wyniku zwolnienia pami ci powstan  dwa wolne obszary, które przylegaj  do siebie, to s  one  czone w jeden wi kszy obszar. Ten niskopoziomowy

ę

ą

ą

ą

łą

ę

mechanizm alokacji udost pnia pi

 funkcji, które umo liwiaj  przydzielenie pami ci:

ę

ęć

ż

ą

ę

alloc_pages(gfp_mask, order) – przydziela 

 stron pami ci i zwraca wska nik na struktur  

ę

ź

ę page opisuj c  pierwsz  z nich.

ą ą

ą

alloc_page(gfp_mask) – przydziela pojedyncz  stron  i zwraca wska nik na jej struktur  

ą

ę

ź

ę page,

get_zeroed_page(gfp_mask) – przydziela pojedyncz  stron , wype nia j  zerami i zwraca jej adres logiczny (stosowana przy przydziale pami ci dla procesów

ą

ę

ł

ą

ę

u ytkownika), 

ż

__get_free_page(gfp_mask) – przydziela pojedyncz  stron  i jej adres logiczny,

ą

ę

__get_free_pages(gfp_mask, order) – przydziela 

stron i zwraca adres logiczny pierwszej z nich.

Je li dysponujemy wska nikiem na struktur  

ś

ź

ę page, to adres logiczny strony, któr  ona opisuje mo emy uzyska  pos uguj c si  funkcj  

ą

ż

ć

ł

ą

ę

ą page_address(). Warto ci jakie

ś

mo e przyjmowa  argument 

ż

ć

gfp_mask b d  opisane pó niej. Po wykonaniu operacji przydzielania nale y sprawdzi , czy si  ona powiod a. Do zwalniana przydzielonej

ę ą

ź

ż

ć

ę

ł

przez powy sze funkcje pami ci s u

 inne funkcje alokatora:

ż

ę

ł żą

void _free_pages(struct page *page, unsigned int order) – zwalnia grup  

ę

stron rozmieszczonych w sposób ci g y, identyfikowan  struktur  

ą ł

ą

ą page

pierwszej z tych stron,

void free_pages(unsigned long addr, unsigned int order) – zwalnia grup  

ę

stron identyfikowan  adresem pierwszej z nich,

ą

void free_page(unsigned long addr) – zwalnia pojedyncz  stron  pami ci. 

ą

ę

ę

Zwalniaj c pami

 nale y  pami ta  o przekazaniu  prawid owych argumentów do funkcji zwalniaj cych pami

. Warto ci argumentów wywo a  tych funkcji nie s

ą

ęć

ż

ę ć

ł

ą

ęć

ś

ł ń

ą

weryfikowane. Nale y te  unika  wycieków pami ci. Je li potrzebny jest nam fizycznie ci g y obszar pami ci o dowolnym rozmiarze, to mo emy skorzysta  z funkcji

ż

ż

ć

ę

ś

ą ł

ę

ż

ć

kmalloc, której prototyp jest nast puj cy: 

ę

ą

void *kmalloc(size_t size, int flags). Funkcja to przydziela tyle pami ci, ile jest okre lone parametrem 

ę

ś

size, lub wi cej, nigdy

ę

za  mniej. Je li przydzia  si  nie powiedzie, to zwracana jest warto

 NULL. Do zwolnienia pami ci przydzielonej przez  

ś

ś

ł

ę

ść

ę

kmalloc  i tylko takiej pami ci s u y funkcja

ę

ł ż

void kfree(const void *ptr); Nale y zadba  o poprawno

 przekazywanych jej wywo aniu argumentów, gdy  funkcja sprawdza jedynie czy przekazany jej wska nik nie

ż

ć

ść

ł

ż

ź

ma   warto ci   NULL.   Argument  

ś

gfp_mask  okre la   znacznik   identyfikuj cy   charakter   operacji   przydzielania   pami ci.   Znaczniki   podzielone   s   na   trzy   kategorie:

ś

ą

ę

ą

modyfikatory czynno ciowe, modyfikatory stref i znaczniki typu. Modyfikatory czynno ciowe s  to sta e okre laj ce, jakie czynno ci podczas przydzielania pami ci mo e

ś

ś

ą

ł

ś

ą

ś

ę

ż

wykona  alokator (zawieszanie, 

ć

operacje wej cia – wyj cia). Modyfikatory stref (s  tylko dwa – dla stron DMA i nale

cych do pami ci wysokiej) okre laj  z której strefy

ś

ś

ą

żą

ę

ś

ą

pami

 b dzie przydzielana.  Modyfikatory obu kategorii mo na  czy  za pomoc  operatora sumy logicznej. Znaczniki  typów s  takimi w a nie  sumami logicznymi.

ęć

ę

ż

łą

ć

ą

ą

ł ś

Poniewa  te znaczniki s  najcz

ciej wykorzystywane zostan  tu szerzej omówione:

ż

ą

ęś

ą

GFP_ATOMIC – przydzia  wysokiego priorytetu, bez mo liwo ci zawieszenia procesu wywo uj cego. Z tego znacznika korzystaj  g ownie procedury obs ugi

ł

ż

ś

ł ą

ą ł

ł

przerwa  i dolne po ówki,

ń

ł

GFP_NOIO – przydzia  z mo liwo ci  zawieszenia,  ale  bez  mo liwo ci  inicjalizacji  operacji  dost pu  do dysku. Stosowany  w kodzie  blokowych  operacji

ł

ż

ś ą

ż

ś

ę

1

które w przypadku Linuksa najcz

ciej nazywane s  stronami fizycznymi.

ęś

ą

1

background image

Systemy Operacyjne – semestr drugi

wej cia wyj cia, aby wyeliminowa  zjawisko zakleszczenia,

ś

ś

ć

GFP_NOFS – przydzia  z mo liwo ci  zawieszenia i inicjalizacji operacji dost pu do dysku, ale bez mo liwo ci korzystania z systemu plików. 

ł

ż

ś ą

ę

ż

ś

GFP_KERNEL – zwyk y przydzia  z mo liwo ci  zawieszenia, stosowany w kontek cie procesu.

ł

ł

ż

ś ą

ś

GFP_USER – zwyk y przydzia  z mo liwo ci  zawieszenia, stosowany w przydzia ach inicjowanych przez procesy u ytkownika.

ł

ł

ż

ś ą

ł

ż

GFP_HIGHUSER – jak wy ej, ale pami

 jest przydzielana w obszarze wysokim.

ż

ęć

GFP_DMA – przydzia  pami ci, która mo e by  wykorzystana w trybie DMA.

ł

ę

ż

ć

Je li  obszar,  który  chcemy  aby   zosta   nam  przydzielony  nie  musi  by   ci g y   fizycznie,   ale  logicznie,  to  mo emy  u y   funkcji  

ś

ł

ć

ą ł

ż

ż ć

vmalloc,  o   prototypie:  void   *vmalloc

(unsigned long size). Pami

 przydzielona t  funkcj  musi by  zwolniona przy pomocy 

ęć

ą

ą

ć

vfree: void vfree(void *addr). 

J dra   systemów   operacyjnych   bardzo   cz sto   przydzielaj   i   zwalniaj   pami

  operacyjn   na   struktury   danych.   Poniewa   proces   alokacji   pami ci   jest   zawsze

ą

ę

ą

ą

ęć

ą

ż

ę

czasoch onny mo na okre li  bufory takich struktur podczas inicjalizacji j dra i w razie konieczno ci stworzenia jednej ze struktur takiego rodzaju, po prostu przekaza

ł

ż

ś ć

ą

ś

ć

wska nik do niej, natomiast po zwolnieniu nie trzeba jej niszczy  tylko umie ci  z powrotem we wspomnianym buforze. Na tym pomy le bazuje alokator plastrowy

ź

ć

ś ć

ś

2

(ang. slab), który zosta  wynaleziony przez firm  SUN Microsystem i po raz pierwszy wykorzystany w ich systemie operacyjnym Solaris. Budowie takiego alokatora

ł

ę

przy wieca y nast puj ce za o enia:

ś

ł

ę

ą

ł ż

Podstawowe struktury danych s  cz sto przydzielane i zwalniane, wi c korzystne jest ich buforowanie.

ą

ę

ę

Cz ste przydzia y i zwolnienia pami ci prowadz  do fragmentacji. Aby j  wyeliminowa  pami  w której b d  si  znajdowa  struktury powinna by  ci g a. 

ę

ł

ę

ą

ą

ć

ęć

ę ą

ę

ć

ć

ą ł

Lista struktur wolnych pozwala na zwi kszenie wydajno ci operacji przydzia u i zwalniania pami ci. 

ę

ś

ł

ę

Je li cz

 bufora  uczyni  specyficzn  dla danego procesora, to przydzia y i zwalniania pami ci da si  przeprowadzi  bez blokowania procesów.

ś

ęść

ć

ą

ł

ę

ę

ć

Obiekty (struktury) przechowywane w buforze mog  by  kolorowane, co zapobiega odwzorowywaniu tych samych fragmentów bufora do ró nych obiektów.

ą

ć

ż

W Linuksie alokator palstrowy tworzy pami ci podr czne dwóch rodzajów: ogólne i dedykowane. Z pami ci ogólnych korzysta on sam, z dedykowanych – pozosta e

ę

ę

ę

ł

cz

ci j dra. Na ka dy typ buforowanej struktury przypada jedna dedykowana pami

 podr czna.  Nazwa tej pami ci wskazuje jakiego  rodzaju struktury s  w niej

ęś

ą

ż

ęć

ę

ę

ą

przechowywane  (np.:  task_struct_cachep).  Pami

 podr czna  jest podzielona  na  plastry,  które sk adaj   si  z jednej   (zazwyczaj)  lub wielu  ramek.  Ka dy  z

ęć

ę

ł

ą

ę

ż

 plastrów

zawiera   pewn   liczb  buforowanych   struktur,   które  s  nazywane   obiektami.  Plastry  mo na  podzieli   na  puste,  pe ne   i  cz

ciowo  zaj te.  Struktur  s   przydzielane

ą

ę

ą

ż

ć

ł

ęś

ę

ą

w pierwszej kolejno ci z plastrów cz

ciowo zaj tych. Je li takich nie ma, to z pustych. Pami

 podr czn  opisuje struktura  

ś

ęś

ę

ś

ęć

ę

ą

kmem_cache_s, a poszczególne plastry są

reprezentowane przez deskryptory, które s  strukturami typu  

ą

struct slab. Te deskryptory s  przechowywane w ogólnych pami ciach podr cznych lub bezpo rednio

ą

ę

ę

ś

w plastrach. Nowy plaster jest tworzony za pomoc  funkcji 

ą

kmem_getpages(), a niszczony przy pomocy kmem_freepages(). Tworzeniem i zwalnianiem plastrów zajmuje

si  automatycznie alokator plastrowy. Programista j dra mo e stworzy  w asn  dedykowan  pami

 podr czn  korzystaj c z funkcji  

ę

ą

ż

ć

ł

ą

ą

ęć

ę

ą

ą

kmem_cache_create().  Pierwszy

argument wywo ania tej funkcji okre la, jak maj  by  przydzielane obiekty w tej pami ci (czy ich rozmiary maj  by  wyrównywane do wielko ci linii sprz towej pami ci

ł

ś

ą

ć

ę

ą

ć

ś

ę

ę

podr cznej, czy strony, na których te obiekty b d  umieszczone b d  przydzielane ze strefy DMA, itd.). Dwa kolejne okre laj  adres funkcji b d cych destruktorem

ę

ę ą

ę ą

ś

ą

ę ą

i konstruktorem struktur przechowywanych w pami ci – st d te struktury nazywane s  obiektami. Najcz

ciej te argumenty maj  warto  NULL. Pami

 podr czna

ę

ą

ą

ęś

ą

ść

ęć

ę

mo e zosta  usuni ta, je li zwolnione  s  wszystkie plastry znajduj ce si  w niej i nie jest do niej  wykonywany  wspó bie ny  dost p przez inne w tki. Usuni cie  jej

ż

ć

ę

ś

ą

ą

ę

ł

ż

ę

ą

ę

odbywa si  za pomoc  funkcji 

ę

ą

kmem_cache_destroy(). Obiekty z tej pami ci s  przydzielane przez 

ę

ą

kmem_cache_alloc(), a zwalniane przez kmem_cache_free(). 

Odmian  pami ci podr cznych tworzonych przez alokator plastrowy s  pule pami ci (

ą

ę

ę

ą

ę

ang. memory pools).   Maj  one na celu zapewnienie,  e dla krytycznych partii

ą

ż

kodu, dla których przydzia  pami ci nie mo e zawie  zawsze b d  dost pne wolne obszary pami ci. Pula pami ci opisywana jest przez typ  

ł

ę

ż

ść

ę ą

ę

ę

ę

mempool_t i mo e zosta

ż

ć

stworzona przez wywo anie  

ł

mempool_create(). Funkcja ta przyjmuje cztery argumenty wywo ania. Pierwszy okre la minimaln  liczb  obiektów, które pula powinna

ł

ś

ą

ę

zawsze posiada , dwa nast pne s  wska nikami do funkcji przydzielaj cej i funkcji zwalniaj cej obiekty, a ostatni argument jest wska nikiem na dane przekazywane

ć

ę

ą

ź

ą

ą

ź

do   tych   funkcji.   Programista   mo e   napisa   w asne   funkcje   alokuj ce   i   dealokuj ce   obiekty   z   puli,   lub   u y   funkcji  

ż

ć

ł

ą

ą

ż ć

mempool_alloc()  i  mempool_free(),   które   mogą

korzysta  z

ć  funkcji dost pnych dla alokatora plastrowego. Pul  mo na rozszerzy  za pomoc  

ę

ę

ż

ć

ą memory_resize(), a usun

 za pomoc  

ąć

ą memory_destroy(). 

Pisz c kod wywo a  systemowych, czy innych cz

ci j dra korzystaj cych ze stosu procesu u ytkownika w j drze, nale y pami ta ,  e jest to bardzo ograniczona pod

ą

ł ń

ęś

ą

ą

ż

ą

ż

ę ć ż

wzgl dem   wielko ci   struktura,   a   jej   przekroczenie   nie   jest   kontrolowane.   Nie   zaleca   si   tworzenia   du ych   struktur   danych   na   stosie,   aby   nie   spowodowa   jego

ę

ś

ę

ż

ć

przepe nienia, które mo e mie  bardzo powa ne konsekwencje. 

ł

ż

ć

ż

Strony nale

ce do strefy pami ci wysokiej nie s  domy lnie odwzorowane w przestrzeni adresowej j dra. Mo emy proces odwzorowania przeprowadzi  samodzielnie.

żą

ę

ą

ś

ą

ż

ć

Istniej  dwa rodzaje takiego odwzorowania: trwa e, które jest dokonywane za pomoc  funkcji 

ą

ł

ą

kmap() i likwidowane za pomoc  

ą kumap() oraz czasowe (nie powoduj ce

ą

zawieszenia) dokonywane za pomoc  

ą kmap_atomic() i likwidowane za pomoc  

ą kumap_atomic(). 

2

zwany te  w polskiej literaturze alokatorem p ytowym.

ż

ł

2