Re: [PATCH] mm: use PageAnon() and PageKsm() helpers in page_anon_vma()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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>




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]