aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hildenbrand <[email protected]>2024-05-29 13:19:00 +0200
committerAndrew Morton <[email protected]>2024-07-03 19:30:16 -0700
commit8db00ad5646171880239b7f10e333278f63d8fcf (patch)
tree9dcaa50ccadda910b24b4806c1ee4b1df4d7aa2f
parent6d21dde7adc0a2deb9e0c6b06f42be3f88ca180d (diff)
mm: allow reuse of the lower 16 bit of the page type with an actual type
As long as the owner sets a page type first, we can allow reuse of the lower 16 bit: sufficient to store an offset into a 64 KiB page, which is the maximum base page size in *common* configurations (ignoring the 256 KiB variant). Restrict it to the head page. We'll use that for zsmalloc next, to set a proper type while still reusing that field to store information (offset into a base page) that cannot go elsewhere for now. Let's reserve the lower 16 bit for that purpose and for catching mapcount underflows, and let's reduce PAGE_TYPE_BASE to a single bit. Note that we will still have to overflow the mapcount quite a lot until we would actually indicate a valid page type. Start handing out the type bits from highest to lowest, to make it clearer how many bits for types we have left. Out of 15 bit we can use for types, we currently use 6. If we run out of bits before we have better typing (e.g., memdesc), we can always investigate storing a value instead [1]. [1] https://lore.kernel.org/all/[email protected]/ [[email protected]: fix PG_hugetlb typo, per David] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: David Hildenbrand <[email protected]> Tested-by: Sergey Senozhatsky <[email protected]> [zram/zsmalloc workloads] Cc: Hyeonggon Yoo <[email protected]> Cc: Matthew Wilcox (Oracle) <[email protected]> Cc: Mike Rapoport (IBM) <[email protected]> Cc: Minchan Kim <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
-rw-r--r--include/linux/mm_types.h5
-rw-r--r--include/linux/page-flags.h25
2 files changed, 20 insertions, 10 deletions
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 278eade2ad4c..ef09c4eef6d3 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -157,6 +157,11 @@ struct page {
*
* See page-flags.h for a list of page types which are currently
* stored here.
+ *
+ * Owners of typed folios may reuse the lower 16 bit of the
+ * head page page_type field after setting the page type,
+ * but must reset these 16 bit to -1 before clearing the
+ * page type.
*/
unsigned int page_type;
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index b041bc058fb1..d221a6a14764 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -941,16 +941,21 @@ PAGEFLAG_FALSE(HasHWPoisoned, has_hwpoisoned)
*/
enum pagetype {
- PG_buddy = 0x00000080,
- PG_offline = 0x00000100,
- PG_table = 0x00000200,
- PG_guard = 0x00000400,
- PG_hugetlb = 0x00000800,
- PG_slab = 0x00001000,
-
- PAGE_TYPE_BASE = 0xf0000000,
- /* Reserve 0x0000007f to catch underflows of _mapcount */
- PAGE_MAPCOUNT_RESERVE = -128,
+ PG_buddy = 0x40000000,
+ PG_offline = 0x20000000,
+ PG_table = 0x10000000,
+ PG_guard = 0x08000000,
+ PG_hugetlb = 0x04000000,
+ PG_slab = 0x02000000,
+
+ PAGE_TYPE_BASE = 0x80000000,
+
+ /*
+ * Reserve 0xffff0000 - 0xfffffffe to catch _mapcount underflows and
+ * allow owners that set a type to reuse the lower 16 bit for their own
+ * purposes.
+ */
+ PAGE_MAPCOUNT_RESERVE = ~0x0000ffff,
};
#define PageType(page, flag) \