Hotcold removal completion
Subsystems (17)
cover Hotcold removal completion
The patch that we had in mm for the removal of the cold page queue was merged. However, there were 3 more pages that I think are necessary to complete the work. Mel's testing indicated that the patch in mm is inferior to simply removing the hot cold distinction in the VM altogether
(see http://marc.info/?t=119507025400001&r=1&w=2).
These 3 patches get rid of cold page handling in the VM.
--
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>
PATCH 1/3 Eliminate the hot/cold distinction in the page allocator
2.6.25-rc1 contains only a part of the patches that were done to get rid of the cold/hot distinction. Performance tests showed that the list operations added to simulate the hot/cold distinction using a single list are worse than not having that distinction at all.
See the discussion and the tests that Mel Gorman performed with this patch at
http://marc.info/?t=119507025400001&r=1&w=2
--- include/linux/gfp.h | 3 +-- mm/page_alloc.c | 34 +++++++--------------------------- mm/swap.c | 2 +- 3 files changed, 9 insertions(+), 30 deletions(-)
include/linux/gfp.h +1 -2
@@ -214,8 +214,7 @@ extern unsigned long FASTCALL(get_zeroedextern void FASTCALL (__free_pages (struct page *page,unsigned int order));extern void FASTCALL (free_pages (unsigned long addr,unsigned int order)); -extern void FASTCALL (free_hot_page (struct page *page)); -extern void FASTCALL (free_cold_page (struct page *page)); +extern void FASTCALL (free_a_page (struct page *page));#define __free_page (page) __free_pages((page), 0)#define free_page (addr) free_pages((addr),0)
mm/page_alloc.c +7 -27
@@ -975,7 +975,7 @@ void mark_free_pages(struct zone *zone)/* * Free a 0-order page */ -static void free_hot_cold_page (struct page *page,int cold) +void free_a_page (struct page *page) {struct zone *zone =page_zone (page);struct per_cpu_pages *pcp;
@@ -995,10 +995,7 @@ static void free_hot_cold_page(struct pa pcp = &zone_pcp (zone,get_cpu ())->pcp;local_irq_save (flags);__count_vm_event (PGFREE ); -if (cold) -list_add_tail (&page->lru, &pcp->list); -else -list_add (&page->lru, &pcp->list); +list_add (&page->lru, &pcp->list);set_page_private (page,get_pageblock_migratetype (page)); pcp->count++;if (pcp->count >= pcp->high) {
@@ -1009,16 +1006,6 @@ static void free_hot_cold_page(struct paput_cpu (); } -void free_hot_page (struct page *page) -{ -free_hot_cold_page (page,0 ); -} - -void free_cold_page (struct page *page) -{ -free_hot_cold_page (page,1 ); -} -/* * split_page takes a non-compound higher-order page, and splits it into * n (1<<order) sub-pages: page[0..n]
@@ -1047,7 +1034,6 @@ static struct page *buffered_rmqueue(str {unsigned long flags;struct page *page; -int cold = !!(gfp_flags & __GFP_COLD);int cpu;int migratetype =allocflags_to_migratetype (gfp_flags);
@@ -1066,15 +1052,9 @@ again: }/* Find a page of the appropriate migrate type */ -if (cold) { -list_for_each_entry_reverse (page, &pcp->list, lru) -if (page_private (page) == migratetype) -break ; - }else { -list_for_each_entry (page, &pcp->list, lru) -if (page_private (page) == migratetype) -break ; - } +list_for_each_entry (page, &pcp->list, lru) +if (page_private (page) == migratetype) +break ;/* Allocate more to the pcp list if necessary */ if (unlikely (&page->lru == &pcp->list)) {
@@ -1677,14 +1657,14 @@ void __pagevec_free(struct pagevec *pvecint i =pagevec_count (pvec);while (--i >=0 ) -free_hot_cold_page (pvec->pages[i], pvec->cold); +free_a_page (pvec->pages[i]); }void __free_pages (struct page *page,unsigned int order) {if (put_page_testzero (page)) {if (order ==0 ) -free_hot_page (page); +free_a_page (page);else __free_pages_ok (page, order); }
mm/swap.c +1 -1
@@ -54,7 +54,7 @@ static void __page_cache_release(structdel_page_from_lru (zone, page);spin_unlock_irqrestore (&zone->lru_lock, flags); } -free_hot_page (page); +free_a_page (page); }static void put_compound_page (struct page *page)
Signature · 5 lines
-- 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>
PATCH 2/3 Remove GFP_COLD
In reply to Christoph LameterOn top of the patch that eliminates the hot/cold distinction:
There is no point in having GFP_COLD if we do not have a hot/cold distinction in the pcp lists. Remove __GFP_COLD and the use of page_cache_alloc_cold().
--- fs/splice.c | 2 +- include/linux/gfp.h | 1 - include/linux/pagemap.h | 5 ----- include/linux/slab.h | 3 --- kernel/power/snapshot.c | 8 ++++---- mm/filemap.c | 6 +++--- mm/readahead.c | 2 +- 7 files changed, 9 insertions(+), 18 deletions(-)
fs/splice.c +1 -1
@@ -315,7 +315,7 @@ __generic_file_splice_read(struct file */* * page didn't exist, allocate one. */ - page =page_cache_alloc_cold (mapping); + page =page_cache_alloc (mapping);if (!page)break ;
include/linux/gfp.h +0 -1
@@ -38,7 +38,6 @@ struct vm_area_struct;#define __GFP_HIGH ((__force gfp_t)0x20u)/* Should access emergency pools? */ #define __GFP_IO ((__force gfp_t)0x40u)/* Can start physical IO? */ #define __GFP_FS ((__force gfp_t)0x80u)/* Can call down to low-level FS? */ -#define __GFP_COLD ((__force gfp_t)0x100u)/* Cache-cold page required */ #define __GFP_NOWARN ((__force gfp_t)0x200u)/* Suppress page allocation failure warning */ #define __GFP_REPEAT ((__force gfp_t)0x400u)/* Retry the allocation. Might fail */ #define __GFP_NOFAIL ((__force gfp_t)0x800u)/* Retry for ever. Cannot fail */
include/linux/pagemap.h +0 -5
@@ -76,11 +76,6 @@ static inline struct page *page_cache_alreturn __page_cache_alloc (mapping_gfp_mask (x)); } -static inline struct page *page_cache_alloc_cold (struct address_space *x) -{ -return __page_cache_alloc (mapping_gfp_mask (x)|__GFP_COLD); -} -typedef int filler_t (void *,struct page *); extern struct page * find_get_page(struct address_space *mapping,
include/linux/slab.h +0 -3
@@ -154,9 +154,6 @@ size_t ksize(const void *);* Also it is possible to set different flags by OR'ing * in one or more of the following additional @flags: * -* %__GFP_COLD - Request cache-cold pages instead of -* trying to return cache-warm pages. -* * %__GFP_HIGH - This allocation has high priority and may use emergency pools. * * %__GFP_NOFAIL - Indicate that this allocation is in no way allowed to fail
kernel/power/snapshot.c +4 -4
@@ -1102,7 +1102,7 @@ static int enough_free_mem(unsigned intstatic inline int get_highmem_buffer (int safe_needed) { - buffer =get_image_page (GFP_ATOMIC | __GFP_COLD, safe_needed); + buffer =get_image_page (GFP_ATOMIC , safe_needed);return buffer ?0 : -ENOMEM ; }
@@ -1154,11 +1154,11 @@ swsusp_alloc(struct memory_bitmap *orig_ {int error; - error =memory_bm_create (orig_bm,GFP_ATOMIC | __GFP_COLD,PG_ANY ); + error =memory_bm_create (orig_bm,GFP_ATOMIC ,PG_ANY );if (error) goto Free; - error =memory_bm_create (copy_bm,GFP_ATOMIC | __GFP_COLD,PG_ANY ); + error =memory_bm_create (copy_bm,GFP_ATOMIC ,PG_ANY );if (error) goto Free;
@@ -1170,7 +1170,7 @@ swsusp_alloc(struct memory_bitmap *orig_ nr_pages +=alloc_highmem_image_pages (copy_bm, nr_highmem); }while (nr_pages-- >0 ) { -struct page *page =alloc_image_page (GFP_ATOMIC | __GFP_COLD); +struct page *page =alloc_image_page (GFP_ATOMIC );if (!page) goto Free;
mm/readahead.c +1 -1
@@ -153,7 +153,7 @@ __do_page_cache_readahead(struct addressif (page)continue ; - page =page_cache_alloc_cold (mapping); + page =page_cache_alloc (mapping);if (!page)break ; page->index = page_offset;
mm/filemap.c +3 -3
@@ -1058,7 +1058,7 @@ no_cached_page:* Ok, it wasn't cached, so we need to create a new * page.. */ - page =page_cache_alloc_cold (mapping); + page =page_cache_alloc (mapping);if (!page) { desc->error = -ENOMEM ; goto out;
@@ -1285,7 +1285,7 @@ static int page_cache_read(struct file *int ret; do { - page = page_cache_alloc_cold(mapping); + page = page_cache_alloc(mapping); if (!page) return -ENOMEM;
@@ -1519,7 +1519,7 @@ static struct page *__read_cache_page(st repeat: page =find_get_page (mapping, index);if (!page) { - page =page_cache_alloc_cold (mapping); + page =page_cache_alloc (mapping);if (!page)return ERR_PTR (-ENOMEM ); err =add_to_page_cache_lru (page, mapping, index,GFP_KERNEL );
Signature · 5 lines
-- 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>
PATCH 3/3 Remove cold field from pagevec
In reply to Christoph LameterWe have removed the distinction between hot/cold in the page allocator and also the use of GFP_COLD. Then we also do not need the cold field in the pagevecs anymore.
--- fs/afs/write.c | 4 ++-- fs/cifs/file.c | 4 ++-- fs/gfs2/ops_address.c | 2 +- fs/hugetlbfs/inode.c | 2 +- fs/nfs/dir.c | 2 +- fs/ntfs/file.c | 2 +- fs/ramfs/file-nommu.c | 2 +- fs/reiser4/plugin/file/file.c | 2 +- fs/xfs/linux-2.6/xfs_aops.c | 4 ++-- include/linux/pagemap.h | 2 +- include/linux/pagevec.h | 4 +--- mm/filemap.c | 2 +- mm/page-writeback.c | 2 +- mm/swap.c | 14 +++++++------- mm/swap_state.c | 2 +- mm/truncate.c | 6 +++--- mm/vmscan.c | 6 +++--- 17 files changed, 30 insertions(+), 32 deletions(-)
include/linux/pagemap.h +1 -1
@@ -60,7 +60,7 @@ static inline void mapping_set_gfp_mask(#define page_cache_get (page) get_page(page)#define page_cache_release (page) put_page(page) -void release_pages (struct page **pages,int nr,int cold); +void release_pages (struct page **pages,int nr);#ifdef CONFIG_NUMA extern struct page *__page_cache_alloc (gfp_t gfp);
include/linux/pagevec.h +1 -3
@@ -16,7 +16,6 @@ struct address_space;struct pagevec {unsigned long nr; -unsigned long cold;struct page *pages[PAGEVEC_SIZE ]; };
@@ -32,10 +31,9 @@ unsigned pagevec_lookup_tag(struct pagev struct address_space *mapping, pgoff_t *index, int tag, unsigned nr_pages); -static inline void pagevec_init (struct pagevec *pvec,int cold) +static inline void pagevec_init (struct pagevec *pvec) { pvec->nr =0 ; - pvec->cold = cold; }static inline void pagevec_reinit (struct pagevec *pvec)
mm/filemap.c +1 -1
@@ -276,7 +276,7 @@ int wait_on_page_writeback_range(structif (end < start)return 0 ; -pagevec_init (&pvec,0 ); +pagevec_init (&pvec); index = start; while ((index <= end) && (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
mm/page-writeback.c +1 -1
@@ -813,7 +813,7 @@ int write_cache_pages(struct address_spareturn 0 ; } -pagevec_init (&pvec,0 ); +pagevec_init (&pvec);if (wbc->range_cyclic) { index = mapping->writeback_index;/* Start from prev offset */ end =-1 ;
mm/swap.c +7 -7
@@ -125,7 +125,7 @@ static void pagevec_move_tail(struct pagif (zone)spin_unlock (&zone->lru_lock);__count_vm_events (PGROTATED , pgmoved); -release_pages (pvec->pages, pvec->nr, pvec->cold); +release_pages (pvec->pages, pvec->nr);pagevec_reinit (pvec); }
@@ -296,14 +296,14 @@ int lru_add_drain_all(void)* page count inside the lock to see whether shrink_cache grabbed the page * via the LRU. If it did, give up: shrink_cache will free it. */ -void release_pages (struct page **pages,int nr,int cold) +void release_pages (struct page **pages,int nr) {int i;struct pagevec pages_to_free;struct zone *zone =NULL ;unsigned long uninitialized_var (flags ); -pagevec_init (&pages_to_free, cold); +pagevec_init (&pages_to_free);for (i =0 ; i < nr; i++) {struct page *page = pages[i];
@@ -361,7 +361,7 @@ void release_pages(struct page **pages,void __pagevec_release (struct pagevec *pvec) {lru_add_drain (); -release_pages (pvec->pages,pagevec_count (pvec), pvec->cold); +release_pages (pvec->pages,pagevec_count (pvec));pagevec_reinit (pvec); }
@@ -377,7 +377,7 @@ void __pagevec_release_nonlru(struct pagint i;struct pagevec pages_to_free; -pagevec_init (&pages_to_free, pvec->cold); +pagevec_init (&pages_to_free);for (i =0 ; i <pagevec_count (pvec); i++) {struct page *page = pvec->pages[i];
@@ -414,7 +414,7 @@ void __pagevec_lru_add(struct pagevec *p }if (zone)spin_unlock_irq (&zone->lru_lock); -release_pages (pvec->pages, pvec->nr, pvec->cold); +release_pages (pvec->pages, pvec->nr);pagevec_reinit (pvec); }
@@ -443,7 +443,7 @@ void __pagevec_lru_add_active(struct pag }if (zone)spin_unlock_irq (&zone->lru_lock); -release_pages (pvec->pages, pvec->nr, pvec->cold); +release_pages (pvec->pages, pvec->nr);pagevec_reinit (pvec); }
mm/truncate.c +3 -3
@@ -173,7 +173,7 @@ void truncate_inode_pages_range(struct aBUG_ON ((lend & (PAGE_CACHE_SIZE -1 )) != (PAGE_CACHE_SIZE -1 )); end = (lend >>PAGE_CACHE_SHIFT ); -pagevec_init (&pvec,0 ); +pagevec_init (&pvec); next = start;while (next <= end &&pagevec_lookup (&pvec, mapping, next,PAGEVEC_SIZE )) {
@@ -274,7 +274,7 @@ unsigned long __invalidate_mapping_pagesunsigned long ret =0 ;int i; -pagevec_init (&pvec,0 ); +pagevec_init (&pvec);while (next <= end &&pagevec_lookup (&pvec, mapping, next,PAGEVEC_SIZE )) {for (i =0 ; i <pagevec_count (&pvec); i++) {
@@ -395,7 +395,7 @@ int invalidate_inode_pages2_range(structint did_range_unmap =0 ;int wrapped =0 ; -pagevec_init (&pvec,0 ); +pagevec_init (&pvec); next = start;while (next <= end && !wrapped && pagevec_lookup(&pvec, mapping, next,
mm/vmscan.c +3 -3
@@ -472,7 +472,7 @@ static unsigned long shrink_page_list(stcond_resched (); -pagevec_init (&freed_pvec,1 ); +pagevec_init (&freed_pvec);while (!list_empty (page_list)) {struct address_space *mapping;struct page *page;
@@ -834,7 +834,7 @@ static unsigned long shrink_inactive_lisunsigned long nr_scanned =0 ;unsigned long nr_reclaimed =0 ; -pagevec_init (&pvec,1 ); +pagevec_init (&pvec);lru_add_drain ();spin_lock_irq (&zone->lru_lock);
@@ -1116,7 +1116,7 @@ static void shrink_active_list(unsignedlist_add (&page->lru, &l_inactive); } -pagevec_init (&pvec,1 ); +pagevec_init (&pvec); pgmoved =0 ;spin_lock_irq (&zone->lru_lock);while (!list_empty (&l_inactive)) {
fs/afs/write.c +2 -2
@@ -330,7 +330,7 @@ static void afs_kill_pages(struct afs_vn_enter ("{%x:%u},%lx-%lx" , vnode->fid.vid, vnode->fid.vnode, first, last); -pagevec_init (&pv,0 ); +pagevec_init (&pv); do { _debug("kill %lx-%lx", first, last);
@@ -666,7 +666,7 @@ void afs_pages_written_back(struct afs_vASSERT (wb !=NULL ); -pagevec_init (&pv,0 ); +pagevec_init (&pv); do { _debug("done %lx-%lx", first, last);
fs/cifs/file.c +2 -2
@@ -1248,7 +1248,7 @@ static int cifs_writepages(struct addres xid =GetXid (); -pagevec_init (&pvec,0 ); +pagevec_init (&pvec);if (wbc->range_cyclic) { index = mapping->writeback_index;/* Start from prev offset */ end =-1 ;
@@ -1813,7 +1813,7 @@ static int cifs_readpages(struct file *f cifs_sb =CIFS_SB (file->f_path.dentry->d_sb); pTcon = cifs_sb->tcon; -pagevec_init (&lru_pvec,0 ); +pagevec_init (&lru_pvec);#ifdef CONFIG_CIFS_DEBUG2 cFYI (1 , ("rpages: num pages %d" , num_pages));#endif
fs/hugetlbfs/inode.c +1 -1
@@ -345,7 +345,7 @@ static void truncate_hugepages(struct inpgoff_t next;int i, freed =0 ; -pagevec_init (&pvec,0 ); +pagevec_init (&pvec); next = start;while (1 ) {if (!pagevec_lookup (&pvec, mapping, next,PAGEVEC_SIZE )) {
fs/nfs/dir.c +1 -1
@@ -1519,7 +1519,7 @@ static int nfs_symlink(struct inode *dir* No big deal if we can't add this page to the page cache here. * READLINK will get the missing page from the server if needed. */ -pagevec_init (&lru_pvec,0 ); +pagevec_init (&lru_pvec);if (!add_to_page_cache (page, dentry->d_inode->i_mapping,0 ,GFP_KERNEL )) {pagevec_add (&lru_pvec, page);
fs/ntfs/file.c +1 -1
@@ -1911,7 +1911,7 @@ static ssize_t ntfs_file_buffered_write( } } } -pagevec_init (&lru_pvec,0 ); +pagevec_init (&lru_pvec); written =0 ;/* * If the write starts beyond the initialized size, extend it up to the
fs/ramfs/file-nommu.c +1 -1
@@ -102,7 +102,7 @@ static int ramfs_nommu_expand_for_mappinmemset (data,0 , newsize);/* attach all the pages to the inode's address space */ -pagevec_init (&lru_pvec,0 ); +pagevec_init (&lru_pvec);for (loop =0 ; loop < npages; loop++) {struct page *page = pages + loop;
fs/reiser4/plugin/file/file.c +1 -1
@@ -989,7 +989,7 @@ capture_anonymous_pages(struct address_sunsigned int i, count;int nr; -pagevec_init (&pvec,0 ); +pagevec_init (&pvec); count =min (pagevec_space (&pvec), to_capture); nr =0 ;
fs/xfs/linux-2.6/xfs_aops.c +2 -2
@@ -651,7 +651,7 @@ xfs_probe_cluster(/* Prune this back to avoid pathological behavior */ tloff =min (tlast, startpage->index +64 ); -pagevec_init (&pvec,0 ); +pagevec_init (&pvec);while (!done && tindex <= tloff) {unsigned len =min_t (pgoff_t,PAGEVEC_SIZE , tlast - tindex +1 );
@@ -882,7 +882,7 @@ xfs_cluster_write(struct pagevec pvec;int done =0 , i; -pagevec_init (&pvec,0 ); +pagevec_init (&pvec);while (!done && tindex <= tlast) {unsigned len =min_t (pgoff_t,PAGEVEC_SIZE , tlast - tindex +1 );
mm/swap_state.c +1 -1
@@ -223,7 +223,7 @@ void free_pages_and_swap_cache(struct pafor (i =0 ; i < todo; i++)free_swap_cache (pagep[i]); -release_pages (pagep, todo,0 ); +release_pages (pagep, todo); pagep += todo; nr -= todo; }
fs/gfs2/ops_address.c +1 -1
@@ -360,7 +360,7 @@ static int gfs2_write_cache_jdata(structreturn 0 ; } -pagevec_init (&pvec,0 ); +pagevec_init (&pvec);if (wbc->range_cyclic) { index = mapping->writeback_index;/* Start from prev offset */ end =-1 ;
Signature · 5 lines
-- 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>
Quoted 2 lines · Christoph Lameter
The patch that we had in mm for the removal of the cold page queue was merged.
That patch to merge the hot and cold lists has obvious problems. It pulls cold pages off the list in the opposite order that hot pages come off the list (which is obviously bad); and also it allows cold allocations to deplete hot pages (which may not be a good idea).
Obviously the half baked code that's there now should be fixed... But whether it is to fix hot/cold properly, or to remove it completely, I don't really know.
Quoted 6 lines
However, there were 3 more pages that I think are necessary to complete the work. Mel's testing indicated that the patch in mm is inferior to simply removing the hot cold distinction in the VM altogether (see http://marc.info/?t=119507025400001&r=1&w=2).
These 3 patches get rid of cold page handling in the VM.
I'm all in favour of removing these. But honestly, I don't think kernbench, [td]bench, and aim9 are really great tests when it comes to subtle cache behaviour... OTOH, that didn't stop the last patch being merged. May as well do it.
--
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>
Andrew Morton
maintainerQuoted 10 lines · On Tue, 12 Feb 2008 17:32:29 +1100 Nick Piggin <[email protected]> wrote:
Quoted 2 lines · Christoph Lameter
The patch that we had in mm for the removal of the cold page queue was merged.
That patch to merge the hot and cold lists has obvious problems. It pulls cold pages off the list in the opposite order that hot pages come off the list (which is obviously bad); and also it allows cold allocations to deplete hot pages (which may not be a good idea).
Quoted 4 lines
Obviously the half baked code that's there now should be fixed... But whether it is to fix hot/cold properly, or to remove it completely, I don't really know.
Well that sounds bad.
Quoted 6 lines
Quoted 6 lines
However, there were 3 more pages that I think are necessary to complete the work. Mel's testing indicated that the patch in mm is inferior to simply removing the hot cold distinction in the VM altogether (see http://marc.info/?t=119507025400001&r=1&w=2).
Quoted 6 lines
Quoted 1 line
These 3 patches get rid of cold page handling in the VM.
I'm all in favour of removing these. But honestly, I don't think kernbench, [td]bench, and aim9 are really great tests when it comes to subtle cache behaviour... OTOH, that didn't stop the last patch being merged. May as well do it.
I think I'd prefer that we convince ourselves that we didn't just merge a regression rather than merging more stuff on top of it. Because right now, page-allocator-get-rid-of-the-list-of-cold-pages.patch reverts cleanly.
--
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>
Quoted 3 lines · Andrew Morton
I think I'd prefer that we convince ourselves that we didn't just merge a regression rather than merging more stuff on top of it. Because right now, page-allocator-get-rid-of-the-list-of-cold-pages.patch reverts cleanly.
Well Mel and I discussed this extensively and I have tried to get these patches merged before (early Jan) because I saw the danger of the half assed stuff getting merged. Either we should backout the half baked stuff upstream now or go the full way and remove the hot/cold distinction. \
--
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>