respin of PageWaiters patch
Subsystems (4)
cover respin of PageWaiters patch
Seeing as Mel said he would test it (and maybe Dave could as well), I will post my patches again. There was a couple of page flags bugs pointed out last time, which should be fixed.
Thanks,
Nick
Nicholas Piggin (2):
mm: Use owner_priv bit for PageSwapCache, valid when PageSwapBacked
mm: add PageWaiters bit to indicate waitqueue should be checked
include/linux/mm.h | 2 + include/linux/page-flags.h | 33 ++++++-- include/linux/pagemap.h | 23 +++--- include/linux/writeback.h | 1 - include/trace/events/mmflags.h | 2 +- init/main.c | 3 +- mm/filemap.c | 180 +++++++++++++++++++++++++++++++++-------- mm/internal.h | 2 + mm/swap.c | 2 + 9 files changed, 189 insertions(+), 59 deletions(-)
Signature · 7 lines
2.11.0 -- 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/2 mm: Use owner_priv bit for PageSwapCache, valid when PageSwapBacked
--- include/linux/page-flags.h | 24 ++++++++++++++++-------- include/trace/events/mmflags.h | 1 - 2 files changed, 16 insertions(+), 9 deletions(-)
include/linux/page-flags.h +16 -8
@@ -87,7 +87,6 @@ enum pageflags { PG_private_2,/* If pagecache, has fs aux data */ PG_writeback,/* Page is under writeback */ PG_head,/* A head page */ - PG_swapcache,/* Swap page: swp_entry_t in private */ PG_mappedtodisk,/* Has blocks allocated on-disk */ PG_reclaim,/* To be reclaimed asap */ PG_swapbacked, /* Page is backed by RAM/swap */
@@ -110,6 +109,9 @@ enum pageflags {/* Filesystems */ PG_checked = PG_owner_priv_1, +/* SwapBacked */ + PG_swapcache = PG_owner_priv_1,/* Swap page: swp_entry_t in private */ +/* Two page bits are conscripted by FS-Cache to maintain local caching * state. These bits are set on pages belonging to the netfs's inodes * when those inodes are being locally cached.
@@ -314,7 +316,13 @@ PAGEFLAG_FALSE(HighMem)#endif #ifdef CONFIG_SWAP -PAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND) +static __always_inline int PageSwapCache(struct page *page) +{ +return PageSwapBacked (page) &&test_bit (PG_swapcache, &page->flags); + +} +SETPAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND) +CLEARPAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND)#else PAGEFLAG_FALSE(SwapCache)#endif
@@ -701,12 +709,12 @@ static inline void ClearPageSlabPfmemalloc(struct page *page)* Flags checked when a page is freed. Pages being freed should not have * these flags set. It they are, there is a problem. */ -#define PAGE_FLAGS_CHECK_AT_FREE \ - (1UL << PG_lru | 1UL << PG_locked | \ - 1UL << PG_private | 1UL << PG_private_2 | \ - 1UL << PG_writeback | 1UL << PG_reserved | \ - 1UL << PG_slab | 1UL << PG_swapcache | 1UL << PG_active | \ - 1UL << PG_unevictable | __PG_MLOCKED) +#define PAGE_FLAGS_CHECK_AT_FREE \ + (1UL << PG_lru | 1UL << PG_locked | \ + 1UL << PG_private | 1UL << PG_private_2 | \ + 1UL << PG_writeback | 1UL << PG_reserved | \ + 1UL << PG_slab | 1UL << PG_active | \ + 1UL << PG_unevictable | __PG_MLOCKED)/* * Flags checked when a page is prepped for return by the page allocator.
include/trace/events/mmflags.h +0 -1
@@ -95,7 +95,6 @@ {1UL << PG_private_2, "private_2" }, \ {1UL << PG_writeback, "writeback" }, \ {1UL << PG_head, "head" }, \ - {1UL << PG_swapcache, "swapcache" }, \ {1UL << PG_mappedtodisk, "mappedtodisk" }, \ {1UL << PG_reclaim, "reclaim" }, \ {1UL << PG_swapbacked, "swapbacked" }, \
Signature · 7 lines
2.11.0 -- 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>
Re: [PATCH 1/2] mm: Use owner_priv bit for PageSwapCache, valid when PageSwapBacked
On Thu, 22 Dec 2016, Nicholas Piggin wrote:
I agree with every word of that changelog ;)
And I'll stamp this with
The thing that Peter remembers I commented on (which 0day caught too), was to remove PG_swapcache from PAGE_FLAGS_CHECK_AT_FREE: you've done that now, so this is good. (Note in passing: wouldn't it be good to add PG_waiters to PAGE_FLAGS_CHECK_AT_FREE in the 2/2?)
Though I did yesterday notice a few more problematic uses of PG_swapcache, which you'll probably need to refine to exclude other uses of PG_owner_priv_1; though no great hurry for those, so not necessarily in this same patch. Do your own grep, but
fs/proc/page.c derives its KPF_SWAPCACHE from PG_swapcache, needs refining.
kernel/kexec_core.c says VMCOREINFO_NUMBER(PG_swapcache):
I haven't looked into what that's about, it will probably just have to be commented as now including other uses of the same bit.
mm/memory-failure.c has an error_states[] table that involves testing PG_swapcache as "sc", but looks as if it can be changed to factor in "swapbacked" too.
Hugh
Quoted 75 lines
--- include/linux/page-flags.h | 24 ++++++++++++++++-------- include/trace/events/mmflags.h | 1 - 2 files changed, 16 insertions(+), 9 deletions(-)include/linux/page-flags.h +16
-8@@ -87,7 +87,6 @@ enum pageflags { PG_private_2,/* If pagecache, has fs aux data */ PG_writeback,/* Page is under writeback */ PG_head,/* A head page */ - PG_swapcache,/* Swap page: swp_entry_t in private */ PG_mappedtodisk,/* Has blocks allocated on-disk */ PG_reclaim,/* To be reclaimed asap */ PG_swapbacked, /* Page is backed by RAM/swap */@@ -110,6 +109,9 @@ enum pageflags {/* Filesystems */ PG_checked = PG_owner_priv_1, +/* SwapBacked */ + PG_swapcache = PG_owner_priv_1,/* Swap page: swp_entry_t in private */ +/* Two page bits are conscripted by FS-Cache to maintain local caching * state. These bits are set on pages belonging to the netfs's inodes * when those inodes are being locally cached. @@ -314,7 +316,13 @@ PAGEFLAG_FALSE(HighMem)#endif #ifdef CONFIG_SWAP -PAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND) +static __always_inline int PageSwapCache(struct page *page) +{ +return PageSwapBacked (page) &&test_bit (PG_swapcache, &page->flags); + +} +SETPAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND) +CLEARPAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND)#else PAGEFLAG_FALSE(SwapCache)#endif @@ -701,12 +709,12 @@ static inline void ClearPageSlabPfmemalloc(struct page *page)* Flags checked when a page is freed. Pages being freed should not have * these flags set. It they are, there is a problem. */ -#define PAGE_FLAGS_CHECK_AT_FREE \ - (1UL << PG_lru | 1UL << PG_locked | \ - 1UL << PG_private | 1UL << PG_private_2 | \ - 1UL << PG_writeback | 1UL << PG_reserved | \ - 1UL << PG_slab | 1UL << PG_swapcache | 1UL << PG_active | \ - 1UL << PG_unevictable | __PG_MLOCKED) +#define PAGE_FLAGS_CHECK_AT_FREE \ + (1UL << PG_lru | 1UL << PG_locked | \ + 1UL << PG_private | 1UL << PG_private_2 | \ + 1UL << PG_writeback | 1UL << PG_reserved | \ + 1UL << PG_slab | 1UL << PG_active | \ + 1UL << PG_unevictable | __PG_MLOCKED)/* * Flags checked when a page is prepped for return by the page allocator. include/trace/events/mmflags.h +0
-1@@ -95,7 +95,6 @@ {1UL << PG_private_2, "private_2" }, \ {1UL << PG_writeback, "writeback" }, \ {1UL << PG_head, "head" }, \ - {1UL << PG_swapcache, "swapcache" }, \ {1UL << PG_mappedtodisk, "mappedtodisk" }, \ {1UL << PG_reclaim, "reclaim" }, \ {1UL << PG_swapbacked, "swapbacked" }, \Signature · 1 line
2.11.0
--
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>
Re: [PATCH 1/2] mm: Use owner_priv bit for PageSwapCache, valid when PageSwapBacked
Quoted 6 lines · On Thu, 22 Dec 2016 11:55:28 -0800 (PST) Hugh Dickins <[email protected]> wrote:
On Thu, 22 Dec 2016, Nicholas Piggin wrote:
I agree with every word of that changelog ;)
And I'll stamp this with
Acked-by Hugh Dickins <[email protected]>
Thanks Hugh.
Quoted 13 lines
The thing that Peter remembers I commented on (which 0day caught too), was to remove
PG_swapcachefromPAGE_FLAGS_CHECK_AT_FREE: you've done that now, so this is good. (Note in passing: wouldn't it be good to addPG_waiterstoPAGE_FLAGS_CHECK_AT_FREEin the 2/2?)Though I did yesterday notice a few more problematic uses of
PG_swapcache, which you'll probably need to refine to exclude other uses ofPG_owner_priv_1; though no great hurry for those, so not necessarily in this same patch. Do your own grep, but
fs/proc/page.cderives itsKPF_SWAPCACHEfromPG_swapcache, needs refining.
Quoted 7 lines
kernel/kexec_core.csaysVMCOREINFO_NUMBER(PG_swapcache):
I haven't looked into what that's about, it will probably just have to be commented as now including other uses of the same bit.
mm/memory-failure.chas an error_states[] table that involves testingPG_swapcacheas "sc", but looks as if it can be changed to factor in "swapbacked" too.
I've added the swapbacked check to mm/memory-failure.c, the others look like they're just dealing with bit number, so not much to do about it really. I also just made the migration case more explicit, seeing as the others are.
Hopefully that doesn't negate your ack because I'm adding that too.
Thanks,
Nick
--
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>
Re: [PATCH 1/2] mm: Use owner_priv bit for PageSwapCache, valid when PageSwapBacked
In reply to Nicholas PigginNick,
mind adding a changelog and a sign-off for these two patches?
I'd like to apply at least the first one asap, just to get as much verification of the page flag bits as possible.
Linus
Quoted 74 lines · Nicholas Piggin
--- include/linux/page-flags.h | 24 ++++++++++++++++-------- include/trace/events/mmflags.h | 1 - 2 files changed, 16 insertions(+), 9 deletions(-)include/linux/page-flags.h +16
-8@@ -87,7 +87,6 @@ enum pageflags { PG_private_2,/* If pagecache, has fs aux data */ PG_writeback,/* Page is under writeback */ PG_head,/* A head page */ - PG_swapcache,/* Swap page: swp_entry_t in private */ PG_mappedtodisk,/* Has blocks allocated on-disk */ PG_reclaim,/* To be reclaimed asap */ PG_swapbacked, /* Page is backed by RAM/swap */@@ -110,6 +109,9 @@ enum pageflags {/* Filesystems */ PG_checked = PG_owner_priv_1, +/* SwapBacked */ + PG_swapcache = PG_owner_priv_1,/* Swap page: swp_entry_t in private */ +/* Two page bits are conscripted by FS-Cache to maintain local caching * state. These bits are set on pages belonging to the netfs's inodes * when those inodes are being locally cached. @@ -314,7 +316,13 @@ PAGEFLAG_FALSE(HighMem)#endif #ifdef CONFIG_SWAP -PAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND) +static __always_inline int PageSwapCache(struct page *page) +{ +return PageSwapBacked (page) &&test_bit (PG_swapcache, &page->flags); + +} +SETPAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND) +CLEARPAGEFLAG(SwapCache, swapcache, PF_NO_COMPOUND)#else PAGEFLAG_FALSE(SwapCache)#endif @@ -701,12 +709,12 @@ static inline void ClearPageSlabPfmemalloc(struct page *page)* Flags checked when a page is freed. Pages being freed should not have * these flags set. It they are, there is a problem. */ -#define PAGE_FLAGS_CHECK_AT_FREE \ - (1UL << PG_lru | 1UL << PG_locked | \ - 1UL << PG_private | 1UL << PG_private_2 | \ - 1UL << PG_writeback | 1UL << PG_reserved | \ - 1UL << PG_slab | 1UL << PG_swapcache | 1UL << PG_active | \ - 1UL << PG_unevictable | __PG_MLOCKED) +#define PAGE_FLAGS_CHECK_AT_FREE \ + (1UL << PG_lru | 1UL << PG_locked | \ + 1UL << PG_private | 1UL << PG_private_2 | \ + 1UL << PG_writeback | 1UL << PG_reserved | \ + 1UL << PG_slab | 1UL << PG_active | \ + 1UL << PG_unevictable | __PG_MLOCKED)/* * Flags checked when a page is prepped for return by the page allocator. include/trace/events/mmflags.h +0
-2@@ -95,7 +95,6 @@ {1UL << PG_private_2, "private_2" }, \ {1UL << PG_writeback, "writeback" }, \ {1UL << PG_head, "head" }, \ - {1UL << PG_swapcache, "swapcache" }, \ {1UL << PG_mappedtodisk, "mappedtodisk" }, \ {1UL << PG_reclaim, "reclaim" }, \ {1UL << PG_swapbacked, "swapbacked" }, \ --
Quoted 2 lines
2.11.0
--
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/2 mm: add PageWaiters bit to indicate waitqueue should be checked
In reply to Nicholas Piggin--- include/linux/mm.h | 2 + include/linux/page-flags.h | 9 +++ include/linux/pagemap.h | 23 +++--- include/linux/writeback.h | 1 - include/trace/events/mmflags.h | 1 + init/main.c | 3 +- mm/filemap.c | 180 +++++++++++++++++++++++++++++++++-------- mm/internal.h | 2 + mm/swap.c | 2 + 9 files changed, 173 insertions(+), 50 deletions(-)
include/linux/mm.h +2 -0
@@ -1758,6 +1758,8 @@ static inline spinlock_t *pmd_lock(struct mm_struct *mm, pmd_t *pmd)return ptl; } +extern void __init pagecache_init (void ); +extern void free_area_init (unsigned long * zones_size);extern void free_area_init_node (int nid,unsigned long * zones_size,unsigned long zone_start_pfn,unsigned long *zholes_size);
include/linux/page-flags.h +9 -0
@@ -73,6 +73,7 @@*/ enum pageflags { PG_locked,/* Page is locked. Don't touch. */ + PG_waiters,/* Page has waiters, check its waitqueue */ PG_error, PG_referenced, PG_uptodate,
@@ -169,6 +170,9 @@ static __always_inline int PageCompound(struct page *page)* for compound page all operations related to the page flag applied to * head page. * +* PF_ONLY_HEAD: +* for compound page, callers only ever operate on the head page. +* * PF_NO_TAIL: * modifications of the page flag must be done on small or head pages, * checks can be done on tail pages too.
@@ -178,6 +182,9 @@ static __always_inline int PageCompound(struct page *page)*/ #define PF_ANY (page, enforce) page#define PF_HEAD (page, enforce) compound_head(page) +#define PF_ONLY_HEAD (page, enforce) ({ \ + VM_BUG_ON_PGFLAGS(PageTail(page), page); \ + page;})#define PF_NO_TAIL (page, enforce) ({ \ VM_BUG_ON_PGFLAGS(enforce && PageTail(page), page); \ compound_head(page);})
@@ -255,6 +262,7 @@ static inline int TestClearPage##uname(struct page *page) { return 0; } TESTSETFLAG_FALSE(uname) TESTCLEARFLAG_FALSE(uname) __PAGEFLAG(Locked, locked, PF_NO_TAIL) +PAGEFLAG(Waiters, waiters, PF_ONLY_HEAD) __CLEARPAGEFLAG(Waiters, waiters, PF_ONLY_HEAD) PAGEFLAG(Error, error, PF_NO_COMPOUND) TESTCLEARFLAG(Error, error, PF_NO_COMPOUND) PAGEFLAG(Referenced, referenced, PF_HEAD) TESTCLEARFLAG(Referenced, referenced, PF_HEAD)
@@ -743,6 +751,7 @@ static inline int page_has_private(struct page *page)#undef PF_ANY#undef PF_HEAD +#undef PF_ONLY_HEAD#undef PF_NO_TAIL#undef PF_NO_COMPOUND#endif /* !__GENERATING_BOUNDS_H */
include/linux/pagemap.h +11 -12
@@ -486,22 +486,14 @@ static inline int lock_page_or_retry(struct page *page, struct mm_struct *mm,* and for filesystems which need to wait on PG_private. */ extern void wait_on_page_bit (struct page *page,int bit_nr); -extern int wait_on_page_bit_killable (struct page *page,int bit_nr); -extern int wait_on_page_bit_killable_timeout (struct page *page, -int bit_nr,unsigned long timeout); - -static inline int wait_on_page_locked_killable (struct page *page) -{ -if (!PageLocked (page)) -return 0 ; -return wait_on_page_bit_killable (compound_head (page), PG_locked); -} +extern void wake_up_page_bit (struct page *page,int bit_nr); -extern wait_queue_head_t *page_waitqueue (struct page *page);static inline void wake_up_page (struct page *page,int bit) { -__wake_up_bit (page_waitqueue (page), &page->flags, bit); +if (!PageWaiters (page)) +return ; +wake_up_page_bit (page, bit); }/*
@@ -517,6 +509,13 @@ static inline void wait_on_page_locked(struct page *page)wait_on_page_bit (compound_head (page), PG_locked); } +static inline int wait_on_page_locked_killable (struct page *page) +{ +if (!PageLocked (page)) +return 0 ; +return wait_on_page_bit_killable (compound_head (page), PG_locked); +} +/* * Wait for a page to complete writeback */
include/linux/writeback.h +0 -1
@@ -375,7 +375,6 @@ void global_dirty_limits(unsigned long *pbackground, unsigned long *pdirty);unsigned long wb_calc_thresh (struct bdi_writeback *wb,unsigned long thresh);void wb_update_bandwidth (struct bdi_writeback *wb,unsigned long start_time); -void page_writeback_init (void );void balance_dirty_pages_ratelimited (struct address_space *mapping);bool wb_over_bg_thresh (struct bdi_writeback *wb);
include/trace/events/mmflags.h +1 -0
@@ -81,6 +81,7 @@#define __def_pageflag_names \ {1UL << PG_locked, "locked" }, \ + {1UL << PG_waiters, "waiters" }, \ {1UL << PG_error, "error" }, \ {1UL << PG_referenced, "referenced" }, \ {1UL << PG_uptodate, "uptodate" }, \
init/main.c +1 -2
@@ -647,9 +647,8 @@ asmlinkage __visible void __init start_kernel(void)security_init ();dbg_late_init ();vfs_caches_init (); +pagecache_init ();signals_init (); -/* rootfs populating might need page-writeback */ -page_writeback_init ();proc_root_init ();nsfs_init ();cpuset_init ();
mm/filemap.c +145 -35
219 lines not on this page · raw message
mm/internal.h +2 -0
@@ -36,6 +36,8 @@/* Do not use these with a slab allocator */ #define GFP_SLAB_BUG_MASK (__GFP_DMA32|__GFP_HIGHMEM|~__GFP_BITS_MASK) +void page_writeback_init (void ); +int do_swap_page (struct vm_fault *vmf); void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *start_vma,
mm/swap.c +2 -0
@@ -69,6 +69,7 @@ static void __page_cache_release(struct page *page)del_page_from_lru_list (page, lruvec,page_off_lru (page));spin_unlock_irqrestore (zone_lru_lock (zone), flags); } +__ClearPageWaiters (page);mem_cgroup_uncharge (page); }
@@ -784,6 +785,7 @@ void release_pages(struct page **pages, int nr, bool cold)/* Clear Active bit in case of parallel mark_page_accessed */ __ClearPageActive (page); +__ClearPageWaiters (page);list_add (&page->lru, &pages_to_free); }
Signature · 7 lines
2.11.0 -- 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 · Nicholas Piggin
Seeing as Mel said he would test it (and maybe Dave could as well), I will post my patches again. There was a couple of page flags bugs pointed out last time, which should be fixed.
So I already had Dave test the previous version, and the preliminary data was good.
I guess we should just apply it. This is not improved by me dropping it on the floor once more, and thinking that the problem is gone by knowing that we can solve it.
But your respun patches don't have commit messages and sign-offs.. Hint hint
Linus
--
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>