mm: add PAGE_TYPE_OP folio functions
authorVishal Moola (Oracle) <vishal.moola@gmail.com>
Mon, 7 Aug 2023 23:04:43 +0000 (16:04 -0700)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 21 Aug 2023 20:37:51 +0000 (13:37 -0700)
Patch series "Split ptdesc from struct page", v9.

The MM subsystem is trying to shrink struct page.  This patchset
introduces a memory descriptor for page table tracking - struct ptdesc.

This patchset introduces ptdesc, splits ptdesc from struct page, and
converts many callers of page table constructor/destructors to use
ptdescs.

Ptdesc is a foundation to further standardize page tables, and eventually
allow for dynamic allocation of page tables independent of struct page.
However, the use of pages for page table tracking is quite deeply
ingrained and varied across archictectures, so there is still a lot of
work to be done before that can happen.

This patch (of 31):

No folio equivalents for page type operations have been defined, so define
them for later folio conversions.

Also changes the Page##uname macros to take in const struct page* since we
only read the memory here.

Link: https://lkml.kernel.org/r/20230807230513.102486-1-vishal.moola@gmail.com
Link: https://lkml.kernel.org/r/20230807230513.102486-2-vishal.moola@gmail.com
Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Acked-by: Mike Rapoport (IBM) <rppt@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Dinh Nguyen <dinguyen@kernel.org>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: Jonas Bonn <jonas@southpole.se>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Guo Ren <guoren@kernel.org>
Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Cc: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
include/linux/page-flags.h

index 92a2063..9218028 100644 (file)
@@ -908,6 +908,8 @@ static inline bool is_page_hwpoison(struct page *page)
 
 #define PageType(page, flag)                                           \
        ((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE)
+#define folio_test_type(folio, flag)                                   \
+       ((folio->page.page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE)
 
 static inline int page_type_has_type(unsigned int page_type)
 {
@@ -919,27 +921,41 @@ static inline int page_has_type(struct page *page)
        return page_type_has_type(page->page_type);
 }
 
-#define PAGE_TYPE_OPS(uname, lname)                                    \
-static __always_inline int Page##uname(struct page *page)              \
+#define PAGE_TYPE_OPS(uname, lname, fname)                             \
+static __always_inline int Page##uname(const struct page *page)                \
 {                                                                      \
        return PageType(page, PG_##lname);                              \
 }                                                                      \
+static __always_inline int folio_test_##fname(const struct folio *folio)\
+{                                                                      \
+       return folio_test_type(folio, PG_##lname);                      \
+}                                                                      \
 static __always_inline void __SetPage##uname(struct page *page)                \
 {                                                                      \
        VM_BUG_ON_PAGE(!PageType(page, 0), page);                       \
        page->page_type &= ~PG_##lname;                                 \
 }                                                                      \
+static __always_inline void __folio_set_##fname(struct folio *folio)   \
+{                                                                      \
+       VM_BUG_ON_FOLIO(!folio_test_type(folio, 0), folio);             \
+       folio->page.page_type &= ~PG_##lname;                           \
+}                                                                      \
 static __always_inline void __ClearPage##uname(struct page *page)      \
 {                                                                      \
        VM_BUG_ON_PAGE(!Page##uname(page), page);                       \
        page->page_type |= PG_##lname;                                  \
-}
+}                                                                      \
+static __always_inline void __folio_clear_##fname(struct folio *folio) \
+{                                                                      \
+       VM_BUG_ON_FOLIO(!folio_test_##fname(folio), folio);             \
+       folio->page.page_type |= PG_##lname;                            \
+}                                                                      \
 
 /*
  * PageBuddy() indicates that the page is free and in the buddy system
  * (see mm/page_alloc.c).
  */
-PAGE_TYPE_OPS(Buddy, buddy)
+PAGE_TYPE_OPS(Buddy, buddy, buddy)
 
 /*
  * PageOffline() indicates that the page is logically offline although the
@@ -963,7 +979,7 @@ PAGE_TYPE_OPS(Buddy, buddy)
  * pages should check PageOffline() and synchronize with such drivers using
  * page_offline_freeze()/page_offline_thaw().
  */
-PAGE_TYPE_OPS(Offline, offline)
+PAGE_TYPE_OPS(Offline, offline, offline)
 
 extern void page_offline_freeze(void);
 extern void page_offline_thaw(void);
@@ -973,12 +989,12 @@ extern void page_offline_end(void);
 /*
  * Marks pages in use as page tables.
  */
-PAGE_TYPE_OPS(Table, table)
+PAGE_TYPE_OPS(Table, table, pgtable)
 
 /*
  * Marks guardpages used with debug_pagealloc.
  */
-PAGE_TYPE_OPS(Guard, guard)
+PAGE_TYPE_OPS(Guard, guard, guard)
 
 extern bool is_free_buddy_page(struct page *page);