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 Wed, Apr 01, 2015 at 03:06:53PM -0700, Andrew Morton wrote:
> On Thu, 2 Apr 2015 01:02:46 +0300 "Kirill A. Shutemov" <kirill@xxxxxxxxxxxxx> wrote:
> 
> > On Wed, Apr 01, 2015 at 12:57:45PM -0700, Andrew Morton wrote:
> > > On Wed, 1 Apr 2015 14:50:54 +0300 "Kirill A. Shutemov" <kirill@xxxxxxxxxxxxx> wrote:
> > > 
> > > > >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
> > > 
> > > Well, code size isn't the only thing to care about.  Some functions
> > > really should be inlined for performance reasons even if that makes the
> > > overall code larger.  But the changes you're proposing here look OK to
> > > me.
> > > 
> > > > As side effect page_anon_vma() now works properly on tail pages.
> > > 
> > > Let's fix the bug in a separate patch, please.  One which can be
> > > backported to earlier kernels if that should be needed.  ie: it should
> > > precede any uninlining.
> > 
> > The bug is not triggerable in current upsteam. AFAIK, we don't call
> > page_anon_vma() on tail pages of THP, since we don't map THP with PTEs
> > yet. For rest of cases we will get NULL, which is valid answer.
> 
> argh.  It rather helps if you can tell me when this happens (and which
> patch it fixes).  I sometimes spend quite a bit of time runnnig around
> in circles wondering what the heck tree/patch just got fixed.

Sorry for the mess.

> > Do you still want "page = compound_head(page);" line in separate patch?
> 
> I think that would be best.  That way the offending patch gets fixed
> and doesn't get bundled up with an unrelated change.

I've sent updated "mm: sanitize page->mapping for tail pages" patch that
care about this part. And this is uninlining patch on top of updated
patch.

>From 17633731522fa958ee0cef5e125f06ea6ddafb08 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

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 |  9 ---------
 mm/util.c            | 42 ++++++++++++++++++++++++++++++++++++------
 3 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 16fe322b66ea..eb19c939a216 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 6e7b0443afb0..c89c53a113a8 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -105,15 +105,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)
-{
-	page = compound_head(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 e78968bd11e7..aca58b81bcfa 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -325,12 +325,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)))
@@ -340,10 +367,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]