zoned and jiffies based vm
Subsystems (7)
PATCH 1/1 zoned and jiffies based vm
This is an attempt to try to solve the performance and CPU usage problems in vm subsystem.
During the development of this patch I have found some interesting things:
* Most read pages will end up as Referenced even if the PG_referenced bit is cleared when inserted into LRU - this is probably due to the pages being read ahead, and thus later referred...
Improvements/bugs in patch:
* does not handle age wrap of really old pages.
* does not use reused pointer.
* could use another counter (incremented at use) or mechanism instead (function that ages all pages at once).
* I am not sure how it will handle mmap002, forgot to run it before connecting to internet...
I am sending it as is since I will be away this weekend...
/RogerL
--
Home page:
http://www.norran.net/nra02596/
include/linux/mm.h +4 -1
@@ -148,6 +148,8 @@atomic_t count;unsigned long flags;/* atomic flags, some possibly updated asynchronously */ struct list_head lru; +unsigned long lru_born;/* at jiffies */ +long lru_reused;/* no of times reused */ wait_queue_head_t wait;struct page **pprev_hash;struct buffer_head * buffers;
@@ -196,7 +198,8 @@#define SetPageError (page) set_bit(PG_error, &(page)->flags)#define ClearPageError (page) clear_bit(PG_error, &(page)->flags)#define PageReferenced (page) test_bit(PG_referenced, &(page)->flags) -#define SetPageReferenced (page) set_bit(PG_referenced, &(page)->flags) +#define SetPageReferenced (page) {(page)->lru_born = jiffies; set_bit(PG_referenced, &(page)->flags);} +#define ClearPageReferenced (page) clear_bit(PG_referenced, &(page)->flags)#define PageTestandClearReferenced (page) test_and_clear_bit(PG_referenced, &(page)->flags)#define PageDecrAfter (page) test_bit(PG_decr_after, &(page)->flags)#define SetPageDecrAfter (page) set_bit(PG_decr_after, &(page)->flags)
include/linux/mmzone.h +3 -0
@@ -32,6 +32,9 @@char zone_wake_kswapd;unsigned long pages_min, pages_low, pages_high; +int nr_lru_pages; +struct list_head lru_cache; +/* * free areas of different sizes */
include/linux/swap.h +6 -4
@@ -67,7 +67,6 @@ FASTCALL(unsigned int nr_free_pages(void)); FASTCALL(unsigned int nr_free_buffer_pages(void)); FASTCALL(unsigned int nr_free_highpages(void)); -extern int nr_lru_pages;extern atomic_t nr_async_pages;extern struct address_space swapper_space;extern atomic_t page_cache_size;
@@ -165,16 +164,19 @@*/ #define lru_cache_add (page) \ do { \ + zone_t *zone = (page)->zone; \ spin_lock(&pagemap_lru_lock); \ - list_add(&(page)->lru, &lru_cache); \ - nr_lru_pages++; \ + list_add(&(page)->lru, &zone->lru_cache); \ + page->lru_born = jiffies; \ + page->lru_reused = 1; \ + zone->nr_lru_pages++; \ spin_unlock(&pagemap_lru_lock); \ } while (0)#define __lru_cache_del (page) \ do { \ list_del(&(page)->lru); \ - nr_lru_pages--; \ + (page)->zone->nr_lru_pages--; \ } while (0)#define lru_cache_del (page) \
mm/filemap.c +114 -23
187 lines not on this page · raw message
mm/page_alloc.c +23 -5
@@ -25,7 +25,6 @@#endif int nr_swap_pages; -int nr_lru_pages;pg_data_t *pgdat_list;static char *zone_names[MAX_NR_ZONES ] = {"DMA" ,"Normal" ,"HighMem" };
@@ -313,6 +312,22 @@ }/* +* Total amount of free (allocatable) RAM: +*/ +unsigned int nr_lru_pages (void ) +{ +unsigned int sum; +zone_t *zone; +int i; + + sum =0 ; +for (i =0 ; i <NUMNODES ; i++) +for (zone =NODE_DATA (i)->node_zones; zone <NODE_DATA (i)->node_zones +MAX_NR_ZONES ; zone++) + sum += zone->nr_lru_pages; +return sum; +} + +/* * Amount of free RAM allocatable as buffer memory: */ unsigned int nr_free_buffer_pages (void )
@@ -321,10 +336,10 @@zone_t *zone;int i; - sum = nr_lru_pages; + sum =0 ;for (i =0 ; i <NUMNODES ; i++)for (zone =NODE_DATA (i)->node_zones; zone <=NODE_DATA (i)->node_zones+ZONE_NORMAL ; zone++) - sum += zone->free_pages; + sum += zone->free_pages + zone->nr_lru_pages;return sum; }
@@ -356,7 +371,7 @@printk ("( Free: %d, lru_cache: %d (%d %d %d) )\n" ,nr_free_pages (), - nr_lru_pages, +nr_lru_pages (), freepages.min, freepages.low, freepages.high);
@@ -497,7 +512,6 @@ freepages.min += i; freepages.low += i *2 ; freepages.high += i *3 ; -memlist_init (&lru_cache);/* * Some architectures (with lots of mem and discontinous memory
@@ -543,6 +557,10 @@ zone->lock =SPIN_LOCK_UNLOCKED ; zone->zone_pgdat = pgdat; zone->free_pages =0 ; + + zone->nr_lru_pages =0 ; +memlist_init (&zone->lru_cache); +if (!size)continue ;
mm/vmscan.c +37 -26
94 lines not on this page · raw message