On Tue, Mar 31, 2015 at 01:33:38PM -0700, Andrew Morton wrote: > On Tue, 31 Mar 2015 17:35:34 +0300 "Kirill A. Shutemov" <kirill@xxxxxxxxxxxxx> wrote: > > > On Tue, Mar 31, 2015 at 08:11:02AM -0500, Christoph Lameter wrote: > > > On Tue, 31 Mar 2015, Kirill A. Shutemov wrote: > > > > > > > Let's use PageAnon() and PageKsm() helpers instead. It helps readability > > > > and makes page_anon_vma() work correctly on tail pages. > > > > > > But it adds a branch due to the use of ||. > > > > Which caller is hot enough to care? > > > > It's a surprisingly expensive patch. > > text data bss dec hex filename > > 19984 1153 15192 36329 8de9 mm/ksm.o-before > 20028 1153 15216 36397 8e2d mm/ksm.o-after > > 14728 116 5168 20012 4e2c mm/rmap.o-before > 14763 116 5192 20071 4e67 mm/rmap.o-after > > 25723 1417 9776 36916 9034 mm/swapfile.o-before > 25769 1417 9800 36986 907a mm/swapfile.o-after > > 197 bytes more text+bss, 125 bytes more text. > > (Why the heck do changes like this allegedly affect bss size?) What about this? >From adc384977898173d65c2567fc5eb421da9b272e0 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx> Date: Wed, 1 Apr 2015 14:33:56 +0300 Subject: [PATCH] mm: uninline and cleanup page-mapping related helpers Most-used page->mapping helper -- page_mapping() -- has already uninlined. Let's uninline also page_rmapping() and page_anon_vma(). It saves us depending on configuration around 400 bytes in text: text data bss dec hex filename 660318 99254 410000 1169572 11d8a4 mm/built-in.o-before 659854 99254 410000 1169108 11d6d4 mm/built-in.o As side effect page_anon_vma() now works properly on tail pages. I also tried to make code a bit more clean. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> --- include/linux/mm.h | 9 ++------- include/linux/rmap.h | 8 -------- mm/util.c | 42 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 4a3a38522ab4..0d73890afc2b 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -910,15 +910,10 @@ void page_address_init(void); #define page_address_init() do { } while(0) #endif +extern void *page_rmapping(struct page *page); +extern struct anon_vma *page_anon_vma(struct page *page); extern struct address_space *page_mapping(struct page *page); -/* Neutral page->mapping pointer to address_space or anon_vma or other */ -static inline void *page_rmapping(struct page *page) -{ - page = compound_head(page); - return (void *)((unsigned long)page->mapping & ~PAGE_MAPPING_FLAGS); -} - extern struct address_space *__page_file_mapping(struct page *); static inline diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 9c5ff69fa0cd..bf36b6e644c4 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -106,14 +106,6 @@ static inline void put_anon_vma(struct anon_vma *anon_vma) __put_anon_vma(anon_vma); } -static inline struct anon_vma *page_anon_vma(struct page *page) -{ - if (((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) != - PAGE_MAPPING_ANON) - return NULL; - return page_rmapping(page); -} - static inline void vma_lock_anon_vma(struct vm_area_struct *vma) { struct anon_vma *anon_vma = vma->anon_vma; diff --git a/mm/util.c b/mm/util.c index 769a7a2870af..426f303f8030 100644 --- a/mm/util.c +++ b/mm/util.c @@ -355,12 +355,39 @@ void kvfree(const void *addr) } EXPORT_SYMBOL(kvfree); +static inline void * __page_rmapping(struct page *page) +{ + unsigned long mapping; + + mapping = (unsigned long)page->mapping; + mapping &= ~PAGE_MAPPING_FLAGS; + + return (void *)mapping; +} + +/* Neutral page->mapping pointer to address_space or anon_vma or other */ +void *page_rmapping(struct page *page) +{ + page = compound_head(page); + return __page_rmapping(page); +} + +struct anon_vma *page_anon_vma(struct page *page) +{ + unsigned long mapping; + + page = compound_head(page); + mapping = (unsigned long)page->mapping; + if ((mapping & PAGE_MAPPING_FLAGS) != PAGE_MAPPING_ANON) + return NULL; + return __page_rmapping(page); +} + struct address_space *page_mapping(struct page *page) { - struct address_space *mapping; + unsigned long mapping; page = compound_head(page); - mapping = page->mapping; /* This happens if someone calls flush_dcache_page on slab page */ if (unlikely(PageSlab(page))) @@ -370,10 +397,13 @@ struct address_space *page_mapping(struct page *page) swp_entry_t entry; entry.val = page_private(page); - mapping = swap_address_space(entry); - } else if ((unsigned long)mapping & PAGE_MAPPING_ANON) - mapping = NULL; - return mapping; + return swap_address_space(entry); + } + + mapping = (unsigned long)page->mapping; + if (mapping & PAGE_MAPPING_FLAGS) + return NULL; + return page->mapping; } int overcommit_ratio_handler(struct ctl_table *table, int write, -- Kirill A. Shutemov -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>