[PATCH] tmpfs: fix shared mempolicy leak
From: Mel Gorman This fixes a regression in 3.7-rc, which has since gone into stable. Commit 00442ad04a5e ("mempolicy: fix a memory corruption by refcount imbalance in alloc_pages_vma()") changed get_vma_policy() to raise the refcount on a shmem shared mempolicy; whereas shmem_alloc_page() went on expecting alloc_page_vma() to drop the refcount it had acquired. This deserves a rework: but for now fix the leak in shmem_alloc_page(). Hugh: shmem_swapin() did not need a fix, but surely it's clearer to use the same refcounting there as in shmem_alloc_page(), delete its onstack mempolicy, and the strange mpol_cond_copy() and __mpol_cond_copy() - those were invented to let swapin_readahead() make an unknown number of calls to alloc_pages_vma() with one mempolicy; but since 00442ad04a5e, alloc_pages_vma() has kept refcount in balance, so now no problem. Reported-and-tested-by: Tommi Rantala Signed-off-by: Mel Gorman Signed-off-by: Hugh Dickins Cc: sta...@vger.kernel.org --- include/linux/mempolicy.h | 16 mm/mempolicy.c| 22 -- mm/shmem.c| 26 -- 3 files changed, 16 insertions(+), 48 deletions(-) --- 3.7-rc8/include/linux/mempolicy.h 2012-10-14 16:16:57.637308925 -0700 +++ linux/include/linux/mempolicy.h 2012-12-04 22:38:21.812178829 -0800 @@ -82,16 +82,6 @@ static inline void mpol_cond_put(struct __mpol_put(pol); } -extern struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol, - struct mempolicy *frompol); -static inline struct mempolicy *mpol_cond_copy(struct mempolicy *tompol, - struct mempolicy *frompol) -{ - if (!frompol) - return frompol; - return __mpol_cond_copy(tompol, frompol); -} - extern struct mempolicy *__mpol_dup(struct mempolicy *pol); static inline struct mempolicy *mpol_dup(struct mempolicy *pol) { @@ -215,12 +205,6 @@ static inline void mpol_cond_put(struct { } -static inline struct mempolicy *mpol_cond_copy(struct mempolicy *to, - struct mempolicy *from) -{ - return from; -} - static inline void mpol_get(struct mempolicy *pol) { } --- 3078/mm/mempolicy.c 2012-10-20 20:56:24.675917367 -0700 +++ 3078X/mm/mempolicy.c2012-12-04 22:33:31.516171929 -0800 @@ -2037,28 +2037,6 @@ struct mempolicy *__mpol_dup(struct memp return new; } -/* - * If *frompol needs [has] an extra ref, copy *frompol to *tompol , - * eliminate the * MPOL_F_* flags that require conditional ref and - * [NOTE!!!] drop the extra ref. Not safe to reference *frompol directly - * after return. Use the returned value. - * - * Allows use of a mempolicy for, e.g., multiple allocations with a single - * policy lookup, even if the policy needs/has extra ref on lookup. - * shmem_readahead needs this. - */ -struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol, - struct mempolicy *frompol) -{ - if (!mpol_needs_cond_ref(frompol)) - return frompol; - - *tompol = *frompol; - tompol->flags &= ~MPOL_F_SHARED;/* copy doesn't need unref */ - __mpol_put(frompol); - return tompol; -} - /* Slow path of a mempolicy comparison */ bool __mpol_equal(struct mempolicy *a, struct mempolicy *b) { --- 3078/mm/shmem.c 2012-11-16 19:26:56.388459961 -0800 +++ 3078X/mm/shmem.c2012-12-04 22:32:35.328170594 -0800 @@ -910,25 +910,29 @@ static struct mempolicy *shmem_get_sbmpo static struct page *shmem_swapin(swp_entry_t swap, gfp_t gfp, struct shmem_inode_info *info, pgoff_t index) { - struct mempolicy mpol, *spol; struct vm_area_struct pvma; - - spol = mpol_cond_copy(, - mpol_shared_policy_lookup(>policy, index)); + struct page *page; /* Create a pseudo vma that just contains the policy */ pvma.vm_start = 0; /* Bias interleave by inode number to distribute better across nodes */ pvma.vm_pgoff = index + info->vfs_inode.i_ino; pvma.vm_ops = NULL; - pvma.vm_policy = spol; - return swapin_readahead(swap, gfp, , 0); + pvma.vm_policy = mpol_shared_policy_lookup(>policy, index); + + page = swapin_readahead(swap, gfp, , 0); + + /* Drop reference taken by mpol_shared_policy_lookup() */ + mpol_cond_put(pvma.vm_policy); + + return page; } static struct page *shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info, pgoff_t index) { struct vm_area_struct pvma; + struct page *page; /* Create a pseudo vma that just contains the policy */ pvma.vm_start = 0; @@ -937,10 +941,12 @@ static struct page *shmem_alloc_page(gfp pvma.vm_ops = NULL; pvma.vm_policy = mpol_shared_policy_lookup(>policy, index); -
Re: [PATCH] tmpfs: fix shared mempolicy leak
On Wed, 5 Dec 2012, Tommi Rantala wrote: > 2012/12/5 Mel Gorman : > > On Tue, Dec 04, 2012 at 11:24:30PM -0800, Hugh Dickins wrote: > >> From: Mel Gorman > >> > >> Commit 00442ad04a5e ("mempolicy: fix a memory corruption by refcount > >> imbalance in alloc_pages_vma()") changed get_vma_policy() to raise the > >> refcount on a shmem shared mempolicy; whereas shmem_alloc_page() went > >> on expecting alloc_page_vma() to drop the refcount it had acquired. > >> This deserves a rework: but for now fix the leak in shmem_alloc_page(). > > > > Thanks Hugh for turning gibber into a patch! > > > > Signed-off-by: Mel Gorman > > > > Tommi, just in case, can you confirm this fixes the problem for you please? > > Confirmed! No more complaints from kmemleak. Great, thanks. I'll update the tags and send straight to Linus now. Hugh -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] tmpfs: fix shared mempolicy leak
2012/12/5 Mel Gorman : > On Tue, Dec 04, 2012 at 11:24:30PM -0800, Hugh Dickins wrote: >> From: Mel Gorman >> >> Commit 00442ad04a5e ("mempolicy: fix a memory corruption by refcount >> imbalance in alloc_pages_vma()") changed get_vma_policy() to raise the >> refcount on a shmem shared mempolicy; whereas shmem_alloc_page() went >> on expecting alloc_page_vma() to drop the refcount it had acquired. >> This deserves a rework: but for now fix the leak in shmem_alloc_page(). > > Thanks Hugh for turning gibber into a patch! > > Signed-off-by: Mel Gorman > > Tommi, just in case, can you confirm this fixes the problem for you please? Confirmed! No more complaints from kmemleak. Thanks, Tommi -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] tmpfs: fix shared mempolicy leak
On Tue, Dec 04, 2012 at 11:24:30PM -0800, Hugh Dickins wrote: > From: Mel Gorman > > Commit 00442ad04a5e ("mempolicy: fix a memory corruption by refcount > imbalance in alloc_pages_vma()") changed get_vma_policy() to raise the > refcount on a shmem shared mempolicy; whereas shmem_alloc_page() went > on expecting alloc_page_vma() to drop the refcount it had acquired. > This deserves a rework: but for now fix the leak in shmem_alloc_page(). > > Hugh: shmem_swapin() did not need a fix, but surely it's clearer to use > the same refcounting there as in shmem_alloc_page(), delete its onstack > mempolicy, and the strange mpol_cond_copy() and __mpol_cond_copy() - > those were invented to let swapin_readahead() make an unknown number of > calls to alloc_pages_vma() with one mempolicy; but since 00442ad04a5e, > alloc_pages_vma() has kept refcount in balance, so now no problem. > Agreed. Anything that reduces the complexity of the mempolicy ref counting is worthwhile even if it's only by a small bit. > Reported-by: Tommi Rantala > Awaiting-signed-off-by: Mel Gorman > Signed-off-by: Hugh Dickins > Cc: sta...@vger.kernel.org Thanks Hugh for turning gibber into a patch! Signed-off-by: Mel Gorman Tommi, just in case, can you confirm this fixes the problem for you please? -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] tmpfs: fix shared mempolicy leak
On Tue, Dec 04, 2012 at 11:24:30PM -0800, Hugh Dickins wrote: From: Mel Gorman mgor...@suse.de Commit 00442ad04a5e (mempolicy: fix a memory corruption by refcount imbalance in alloc_pages_vma()) changed get_vma_policy() to raise the refcount on a shmem shared mempolicy; whereas shmem_alloc_page() went on expecting alloc_page_vma() to drop the refcount it had acquired. This deserves a rework: but for now fix the leak in shmem_alloc_page(). Hugh: shmem_swapin() did not need a fix, but surely it's clearer to use the same refcounting there as in shmem_alloc_page(), delete its onstack mempolicy, and the strange mpol_cond_copy() and __mpol_cond_copy() - those were invented to let swapin_readahead() make an unknown number of calls to alloc_pages_vma() with one mempolicy; but since 00442ad04a5e, alloc_pages_vma() has kept refcount in balance, so now no problem. Agreed. Anything that reduces the complexity of the mempolicy ref counting is worthwhile even if it's only by a small bit. Reported-by: Tommi Rantala tt.rant...@gmail.com Awaiting-signed-off-by: Mel Gorman mgor...@suse.de Signed-off-by: Hugh Dickins hu...@google.com Cc: sta...@vger.kernel.org Thanks Hugh for turning gibber into a patch! Signed-off-by: Mel Gorman mgor...@suse.de Tommi, just in case, can you confirm this fixes the problem for you please? -- Mel Gorman SUSE Labs -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] tmpfs: fix shared mempolicy leak
2012/12/5 Mel Gorman mgor...@suse.de: On Tue, Dec 04, 2012 at 11:24:30PM -0800, Hugh Dickins wrote: From: Mel Gorman mgor...@suse.de Commit 00442ad04a5e (mempolicy: fix a memory corruption by refcount imbalance in alloc_pages_vma()) changed get_vma_policy() to raise the refcount on a shmem shared mempolicy; whereas shmem_alloc_page() went on expecting alloc_page_vma() to drop the refcount it had acquired. This deserves a rework: but for now fix the leak in shmem_alloc_page(). Thanks Hugh for turning gibber into a patch! Signed-off-by: Mel Gorman mgor...@suse.de Tommi, just in case, can you confirm this fixes the problem for you please? Confirmed! No more complaints from kmemleak. Thanks, Tommi -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] tmpfs: fix shared mempolicy leak
On Wed, 5 Dec 2012, Tommi Rantala wrote: 2012/12/5 Mel Gorman mgor...@suse.de: On Tue, Dec 04, 2012 at 11:24:30PM -0800, Hugh Dickins wrote: From: Mel Gorman mgor...@suse.de Commit 00442ad04a5e (mempolicy: fix a memory corruption by refcount imbalance in alloc_pages_vma()) changed get_vma_policy() to raise the refcount on a shmem shared mempolicy; whereas shmem_alloc_page() went on expecting alloc_page_vma() to drop the refcount it had acquired. This deserves a rework: but for now fix the leak in shmem_alloc_page(). Thanks Hugh for turning gibber into a patch! Signed-off-by: Mel Gorman mgor...@suse.de Tommi, just in case, can you confirm this fixes the problem for you please? Confirmed! No more complaints from kmemleak. Great, thanks. I'll update the tags and send straight to Linus now. Hugh -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] tmpfs: fix shared mempolicy leak
From: Mel Gorman mgor...@suse.de This fixes a regression in 3.7-rc, which has since gone into stable. Commit 00442ad04a5e (mempolicy: fix a memory corruption by refcount imbalance in alloc_pages_vma()) changed get_vma_policy() to raise the refcount on a shmem shared mempolicy; whereas shmem_alloc_page() went on expecting alloc_page_vma() to drop the refcount it had acquired. This deserves a rework: but for now fix the leak in shmem_alloc_page(). Hugh: shmem_swapin() did not need a fix, but surely it's clearer to use the same refcounting there as in shmem_alloc_page(), delete its onstack mempolicy, and the strange mpol_cond_copy() and __mpol_cond_copy() - those were invented to let swapin_readahead() make an unknown number of calls to alloc_pages_vma() with one mempolicy; but since 00442ad04a5e, alloc_pages_vma() has kept refcount in balance, so now no problem. Reported-and-tested-by: Tommi Rantala tt.rant...@gmail.com Signed-off-by: Mel Gorman mgor...@suse.de Signed-off-by: Hugh Dickins hu...@google.com Cc: sta...@vger.kernel.org --- include/linux/mempolicy.h | 16 mm/mempolicy.c| 22 -- mm/shmem.c| 26 -- 3 files changed, 16 insertions(+), 48 deletions(-) --- 3.7-rc8/include/linux/mempolicy.h 2012-10-14 16:16:57.637308925 -0700 +++ linux/include/linux/mempolicy.h 2012-12-04 22:38:21.812178829 -0800 @@ -82,16 +82,6 @@ static inline void mpol_cond_put(struct __mpol_put(pol); } -extern struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol, - struct mempolicy *frompol); -static inline struct mempolicy *mpol_cond_copy(struct mempolicy *tompol, - struct mempolicy *frompol) -{ - if (!frompol) - return frompol; - return __mpol_cond_copy(tompol, frompol); -} - extern struct mempolicy *__mpol_dup(struct mempolicy *pol); static inline struct mempolicy *mpol_dup(struct mempolicy *pol) { @@ -215,12 +205,6 @@ static inline void mpol_cond_put(struct { } -static inline struct mempolicy *mpol_cond_copy(struct mempolicy *to, - struct mempolicy *from) -{ - return from; -} - static inline void mpol_get(struct mempolicy *pol) { } --- 3078/mm/mempolicy.c 2012-10-20 20:56:24.675917367 -0700 +++ 3078X/mm/mempolicy.c2012-12-04 22:33:31.516171929 -0800 @@ -2037,28 +2037,6 @@ struct mempolicy *__mpol_dup(struct memp return new; } -/* - * If *frompol needs [has] an extra ref, copy *frompol to *tompol , - * eliminate the * MPOL_F_* flags that require conditional ref and - * [NOTE!!!] drop the extra ref. Not safe to reference *frompol directly - * after return. Use the returned value. - * - * Allows use of a mempolicy for, e.g., multiple allocations with a single - * policy lookup, even if the policy needs/has extra ref on lookup. - * shmem_readahead needs this. - */ -struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol, - struct mempolicy *frompol) -{ - if (!mpol_needs_cond_ref(frompol)) - return frompol; - - *tompol = *frompol; - tompol-flags = ~MPOL_F_SHARED;/* copy doesn't need unref */ - __mpol_put(frompol); - return tompol; -} - /* Slow path of a mempolicy comparison */ bool __mpol_equal(struct mempolicy *a, struct mempolicy *b) { --- 3078/mm/shmem.c 2012-11-16 19:26:56.388459961 -0800 +++ 3078X/mm/shmem.c2012-12-04 22:32:35.328170594 -0800 @@ -910,25 +910,29 @@ static struct mempolicy *shmem_get_sbmpo static struct page *shmem_swapin(swp_entry_t swap, gfp_t gfp, struct shmem_inode_info *info, pgoff_t index) { - struct mempolicy mpol, *spol; struct vm_area_struct pvma; - - spol = mpol_cond_copy(mpol, - mpol_shared_policy_lookup(info-policy, index)); + struct page *page; /* Create a pseudo vma that just contains the policy */ pvma.vm_start = 0; /* Bias interleave by inode number to distribute better across nodes */ pvma.vm_pgoff = index + info-vfs_inode.i_ino; pvma.vm_ops = NULL; - pvma.vm_policy = spol; - return swapin_readahead(swap, gfp, pvma, 0); + pvma.vm_policy = mpol_shared_policy_lookup(info-policy, index); + + page = swapin_readahead(swap, gfp, pvma, 0); + + /* Drop reference taken by mpol_shared_policy_lookup() */ + mpol_cond_put(pvma.vm_policy); + + return page; } static struct page *shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info, pgoff_t index) { struct vm_area_struct pvma; + struct page *page; /* Create a pseudo vma that just contains the policy */ pvma.vm_start = 0; @@ -937,10 +941,12 @@ static struct page *shmem_alloc_page(gfp pvma.vm_ops =
[PATCH] tmpfs: fix shared mempolicy leak
From: Mel Gorman Commit 00442ad04a5e ("mempolicy: fix a memory corruption by refcount imbalance in alloc_pages_vma()") changed get_vma_policy() to raise the refcount on a shmem shared mempolicy; whereas shmem_alloc_page() went on expecting alloc_page_vma() to drop the refcount it had acquired. This deserves a rework: but for now fix the leak in shmem_alloc_page(). Hugh: shmem_swapin() did not need a fix, but surely it's clearer to use the same refcounting there as in shmem_alloc_page(), delete its onstack mempolicy, and the strange mpol_cond_copy() and __mpol_cond_copy() - those were invented to let swapin_readahead() make an unknown number of calls to alloc_pages_vma() with one mempolicy; but since 00442ad04a5e, alloc_pages_vma() has kept refcount in balance, so now no problem. Reported-by: Tommi Rantala Awaiting-signed-off-by: Mel Gorman Signed-off-by: Hugh Dickins Cc: sta...@vger.kernel.org --- include/linux/mempolicy.h | 16 mm/mempolicy.c| 22 -- mm/shmem.c| 26 -- 3 files changed, 16 insertions(+), 48 deletions(-) --- 3.7-rc8/include/linux/mempolicy.h 2012-10-14 16:16:57.637308925 -0700 +++ linux/include/linux/mempolicy.h 2012-12-04 22:38:21.812178829 -0800 @@ -82,16 +82,6 @@ static inline void mpol_cond_put(struct __mpol_put(pol); } -extern struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol, - struct mempolicy *frompol); -static inline struct mempolicy *mpol_cond_copy(struct mempolicy *tompol, - struct mempolicy *frompol) -{ - if (!frompol) - return frompol; - return __mpol_cond_copy(tompol, frompol); -} - extern struct mempolicy *__mpol_dup(struct mempolicy *pol); static inline struct mempolicy *mpol_dup(struct mempolicy *pol) { @@ -215,12 +205,6 @@ static inline void mpol_cond_put(struct { } -static inline struct mempolicy *mpol_cond_copy(struct mempolicy *to, - struct mempolicy *from) -{ - return from; -} - static inline void mpol_get(struct mempolicy *pol) { } --- 3078/mm/mempolicy.c 2012-10-20 20:56:24.675917367 -0700 +++ 3078X/mm/mempolicy.c2012-12-04 22:33:31.516171929 -0800 @@ -2037,28 +2037,6 @@ struct mempolicy *__mpol_dup(struct memp return new; } -/* - * If *frompol needs [has] an extra ref, copy *frompol to *tompol , - * eliminate the * MPOL_F_* flags that require conditional ref and - * [NOTE!!!] drop the extra ref. Not safe to reference *frompol directly - * after return. Use the returned value. - * - * Allows use of a mempolicy for, e.g., multiple allocations with a single - * policy lookup, even if the policy needs/has extra ref on lookup. - * shmem_readahead needs this. - */ -struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol, - struct mempolicy *frompol) -{ - if (!mpol_needs_cond_ref(frompol)) - return frompol; - - *tompol = *frompol; - tompol->flags &= ~MPOL_F_SHARED;/* copy doesn't need unref */ - __mpol_put(frompol); - return tompol; -} - /* Slow path of a mempolicy comparison */ bool __mpol_equal(struct mempolicy *a, struct mempolicy *b) { --- 3078/mm/shmem.c 2012-11-16 19:26:56.388459961 -0800 +++ 3078X/mm/shmem.c2012-12-04 22:32:35.328170594 -0800 @@ -910,25 +910,29 @@ static struct mempolicy *shmem_get_sbmpo static struct page *shmem_swapin(swp_entry_t swap, gfp_t gfp, struct shmem_inode_info *info, pgoff_t index) { - struct mempolicy mpol, *spol; struct vm_area_struct pvma; - - spol = mpol_cond_copy(, - mpol_shared_policy_lookup(>policy, index)); + struct page *page; /* Create a pseudo vma that just contains the policy */ pvma.vm_start = 0; /* Bias interleave by inode number to distribute better across nodes */ pvma.vm_pgoff = index + info->vfs_inode.i_ino; pvma.vm_ops = NULL; - pvma.vm_policy = spol; - return swapin_readahead(swap, gfp, , 0); + pvma.vm_policy = mpol_shared_policy_lookup(>policy, index); + + page = swapin_readahead(swap, gfp, , 0); + + /* Drop reference taken by mpol_shared_policy_lookup() */ + mpol_cond_put(pvma.vm_policy); + + return page; } static struct page *shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info, pgoff_t index) { struct vm_area_struct pvma; + struct page *page; /* Create a pseudo vma that just contains the policy */ pvma.vm_start = 0; @@ -937,10 +941,12 @@ static struct page *shmem_alloc_page(gfp pvma.vm_ops = NULL; pvma.vm_policy = mpol_shared_policy_lookup(>policy, index); - /* -* alloc_page_vma() will drop the shared policy reference -
[PATCH] tmpfs: fix shared mempolicy leak
From: Mel Gorman mgor...@suse.de Commit 00442ad04a5e (mempolicy: fix a memory corruption by refcount imbalance in alloc_pages_vma()) changed get_vma_policy() to raise the refcount on a shmem shared mempolicy; whereas shmem_alloc_page() went on expecting alloc_page_vma() to drop the refcount it had acquired. This deserves a rework: but for now fix the leak in shmem_alloc_page(). Hugh: shmem_swapin() did not need a fix, but surely it's clearer to use the same refcounting there as in shmem_alloc_page(), delete its onstack mempolicy, and the strange mpol_cond_copy() and __mpol_cond_copy() - those were invented to let swapin_readahead() make an unknown number of calls to alloc_pages_vma() with one mempolicy; but since 00442ad04a5e, alloc_pages_vma() has kept refcount in balance, so now no problem. Reported-by: Tommi Rantala tt.rant...@gmail.com Awaiting-signed-off-by: Mel Gorman mgor...@suse.de Signed-off-by: Hugh Dickins hu...@google.com Cc: sta...@vger.kernel.org --- include/linux/mempolicy.h | 16 mm/mempolicy.c| 22 -- mm/shmem.c| 26 -- 3 files changed, 16 insertions(+), 48 deletions(-) --- 3.7-rc8/include/linux/mempolicy.h 2012-10-14 16:16:57.637308925 -0700 +++ linux/include/linux/mempolicy.h 2012-12-04 22:38:21.812178829 -0800 @@ -82,16 +82,6 @@ static inline void mpol_cond_put(struct __mpol_put(pol); } -extern struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol, - struct mempolicy *frompol); -static inline struct mempolicy *mpol_cond_copy(struct mempolicy *tompol, - struct mempolicy *frompol) -{ - if (!frompol) - return frompol; - return __mpol_cond_copy(tompol, frompol); -} - extern struct mempolicy *__mpol_dup(struct mempolicy *pol); static inline struct mempolicy *mpol_dup(struct mempolicy *pol) { @@ -215,12 +205,6 @@ static inline void mpol_cond_put(struct { } -static inline struct mempolicy *mpol_cond_copy(struct mempolicy *to, - struct mempolicy *from) -{ - return from; -} - static inline void mpol_get(struct mempolicy *pol) { } --- 3078/mm/mempolicy.c 2012-10-20 20:56:24.675917367 -0700 +++ 3078X/mm/mempolicy.c2012-12-04 22:33:31.516171929 -0800 @@ -2037,28 +2037,6 @@ struct mempolicy *__mpol_dup(struct memp return new; } -/* - * If *frompol needs [has] an extra ref, copy *frompol to *tompol , - * eliminate the * MPOL_F_* flags that require conditional ref and - * [NOTE!!!] drop the extra ref. Not safe to reference *frompol directly - * after return. Use the returned value. - * - * Allows use of a mempolicy for, e.g., multiple allocations with a single - * policy lookup, even if the policy needs/has extra ref on lookup. - * shmem_readahead needs this. - */ -struct mempolicy *__mpol_cond_copy(struct mempolicy *tompol, - struct mempolicy *frompol) -{ - if (!mpol_needs_cond_ref(frompol)) - return frompol; - - *tompol = *frompol; - tompol-flags = ~MPOL_F_SHARED;/* copy doesn't need unref */ - __mpol_put(frompol); - return tompol; -} - /* Slow path of a mempolicy comparison */ bool __mpol_equal(struct mempolicy *a, struct mempolicy *b) { --- 3078/mm/shmem.c 2012-11-16 19:26:56.388459961 -0800 +++ 3078X/mm/shmem.c2012-12-04 22:32:35.328170594 -0800 @@ -910,25 +910,29 @@ static struct mempolicy *shmem_get_sbmpo static struct page *shmem_swapin(swp_entry_t swap, gfp_t gfp, struct shmem_inode_info *info, pgoff_t index) { - struct mempolicy mpol, *spol; struct vm_area_struct pvma; - - spol = mpol_cond_copy(mpol, - mpol_shared_policy_lookup(info-policy, index)); + struct page *page; /* Create a pseudo vma that just contains the policy */ pvma.vm_start = 0; /* Bias interleave by inode number to distribute better across nodes */ pvma.vm_pgoff = index + info-vfs_inode.i_ino; pvma.vm_ops = NULL; - pvma.vm_policy = spol; - return swapin_readahead(swap, gfp, pvma, 0); + pvma.vm_policy = mpol_shared_policy_lookup(info-policy, index); + + page = swapin_readahead(swap, gfp, pvma, 0); + + /* Drop reference taken by mpol_shared_policy_lookup() */ + mpol_cond_put(pvma.vm_policy); + + return page; } static struct page *shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info, pgoff_t index) { struct vm_area_struct pvma; + struct page *page; /* Create a pseudo vma that just contains the policy */ pvma.vm_start = 0; @@ -937,10 +941,12 @@ static struct page *shmem_alloc_page(gfp pvma.vm_ops = NULL; pvma.vm_policy = mpol_shared_policy_lookup(info-policy,