next up previous contents
Next: inactive_dirty_list Up: Listy active_list, inactive_dirty_list oraz Previous: Listy active_list, inactive_dirty_list oraz   Spis tresci

active_list

Jest to lista, na której znajdują się wszystkie strony, które uczestniczą w algorytmie postarzania. Trzeba tu zaznaczyć, że w momencie zaalokowania strony przez proces strona ta nie jest brana pod uwagę przy mechaniazmach swappowania, włącznie z postarzaniem. Dopiero, gdy trafi ona na listę active_list jej wiek będzie się zmieniał w przybliżeniu co sekundę.

Samo jądro algorytmu LRU wykonywane jest w funkcji refill_inactive_scan() (zdefiniowanej w mm/vmscan.c) oraz w try_to_swap_out() (będzie opisana później). Przyjrzyjmy się działaniu funkcji:







/* funkcja postarza lub odmładza "target" stron, przy czym działa ona na liście active_clean_list w kółko. Czyli w kolejnym wywołaniu rozpocznie przeliczanie wieku stron w miejscu, w którym ostatnio przestała */

int refill_inactive_scan(unsigned int priority, int target)

  if target != 0
    maxcount = target;
  else
    maxcount = inactive_shortage();
/* funkcja inactive_shortage() zwraca ilość brakujących stron, do uzyskania bezpiecznego poziomu ilości nieaktywnej pamięci. Czyli domyślnie postarza tyle stron ile brakuje do uzyskania bezpiecznego poziomu stron nieaktywnych */
  for each page in active_list do
    jeżeli bit PG_referenced jest ustawiony
      page->age += 3
      jeżeli page->age > PAGE_AGE_MAX
        page->age = PAGE_AGE_MAX
    wpp
      page->age /= 2

    jeżeli page->age == 0
      przesuń stronę z active_list do inactive_dirty_list o ile 
            nie korzysta z niej więcej niż jeden użytkownik
/* Czyli odwołanie tylko z systemu swappującego (swap cache) */
    jeżeli --maxcount <= 0
      break;

  return ilość zdeaktywowanych stron

W tym momencie należałoby przyjrzeć się strukturze danych opisującej strony w systemie Linux (plik includeinux/mm.h):


struct page {
struct list_head list;
struct address_space *mapping;
/* inode, do którego należymy - w szczególności może to być inode urządzenia swappującego (lub plik z dysku, który przedstawiamy) */
unsigned long index;
/* offset w inode (mapping) */
struct page *next_hash;
atomic_t count;
/* ilość procesów używających stronę + 1 dla buforów + 1 dla cache strony (aby ktoś nam nie zwolnił strony, gdy my ją będziemy zapisywać na dysk) */
unsigned long flags;
struct list_head lru;
/* jedna z list: active_list, inactive_dirty_list, zone->inactive_clean_list */
unsigned long age; /* wiek strony */
wait_queue_head_t wait;
struct page **pprev_hash;
struct buffer_head * buffers;
/* bufory związane ze stroną */
void *virtual;
struct zone_struct *zone;
}

Wśród bitów w polu flags będą nas interesowały bity:

Warto zauważyć, że strony, których wiek spadł do zera zostają przeniesione na listę inactive_dirty_list.


next up previous contents
Next: inactive_dirty_list Up: Listy active_list, inactive_dirty_list oraz Previous: Listy active_list, inactive_dirty_list oraz   Spis tresci
Łukasz Heldt 2001-12-18