CART Implementation ver 2
Subsystems (10)
cover CART Implementation ver 2
Hi All,
Marcelo was ofcourse right, and I needed to do scary stuff to avoid calling page_referenced() while holding zone->lru_lock. Thanks Rik for making my thik head see that :-)
So here is an update of my code.
Changes:
- Changed the hash algo. for the nonresident buckets It is worse now, so it has to change again :-(
- Made the nonresident code blank out a paged in cookie.
- Rewrote the cart code (yet again) to work on temp lists much like refill_inactive and co.
I put all that code in cart.c instead of swap.c to get a clearer distinction on what was general page reclaim logic and what was part of the page cache.
Just before mailing (and ofcourse untested) I changed the calls to cart_rebalance_*() to take nr_dst/2 + 1 as target because I got too much OOMs, no idea if this solved it. When i put nr_scan = sc->swap_cluster_max (in shrink_cache) I go no OOMs, work left there.
Kind regards,
Peter Zijlstra
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
RFC PATCH 1/6 CART Implementation ver 2
include/linux/swap.h +14 -0
@@ -154,6 +154,15 @@ extern void out_of_memory(unsigned int _/* linux/mm/memory.c */ extern void swapin_readahead (swp_entry_t ,unsigned long ,struct vm_area_struct *); +/* linux/mm/nonresident.c */ +#define NR_filter 0x01/* short/long */ +#define NR_list 0x02/* b1/b2; correlates to PG_active */ +#define NR_evict 0x80000000 + +extern unsigned int remember_page (struct address_space *,unsigned long ,unsigned int ); +extern unsigned int recently_evicted (struct address_space *,unsigned long ); +extern void init_nonresident (void ); +/* linux/mm/page_alloc.c */ extern unsigned long totalram_pages;extern unsigned long totalhigh_pages;
@@ -292,6 +301,11 @@ static inline swp_entry_t get_swap_page(#define grab_swap_token () do { } while(0)#define has_swap_token (x) 0 +/* linux/mm/nonresident.c */ +#define init_nonresident () do { } while (0) +#define remember_page (x,y,z) 0 +#define recently_evicted (x,y) 0 +#endif /* CONFIG_SWAP */ #endif /* __KERNEL__*/ #endif /* _LINUX_SWAP_H */
init/main.c +2 -0
@@ -47,6 +47,7 @@#include <linux/rmap.h> #include <linux/mempolicy.h> #include <linux/key.h> +#include <linux/swap.h> #include <asm/io.h> #include <asm/bugs.h>
@@ -494,6 +495,7 @@ asmlinkage void __init start_kernel(void }#endif vfs_caches_init_early (); +init_nonresident ();mem_init ();kmem_cache_init ();setup_per_cpu_pageset ();
mm/Makefile +2 -1
@@ -12,7 +12,8 @@ obj-y := bootmem.o filemap.o mempool.o readahead.o slab.o swap.o truncate.o vmscan.o \ prio_tree.o $(mmu-y) -obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o +obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o \ + nonresident.o obj-$(CONFIG_HUGETLBFS) += hugetlb.o obj-$(CONFIG_NUMA) += mempolicy.o obj-$(CONFIG_SPARSEMEM) += sparse.o
mm/nonresident.c new file +275 -0
275 lines not on this page · raw message
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
RFC PATCH 2/6 CART Implementation ver 2
In reply to [email protected]fs/proc/proc_misc.c +15 -0
@@ -233,6 +233,20 @@ static struct file_operations proc_zonei .release = seq_release, }; +extern struct seq_operations nonresident_op; +static int nonresident_open (struct inode *inode,struct file *file) +{ + (void )inode; +return seq_open (file, &nonresident_op); +} + +static struct file_operations nonresident_file_operations = { + .open = nonresident_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; +static int version_read_proc (char *page,char **start,off_t off,int count,int *eof,void *data) {
@@ -602,6 +616,7 @@ void __init proc_misc_init(void)create_seq_entry ("interrupts" ,0 , &proc_interrupts_operations);create_seq_entry ("slabinfo" ,S_IWUSR |S_IRUGO ,&proc_slabinfo_operations);create_seq_entry ("buddyinfo" ,S_IRUGO , &fragmentation_file_operations); +create_seq_entry ("nonresident" ,S_IRUGO , &nonresident_file_operations);create_seq_entry ("vmstat" ,S_IRUGO , &proc_vmstat_file_operations);create_seq_entry ("zoneinfo" ,S_IRUGO , &proc_zoneinfo_file_operations);create_seq_entry ("diskstats" ,0 , &proc_diskstats_operations);
mm/nonresident.c +71 -0
74 lines not on this page · raw message
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
RFC PATCH 3/6 CART Implementation ver 2
In reply to [email protected]include/linux/mm_inline.h +20 -2
@@ -31,10 +31,28 @@ static inline void del_page_from_lru(struct zone *zone, struct page *page) { list_del(&page->lru); -if (PageActive (page)) { -ClearPageActive (page); +if (TestClearPageActive (page)) { zone->nr_active--; }else { zone->nr_inactive--; } +if (TestClearPageLongTerm (page)) { +/* zone->nr_longterm--; */ + }else { + zone->nr_shortterm--; + } +} + +static inline void +add_page_to_active_tail (struct zone *zone,struct page *page) +{ +list_add_tail (&page->lru, &zone->active_list); + zone->nr_active++; +} + +static inline void +add_page_to_inactive_tail (struct zone *zone,struct page *page) +{ +list_add_tail (&page->lru, &zone->inactive_list); + zone->nr_inactive++; }
include/linux/mmzone.h +7 -3
@@ -143,13 +143,17 @@ struct zone {ZONE_PADDING (_pad1_)/* Fields commonly accessed by the page reclaim scanner */ - spinlock_t lru_lock; -struct list_head active_list; -struct list_head inactive_list; + spinlock_t lru_lock; +struct list_head active_list;/* The T1 list of CART */ +struct list_head inactive_list;/* The T2 list of CART */ unsigned long nr_scan_active;unsigned long nr_scan_inactive;unsigned long nr_active;unsigned long nr_inactive; +unsigned long nr_evicted_active; +unsigned long nr_shortterm;/* number of short term pages */ +unsigned long nr_p;/* p from the CART paper */ +unsigned long nr_q;/* q from the cart paper */ unsigned long pages_scanned;/* since last reclaim */ int all_unreclaimable;/* All pages pinned */
include/linux/page-flags.h +8 -0
@@ -76,6 +76,8 @@#define PG_nosave_free 18/* Free, should not be written */ #define PG_uncached 19/* Page has been mapped as uncached */ +#define PG_longterm 20/* Filter bit for CART see mm/cart.c */ +/* * Global page accounting. One instance per CPU. Only unsigned longs are * allowed.
@@ -305,6 +307,12 @@ extern void __mod_page_state(unsigned lo#define SetPageUncached (page) set_bit(PG_uncached, &(page)->flags)#define ClearPageUncached (page) clear_bit(PG_uncached, &(page)->flags) +#define PageLongTerm (page) test_bit(PG_longterm, &(page)->flags) +#define SetPageLongTerm (page) set_bit(PG_longterm, &(page)->flags) +#define TestSetPageLongTerm (page) test_and_set_bit(PG_longterm, &(page)->flags) +#define ClearPageLongTerm (page) clear_bit(PG_longterm, &(page)->flags) +#define TestClearPageLongTerm (page) test_and_clear_bit(PG_longterm, &(page)->flags) +struct page ;/* forward declaration */ int test_clear_page_dirty (struct page *page);
include/linux/swap.h +17 -0
@@ -7,6 +7,7 @@#include <linux/mmzone.h> #include <linux/list.h> #include <linux/sched.h> +#include <linux/mm.h> #include <asm/atomic.h> #include <asm/page.h>
@@ -163,6 +164,22 @@ extern unsigned int remember_page(structextern unsigned int recently_evicted (struct address_space *,unsigned long );extern void init_nonresident (void ); +/* linux/mm/cart.c */ +extern void cart_init (void ); +extern void __cart_insert (struct zone *,struct page *); +extern unsigned long cart_replace (struct zone *,struct list_head *,unsigned long ,unsigned long *); +extern void cart_reinsert (struct zone *,struct list_head *); +extern void __cart_remember (struct zone *,struct page *); + +static inline void cart_remember (struct page *page) +{ +unsigned long flags; +struct zone *zone =page_zone (page); +spin_lock_irqsave (&zone->lru_lock, flags); +__cart_remember (zone, page); +spin_unlock_irqrestore (&zone->lru_lock, flags); +} +/* linux/mm/page_alloc.c */ extern unsigned long totalram_pages;extern unsigned long totalhigh_pages;
init/main.c +1 -0
@@ -497,6 +497,7 @@ asmlinkage void __init start_kernel(voidvfs_caches_init_early ();init_nonresident ();mem_init (); +cart_init ();kmem_cache_init ();setup_per_cpu_pageset ();numa_policy_init ();
mm/Makefile +1 -1
@@ -13,7 +13,7 @@ obj-y := bootmem.o filemap.o mempool.o prio_tree.o $(mmu-y) obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o \ - nonresident.o + nonresident.o cart.o obj-$(CONFIG_HUGETLBFS) += hugetlb.o obj-$(CONFIG_NUMA) += mempolicy.o obj-$(CONFIG_SPARSEMEM) += sparse.o
mm/cart.c new file +487 -0
487 lines not on this page · raw message
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
RFC PATCH 4/6 CART Implementation ver 2
In reply to [email protected]fs/proc/proc_misc.c +15 -0
@@ -233,6 +233,20 @@ static struct file_operations proc_zonei .release = seq_release, }; +extern struct seq_operations cart_op; +static int cart_open (struct inode *inode,struct file *file) +{ + (void )inode; +return seq_open (file, &cart_op); +} + +static struct file_operations cart_file_operations = { + .open = cart_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; +extern struct seq_operations nonresident_op;static int nonresident_open (struct inode *inode,struct file *file) {
@@ -616,6 +630,7 @@ void __init proc_misc_init(void)create_seq_entry ("interrupts" ,0 , &proc_interrupts_operations);create_seq_entry ("slabinfo" ,S_IWUSR |S_IRUGO ,&proc_slabinfo_operations);create_seq_entry ("buddyinfo" ,S_IRUGO , &fragmentation_file_operations); +create_seq_entry ("cart" ,S_IRUGO , &cart_file_operations);create_seq_entry ("nonresident" ,S_IRUGO , &nonresident_file_operations);create_seq_entry ("vmstat" ,S_IRUGO , &proc_vmstat_file_operations);create_seq_entry ("zoneinfo" ,S_IRUGO , &proc_zoneinfo_file_operations);
mm/cart.c +86 -0
89 lines not on this page · raw message
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
RFC PATCH 5/6 CART Implementation ver 2
In reply to [email protected]mm/filemap.c +1 -9
@@ -723,7 +723,6 @@ void do_generic_mapping_read(struct addrunsigned long offset;unsigned long last_index;unsigned long next_index; -unsigned long prev_index;loff_t isize;struct page *cached_page;int error;
@@ -732,7 +731,6 @@ void do_generic_mapping_read(struct addr cached_page =NULL ; index = *ppos >>PAGE_CACHE_SHIFT ; next_index = index; - prev_index = ra.prev_page; last_index = (*ppos + desc->count +PAGE_CACHE_SIZE -1 ) >>PAGE_CACHE_SHIFT ; offset = *ppos & ~PAGE_CACHE_MASK ;
@@ -779,13 +777,7 @@ page_ok:if (mapping_writably_mapped (mapping))flush_dcache_page (page); -/* -* When (part of) the same page is read multiple times -* in succession, only mark it as accessed the first time. -*/ -if (prev_index != index) -mark_page_accessed (page); - prev_index = index; +mark_page_accessed (page);/* * Ok, we have the page, and it's up-to-date, so
mm/shmem.c +2 -5
@@ -1500,11 +1500,8 @@ static void do_shmem_file_read(struct fi*/ if (mapping_writably_mapped (mapping))flush_dcache_page (page); -/* -* Mark the page accessed if we read the beginning. -*/ -if (!offset) -mark_page_accessed (page); + +mark_page_accessed (page); }else page =ZERO_PAGE (0 );
mm/swap.c +1 -26
@@ -97,37 +97,12 @@ int rotate_reclaimable_page(struct page }/* -* FIXME: speed this up? -*/ -void fastcall activate_page(struct page *page) -{ -struct zone *zone =page_zone (page); - -spin_lock_irq (&zone->lru_lock); -if (PageLRU (page) && !PageActive (page)) { -del_page_from_inactive_list (zone, page); -SetPageActive (page); -add_page_to_active_list (zone, page); -inc_page_state (pgactivate); - } -spin_unlock_irq (&zone->lru_lock); -} - -/* * Mark a page as having seen activity. -* -* inactive,unreferenced -> inactive,referenced -* inactive,referenced -> active,unreferenced -* active,unreferenced -> active,referenced */ void fastcall mark_page_accessed(struct page *page) { -if (!PageActive (page) &&PageReferenced (page) &&PageLRU (page)) { -activate_page (page); -ClearPageReferenced (page); - }else if (!PageReferenced (page)) { +if (!PageReferenced (page))SetPageReferenced (page); - } }EXPORT_SYMBOL (mark_page_accessed);
mm/swapfile.c +2 -2
@@ -408,7 +408,7 @@ static void unuse_pte(struct vm_area_str* Move the page to the active list so it is not * immediately swapped out again after swapon. */ -activate_page (page); +SetPageReferenced (page); } static int unuse_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
@@ -508,7 +508,7 @@ static int unuse_mm(struct mm_struct *mm* Activate page so shrink_cache is unlikely to unmap its * ptes while lock is dropped, so swapoff can make progress. */ -activate_page (page); +SetPageReferenced (page);unlock_page (page);down_read (&mm->mmap_sem);lock_page (page);
mm/vmscan.c +2 -23
@@ -235,27 +235,6 @@ static int shrink_slab(unsigned long scareturn ret; } -/* Called without lock on whether page is mapped, so answer is unstable */ -static inline int page_mapping_inuse (struct page *page) -{ -struct address_space *mapping; - -/* Page is in somebody's page tables. */ -if (page_mapped (page)) -return 1 ; - -/* Be more reluctant to reclaim swapcache than pagecache */ -if (PageSwapCache (page)) -return 1 ; - - mapping =page_mapping (page); -if (!mapping) -return 0 ; - -/* File is mmap'd by somebody? */ -return mapping_mapped (mapping); -} -static inline int is_page_cache_freeable (struct page *page) {return page_count (page) - !!PagePrivate (page) ==2 ;
@@ -408,8 +387,8 @@ static int shrink_list(struct list_head goto keep_locked; referenced =page_referenced (page,1 , sc->priority <=0 ); -/* In active use or really unfreeable? Activate it. */ -if (referenced &&page_mapping_inuse (page)) + +if (referenced) goto activate_locked;#ifdef CONFIG_SWAP
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
RFC PATCH 6/6 CART Implementation ver 2
In reply to [email protected]fs/exec.c +1 -1
@@ -331,7 +331,7 @@ void install_arg_page(struct vm_area_str goto out; }inc_mm_counter (mm, rss); -lru_cache_add_active (page); +lru_cache_add (page);set_pte_at (mm, address, pte,pte_mkdirty (pte_mkwrite (mk_pte ( page, vma->vm_page_prot))));page_add_anon_rmap (page, vma, address);
include/linux/swap.h +0 -2
@@ -191,8 +191,6 @@ extern unsigned int nr_free_pagecache_pa/* linux/mm/swap.c */ extern void FASTCALL (lru_cache_add (struct page *)); -extern void FASTCALL (lru_cache_add_active (struct page *)); -extern void FASTCALL (activate_page (struct page *));extern void FASTCALL (mark_page_accessed (struct page *));extern void lru_add_drain (void );extern int rotate_reclaimable_page (struct page *page);
mm/memory.c +4 -3
@@ -1304,7 +1304,7 @@ static int do_wp_page(struct mm_struct *page_remove_rmap (old_page);flush_cache_page (vma, address, pfn);break_cow (vma, new_page, address, page_table); -lru_cache_add_active (new_page); +lru_cache_add (new_page);page_add_anon_rmap (new_page, vma, address);/* Free the old page.. */
@@ -1782,7 +1782,7 @@ do_anonymous_page(struct mm_struct *mm, entry =maybe_mkwrite (pte_mkdirty (mk_pte (page, vma->vm_page_prot)), vma); -lru_cache_add_active (page); +lru_cache_add (page);SetPageReferenced (page);page_add_anon_rmap (page, vma, addr); }
@@ -1903,7 +1903,8 @@ retry: entry =maybe_mkwrite (pte_mkdirty (entry), vma);set_pte_at (mm, address, page_table, entry);if (anon) { -lru_cache_add_active (new_page); +lru_cache_add (new_page); +SetPageReferenced (new_page);page_add_anon_rmap (new_page, vma, address); }else page_add_file_rmap (new_page);
mm/swap.c +8 -49
105 lines not on this page · raw message
mm/swap_state.c +1 -1
@@ -359,7 +359,7 @@ struct page *read_swap_cache_async(swp_e/* * Initiate read into locked page and return. */ -lru_cache_add_active (new_page); +lru_cache_add (new_page);swap_readpage (NULL , new_page);return new_page; }
mm/vmscan.c +16 -244
335 lines not on this page · raw message
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>