The patch titled Subject: page-flags: define PG_locked behavior on compound pages has been removed from the -mm tree. Its filename was page-flags-define-pg_locked-behavior-on-compound-pages.patch This patch was dropped because an updated version will be merged ------------------------------------------------------ From: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx> Subject: page-flags: define PG_locked behavior on compound pages lock_page() must operate on the whole compound page. It doesn't make much sense to lock part of compound page. Change code to use head page's PG_locked, if tail page is passed. This patch also gets rid of custom helper functions -- __set_page_locked() and __clear_page_locked(). They are replaced with helpers generated by __SETPAGEFLAG/__CLEARPAGEFLAG. Tail pages to these helper would trigger VM_BUG_ON(). SLUB uses PG_locked as a bit spin locked. IIUC, tail pages should never appear there. VM_BUG_ON() is added to make sure that this assumption is correct. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> Cc: Andrea Arcangeli <aarcange@xxxxxxxxxx> Cc: Hugh Dickins <hughd@xxxxxxxxxx> Cc: Dave Hansen <dave.hansen@xxxxxxxxx> Cc: Mel Gorman <mgorman@xxxxxxx> Cc: Rik van Riel <riel@xxxxxxxxxx> Cc: Vlastimil Babka <vbabka@xxxxxxx> Cc: Christoph Lameter <cl@xxxxxxxxx> Cc: Naoya Horiguchi <n-horiguchi@xxxxxxxxxxxxx> Cc: Steve Capper <steve.capper@xxxxxxxxxx> Cc: "Aneesh Kumar K.V" <aneesh.kumar@xxxxxxxxxxxxxxxxxx> Cc: Johannes Weiner <hannes@xxxxxxxxxxx> Cc: Michal Hocko <mhocko@xxxxxxx> Cc: Jerome Marchand <jmarchan@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- fs/cifs/file.c | 8 ++++---- include/linux/page-flags.h | 2 +- include/linux/pagemap.h | 25 ++++++++----------------- mm/filemap.c | 15 +++++++++------ mm/ksm.c | 2 +- mm/memory-failure.c | 2 +- mm/migrate.c | 2 +- mm/shmem.c | 4 ++-- mm/slub.c | 2 ++ mm/swap_state.c | 4 ++-- mm/vmscan.c | 2 +- 11 files changed, 32 insertions(+), 36 deletions(-) diff -puN fs/cifs/file.c~page-flags-define-pg_locked-behavior-on-compound-pages fs/cifs/file.c --- a/fs/cifs/file.c~page-flags-define-pg_locked-behavior-on-compound-pages +++ a/fs/cifs/file.c @@ -3391,13 +3391,13 @@ readpages_get_pages(struct address_space * should have access to this page, we're safe to simply set * PG_locked without checking it first. */ - __set_page_locked(page); + __SetPageLocked(page); rc = add_to_page_cache_locked(page, mapping, page->index, gfp); /* give up if we can't stick it in the cache */ if (rc) { - __clear_page_locked(page); + __ClearPageLocked(page); return rc; } @@ -3418,9 +3418,9 @@ readpages_get_pages(struct address_space if (*bytes + PAGE_CACHE_SIZE > rsize) break; - __set_page_locked(page); + __SetPageLocked(page); if (add_to_page_cache_locked(page, mapping, page->index, gfp)) { - __clear_page_locked(page); + __ClearPageLocked(page); break; } list_move_tail(&page->lru, tmplist); diff -puN include/linux/page-flags.h~page-flags-define-pg_locked-behavior-on-compound-pages include/linux/page-flags.h --- a/include/linux/page-flags.h~page-flags-define-pg_locked-behavior-on-compound-pages +++ a/include/linux/page-flags.h @@ -229,7 +229,7 @@ static inline int PageCompound(struct pa static inline int PageTail(struct page *page); static inline struct page *compound_head(struct page *page); -TESTPAGEFLAG(Locked, locked, ANY) +__PAGEFLAG(Locked, locked, NO_TAIL) PAGEFLAG(Error, error, ANY) TESTCLEARFLAG(Error, error, ANY) PAGEFLAG(Referenced, referenced, ANY) TESTCLEARFLAG(Referenced, referenced, ANY) __SETPAGEFLAG(Referenced, referenced, ANY) diff -puN include/linux/pagemap.h~page-flags-define-pg_locked-behavior-on-compound-pages include/linux/pagemap.h --- a/include/linux/pagemap.h~page-flags-define-pg_locked-behavior-on-compound-pages +++ a/include/linux/pagemap.h @@ -426,18 +426,9 @@ extern int __lock_page_or_retry(struct p unsigned int flags); extern void unlock_page(struct page *page); -static inline void __set_page_locked(struct page *page) -{ - __set_bit(PG_locked, &page->flags); -} - -static inline void __clear_page_locked(struct page *page) -{ - __clear_bit(PG_locked, &page->flags); -} - static inline int trylock_page(struct page *page) { + page = compound_head(page); return (likely(!test_and_set_bit_lock(PG_locked, &page->flags))); } @@ -490,9 +481,9 @@ extern int wait_on_page_bit_killable_tim static inline int wait_on_page_locked_killable(struct page *page) { - if (PageLocked(page)) - return wait_on_page_bit_killable(page, PG_locked); - return 0; + if (!PageLocked(page)) + return 0; + return wait_on_page_bit_killable(compound_head(page), PG_locked); } extern wait_queue_head_t *page_waitqueue(struct page *page); @@ -511,7 +502,7 @@ static inline void wake_up_page(struct p static inline void wait_on_page_locked(struct page *page) { if (PageLocked(page)) - wait_on_page_bit(page, PG_locked); + wait_on_page_bit(compound_head(page), PG_locked); } /* @@ -657,17 +648,17 @@ int replace_page_cache_page(struct page /* * Like add_to_page_cache_locked, but used to add newly allocated pages: - * the page is new, so we can just run __set_page_locked() against it. + * the page is new, so we can just run __SetPageLocked() against it. */ static inline int add_to_page_cache(struct page *page, struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask) { int error; - __set_page_locked(page); + __SetPageLocked(page); error = add_to_page_cache_locked(page, mapping, offset, gfp_mask); if (unlikely(error)) - __clear_page_locked(page); + __ClearPageLocked(page); return error; } diff -puN mm/filemap.c~page-flags-define-pg_locked-behavior-on-compound-pages mm/filemap.c --- a/mm/filemap.c~page-flags-define-pg_locked-behavior-on-compound-pages +++ a/mm/filemap.c @@ -682,11 +682,11 @@ int add_to_page_cache_lru(struct page *p void *shadow = NULL; int ret; - __set_page_locked(page); + __SetPageLocked(page); ret = __add_to_page_cache_locked(page, mapping, offset, gfp_mask, &shadow); if (unlikely(ret)) - __clear_page_locked(page); + __ClearPageLocked(page); else { /* * The page might have been evicted from cache only @@ -809,6 +809,7 @@ EXPORT_SYMBOL_GPL(add_page_wait_queue); */ void unlock_page(struct page *page) { + page = compound_head(page); VM_BUG_ON_PAGE(!PageLocked(page), page); clear_bit_unlock(PG_locked, &page->flags); smp_mb__after_atomic(); @@ -873,18 +874,20 @@ EXPORT_SYMBOL_GPL(page_endio); */ void __lock_page(struct page *page) { - DEFINE_WAIT_BIT(wait, &page->flags, PG_locked); + struct page *page_head = compound_head(page); + DEFINE_WAIT_BIT(wait, &page_head->flags, PG_locked); - __wait_on_bit_lock(page_waitqueue(page), &wait, bit_wait_io, + __wait_on_bit_lock(page_waitqueue(page_head), &wait, bit_wait_io, TASK_UNINTERRUPTIBLE); } EXPORT_SYMBOL(__lock_page); int __lock_page_killable(struct page *page) { - DEFINE_WAIT_BIT(wait, &page->flags, PG_locked); + struct page *page_head = compound_head(page); + DEFINE_WAIT_BIT(wait, &page_head->flags, PG_locked); - return __wait_on_bit_lock(page_waitqueue(page), &wait, + return __wait_on_bit_lock(page_waitqueue(page_head), &wait, bit_wait_io, TASK_KILLABLE); } EXPORT_SYMBOL_GPL(__lock_page_killable); diff -puN mm/ksm.c~page-flags-define-pg_locked-behavior-on-compound-pages mm/ksm.c --- a/mm/ksm.c~page-flags-define-pg_locked-behavior-on-compound-pages +++ a/mm/ksm.c @@ -1884,7 +1884,7 @@ struct page *ksm_might_need_to_copy(stru SetPageDirty(new_page); __SetPageUptodate(new_page); - __set_page_locked(new_page); + __SetPageLocked(new_page); } return new_page; diff -puN mm/memory-failure.c~page-flags-define-pg_locked-behavior-on-compound-pages mm/memory-failure.c --- a/mm/memory-failure.c~page-flags-define-pg_locked-behavior-on-compound-pages +++ a/mm/memory-failure.c @@ -1166,7 +1166,7 @@ int memory_failure(unsigned long pfn, in /* * We ignore non-LRU pages for good reasons. * - PG_locked is only well defined for LRU pages and a few others - * - to avoid races with __set_page_locked() + * - to avoid races with __SetPageLocked() * - to avoid races with __SetPageSlab*() (and more non-atomic ops) * The check (unnecessarily) ignores LRU pages being isolated and * walked by the page reclaim code, however that's not a big loss. diff -puN mm/migrate.c~page-flags-define-pg_locked-behavior-on-compound-pages mm/migrate.c --- a/mm/migrate.c~page-flags-define-pg_locked-behavior-on-compound-pages +++ a/mm/migrate.c @@ -1765,7 +1765,7 @@ int migrate_misplaced_transhuge_page(str flush_tlb_range(vma, mmun_start, mmun_end); /* Prepare a page as a migration target */ - __set_page_locked(new_page); + __SetPageLocked(new_page); SetPageSwapBacked(new_page); /* anon mapping, we can simply copy page->mapping to the new page: */ diff -puN mm/shmem.c~page-flags-define-pg_locked-behavior-on-compound-pages mm/shmem.c --- a/mm/shmem.c~page-flags-define-pg_locked-behavior-on-compound-pages +++ a/mm/shmem.c @@ -996,7 +996,7 @@ static int shmem_replace_page(struct pag copy_highpage(newpage, oldpage); flush_dcache_page(newpage); - __set_page_locked(newpage); + __SetPageLocked(newpage); SetPageUptodate(newpage); SetPageSwapBacked(newpage); set_page_private(newpage, swap_index); @@ -1188,7 +1188,7 @@ repeat: } __SetPageSwapBacked(page); - __set_page_locked(page); + __SetPageLocked(page); if (sgp == SGP_WRITE) __SetPageReferenced(page); diff -puN mm/slub.c~page-flags-define-pg_locked-behavior-on-compound-pages mm/slub.c --- a/mm/slub.c~page-flags-define-pg_locked-behavior-on-compound-pages +++ a/mm/slub.c @@ -338,11 +338,13 @@ static inline int oo_objects(struct kmem */ static __always_inline void slab_lock(struct page *page) { + VM_BUG_ON_PAGE(PageTail(page), page); bit_spin_lock(PG_locked, &page->flags); } static __always_inline void slab_unlock(struct page *page) { + VM_BUG_ON_PAGE(PageTail(page), page); __bit_spin_unlock(PG_locked, &page->flags); } diff -puN mm/swap_state.c~page-flags-define-pg_locked-behavior-on-compound-pages mm/swap_state.c --- a/mm/swap_state.c~page-flags-define-pg_locked-behavior-on-compound-pages +++ a/mm/swap_state.c @@ -353,7 +353,7 @@ struct page *__read_swap_cache_async(swp } /* May fail (-ENOMEM) if radix-tree node allocation failed. */ - __set_page_locked(new_page); + __SetPageLocked(new_page); SetPageSwapBacked(new_page); err = __add_to_swap_cache(new_page, entry); if (likely(!err)) { @@ -367,7 +367,7 @@ struct page *__read_swap_cache_async(swp } radix_tree_preload_end(); ClearPageSwapBacked(new_page); - __clear_page_locked(new_page); + __ClearPageLocked(new_page); /* * add_to_swap_cache() doesn't return -EEXIST, so we can safely * clear SWAP_HAS_CACHE flag. diff -puN mm/vmscan.c~page-flags-define-pg_locked-behavior-on-compound-pages mm/vmscan.c --- a/mm/vmscan.c~page-flags-define-pg_locked-behavior-on-compound-pages +++ a/mm/vmscan.c @@ -1184,7 +1184,7 @@ static unsigned long shrink_page_list(st * we obviously don't have to worry about waking up a process * waiting on the page lock, because there are no references. */ - __clear_page_locked(page); + __ClearPageLocked(page); free_it: nr_reclaimed++; _ Patches currently in -mm which might be from kirill.shutemov@xxxxxxxxxxxxxxx are rcu-force-alignment-on-struct-callback_head-rcu_head.patch mm-make-optimistic-check-for-swapin-readahead-fix.patch mm-make-swapin-readahead-to-improve-thp-collapse-rate-fix.patch mm-make-swapin-readahead-to-improve-thp-collapse-rate-fix-2.patch mm-make-swapin-readahead-to-improve-thp-collapse-rate-fix-3.patch mm-drop-page-slab_page.patch slab-slub-use-page-rcu_head-instead-of-page-lru-plus-cast.patch zsmalloc-use-page-private-instead-of-page-first_page.patch mm-pack-compound_dtor-and-compound_order-into-one-word-in-struct-page.patch mm-make-compound_head-robust.patch mm-use-unsigned-int-for-page-order.patch mm-use-unsigned-int-for-compound_dtor-compound_order-on-64bit.patch page-flags-define-behavior-of-fs-io-related-flags-on-compound-pages.patch page-flags-define-behavior-of-lru-related-flags-on-compound-pages.patch page-flags-define-behavior-slb-related-flags-on-compound-pages.patch page-flags-define-behavior-of-xen-related-flags-on-compound-pages.patch page-flags-define-pg_reserved-behavior-on-compound-pages.patch page-flags-define-pg_swapbacked-behavior-on-compound-pages.patch page-flags-define-pg_swapcache-behavior-on-compound-pages.patch page-flags-define-pg_mlocked-behavior-on-compound-pages.patch page-flags-define-pg_uncached-behavior-on-compound-pages.patch page-flags-define-pg_uptodate-behavior-on-compound-pages.patch page-flags-look-on-head-page-if-the-flag-is-encoded-in-page-mapping.patch mm-sanitize-page-mapping-for-tail-pages.patch mm-support-madvisemadv_free-fix-3.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html