All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v3 0/4] move PG_slab flag to page_type
@ 2022-12-18 10:18 Hyeonggon Yoo
  2022-12-18 10:18 ` [RFC v3 1/4] mm/hwpoison: remove MF_MSG_SLAB from action_page_types Hyeonggon Yoo
                   ` (3 more replies)
  0 siblings, 4 replies; 25+ messages in thread
From: Hyeonggon Yoo @ 2022-12-18 10:18 UTC (permalink / raw)
  To: Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Vlastimil Babka, Roman Gushchin
  Cc: Hyeonggon Yoo,
	HORIGUCHI NAOYA(堀口 直也),
	Joe Perches, Petr Mladek, Andy Shevchenko, Matthew WilCox,
	David Hildenbrand, linux-mm, linux-kernel

RFC v2:
https://lore.kernel.org/linux-mm/20221106140355.294845-1-42.hyeyoo@gmail.com/

This patch series moves PG_slab page flag to page_type,
freeing one bit in page->flags and introduces %pGt format
that prints human-readable page_type like %pGp for printing page flags.

See changelog of patch 2 for more implementation details.

Thanks everyone that gave valuable comments.

v2 -> v3:
- dropped show_page_types() in a thought that it is not interesting
  to track refcount of non-usermapped pages.
- added patch 1 that cleans up MF_MSG_SLAB in hwpoison
- split implementation and application of %pGt to separate patches.
- instead of printing "no page_type for ..." in %pGt, just print 
  '0x<value>()' for a page that does not use page_type field.

Hyeonggon Yoo (4):
  mm/hwpoison: remove MF_MSG_SLAB from action_page_types
  mm: move PG_slab flag to page_type
  mm, printk: introduce new format %pGt for page_type
  mm/debug: use %pGt to print page_type in dump_page()

 Documentation/core-api/printk-formats.rst |  3 +-
 fs/proc/page.c                            | 13 ++--
 include/linux/mm_types.h                  | 11 ++--
 include/linux/page-flags.h                | 77 ++++++++++++++++-------
 include/trace/events/mmflags.h            |  8 ++-
 kernel/crash_core.c                       |  3 +-
 lib/test_printf.c                         | 26 ++++++++
 lib/vsprintf.c                            | 21 +++++++
 mm/debug.c                                |  7 +++
 mm/internal.h                             |  1 +
 mm/memory-failure.c                       | 10 ---
 mm/slab.c                                 | 44 ++++++++-----
 mm/slab.h                                 |  3 +-
 13 files changed, 162 insertions(+), 65 deletions(-)

-- 
2.32.0



^ permalink raw reply	[flat|nested] 25+ messages in thread

* [RFC v3 1/4] mm/hwpoison: remove MF_MSG_SLAB from action_page_types
  2022-12-18 10:18 [RFC v3 0/4] move PG_slab flag to page_type Hyeonggon Yoo
@ 2022-12-18 10:18 ` Hyeonggon Yoo
  2022-12-20 23:53   ` HORIGUCHI NAOYA(堀口 直也)
  2022-12-18 10:18 ` [RFC v3 2/4] mm: move PG_slab flag to page_type Hyeonggon Yoo
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 25+ messages in thread
From: Hyeonggon Yoo @ 2022-12-18 10:18 UTC (permalink / raw)
  To: Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Vlastimil Babka, Roman Gushchin
  Cc: Hyeonggon Yoo,
	HORIGUCHI NAOYA(堀口 直也),
	Joe Perches, Petr Mladek, Andy Shevchenko, Matthew WilCox,
	David Hildenbrand, linux-mm, linux-kernel

As suggested by Naoya [1], identify_page_state() is never
called when handling memory error on a slab page.

Clean this up before moving PG_slab flag to page_type in later patch.

[1] https://lore.kernel.org/linux-mm/Y2s+dnBsHAJu19ob@hyeyoo/#r

Suggested-by: Naoya Horiguchi <naoya.horiguchi@nec.com>
Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
---
 mm/memory-failure.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index c77a9e37e27e..74ad1db989e3 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -783,7 +783,6 @@ static const char *action_name[] = {
 static const char * const action_page_types[] = {
 	[MF_MSG_KERNEL]			= "reserved kernel page",
 	[MF_MSG_KERNEL_HIGH_ORDER]	= "high-order kernel page",
-	[MF_MSG_SLAB]			= "kernel slab page",
 	[MF_MSG_DIFFERENT_COMPOUND]	= "different compound page after locking",
 	[MF_MSG_HUGE]			= "huge page",
 	[MF_MSG_FREE_HUGE]		= "free huge page",
@@ -1146,7 +1145,6 @@ static int me_huge_page(struct page_state *ps, struct page *p)
 #define mlock		(1UL << PG_mlocked)
 #define lru		(1UL << PG_lru)
 #define head		(1UL << PG_head)
-#define slab		(1UL << PG_slab)
 #define reserved	(1UL << PG_reserved)
 
 static struct page_state error_states[] = {
@@ -1156,13 +1154,6 @@ static struct page_state error_states[] = {
 	 * PG_buddy pages only make a small fraction of all free pages.
 	 */
 
-	/*
-	 * Could in theory check if slab page is free or if we can drop
-	 * currently unused objects without touching them. But just
-	 * treat it as standard kernel for now.
-	 */
-	{ slab,		slab,		MF_MSG_SLAB,	me_kernel },
-
 	{ head,		head,		MF_MSG_HUGE,		me_huge_page },
 
 	{ sc|dirty,	sc|dirty,	MF_MSG_DIRTY_SWAPCACHE,	me_swapcache_dirty },
@@ -1189,7 +1180,6 @@ static struct page_state error_states[] = {
 #undef mlock
 #undef lru
 #undef head
-#undef slab
 #undef reserved
 
 /*
-- 
2.32.0



^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [RFC v3 2/4] mm: move PG_slab flag to page_type
  2022-12-18 10:18 [RFC v3 0/4] move PG_slab flag to page_type Hyeonggon Yoo
  2022-12-18 10:18 ` [RFC v3 1/4] mm/hwpoison: remove MF_MSG_SLAB from action_page_types Hyeonggon Yoo
@ 2022-12-18 10:18 ` Hyeonggon Yoo
  2023-01-12 16:27   ` Vlastimil Babka
  2022-12-18 10:19 ` [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type Hyeonggon Yoo
  2022-12-18 10:19 ` [RFC v3 4/4] mm/debug: use %pGt to print page_type in dump_page() Hyeonggon Yoo
  3 siblings, 1 reply; 25+ messages in thread
From: Hyeonggon Yoo @ 2022-12-18 10:18 UTC (permalink / raw)
  To: Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Vlastimil Babka, Roman Gushchin
  Cc: Hyeonggon Yoo,
	HORIGUCHI NAOYA(堀口 直也),
	Joe Perches, Petr Mladek, Andy Shevchenko, Matthew WilCox,
	David Hildenbrand, linux-mm, linux-kernel

For now, only SLAB uses _mapcount field as a number of active objects in
a slab, and other slab allocators do not. As 16 bits are enough for that,
use remaining 16 bits of _mapcount as page_type even when SLAB is used.
And then move PG_slab flag to page_type.

As suggested by Matthew, store number of active objects in negative
form and use helper when accessing or modifying it.

page_type is always placed in upper half of _mapcount to avoid
confusing normal _mapcount as page_type. As underflow (actually I mean,
yeah, overflow) is not a concern anymore, use more lower bits.

Add more folio helpers for PAGE_TYPE_OPS() not to break existing
slab implementations. To preserve current behavior apply page policy
in PAGE_TYPE_OPS() and use PF_NO_TAIL for slab pages and PF_ANY for others.

Remove PG_slab check from PAGE_FLAGS_CHECK_AT_FREE. buddy will still
check if _mapcount is properly set at free.

Note that with this change, page_mapped() and folio_mapped() always return
false for a slab page.

Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
---
 fs/proc/page.c                 | 13 ++----
 include/linux/mm_types.h       | 11 +++--
 include/linux/page-flags.h     | 77 ++++++++++++++++++++++++----------
 include/trace/events/mmflags.h |  1 -
 kernel/crash_core.c            |  3 +-
 mm/slab.c                      | 44 ++++++++++++-------
 mm/slab.h                      |  3 +-
 7 files changed, 98 insertions(+), 54 deletions(-)

diff --git a/fs/proc/page.c b/fs/proc/page.c
index 6249c347809a..e7524f21cefe 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -67,7 +67,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
 		 */
 		ppage = pfn_to_online_page(pfn);
 
-		if (!ppage || PageSlab(ppage) || page_has_type(ppage))
+		if (!ppage || page_has_type(ppage))
 			pcount = 0;
 		else
 			pcount = page_mapcount(ppage);
@@ -124,11 +124,8 @@ u64 stable_page_flags(struct page *page)
 
 	/*
 	 * pseudo flags for the well known (anonymous) memory mapped pages
-	 *
-	 * Note that page->_mapcount is overloaded in SLOB/SLUB/SLQB, so the
-	 * simple test in page_mapped() is not enough.
 	 */
-	if (!PageSlab(page) && page_mapped(page))
+	if (page_mapped(page))
 		u |= 1 << KPF_MMAP;
 	if (PageAnon(page))
 		u |= 1 << KPF_ANON;
@@ -178,16 +175,14 @@ u64 stable_page_flags(struct page *page)
 		u |= 1 << KPF_OFFLINE;
 	if (PageTable(page))
 		u |= 1 << KPF_PGTABLE;
+	if (PageSlab(page))
+		u |= 1 << KPF_SLAB;
 
 	if (page_is_idle(page))
 		u |= 1 << KPF_IDLE;
 
 	u |= kpf_copy_bit(k, KPF_LOCKED,	PG_locked);
 
-	u |= kpf_copy_bit(k, KPF_SLAB,		PG_slab);
-	if (PageTail(page) && PageSlab(compound_head(page)))
-		u |= 1 << KPF_SLAB;
-
 	u |= kpf_copy_bit(k, KPF_ERROR,		PG_error);
 	u |= kpf_copy_bit(k, KPF_DIRTY,		PG_dirty);
 	u |= kpf_copy_bit(k, KPF_UPTODATE,	PG_uptodate);
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 3b8475007734..6b04ae65241d 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -207,10 +207,13 @@ struct page {
 		atomic_t _mapcount;
 
 		/*
-		 * If the page is neither PageSlab nor mappable to userspace,
-		 * the value stored here may help determine what this page
-		 * is used for.  See page-flags.h for a list of page types
-		 * which are currently stored here.
+		 * If the page is not mappable to userspace, the value
+		 * stored here may help determine what this page is used for.
+		 * See page-flags.h for a list of page types which are currently
+		 * stored here.
+		 *
+		 * Note that only upper half is used for page types and lower
+		 * half is reserved for SLAB.
 		 */
 		unsigned int page_type;
 	};
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 69e93a0c1277..07063d60efe3 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -107,7 +107,6 @@ enum pageflags {
 	PG_workingset,
 	PG_waiters,		/* Page has waiters, check its waitqueue. Must be bit #7 and in the same byte as "PG_locked" */
 	PG_error,
-	PG_slab,
 	PG_owner_priv_1,	/* Owner use. If pagecache, fs may use*/
 	PG_arch_1,
 	PG_reserved,
@@ -482,7 +481,6 @@ PAGEFLAG(Active, active, PF_HEAD) __CLEARPAGEFLAG(Active, active, PF_HEAD)
 	TESTCLEARFLAG(Active, active, PF_HEAD)
 PAGEFLAG(Workingset, workingset, PF_HEAD)
 	TESTCLEARFLAG(Workingset, workingset, PF_HEAD)
-__PAGEFLAG(Slab, slab, PF_NO_TAIL)
 __PAGEFLAG(SlobFree, slob_free, PF_NO_TAIL)
 PAGEFLAG(Checked, checked, PF_NO_COMPOUND)	   /* Used by some filesystems */
 
@@ -906,42 +904,72 @@ static inline bool is_page_hwpoison(struct page *page)
 }
 
 /*
- * For pages that are never mapped to userspace (and aren't PageSlab),
- * page_type may be used.  Because it is initialised to -1, we invert the
- * sense of the bit, so __SetPageFoo *clears* the bit used for PageFoo, and
- * __ClearPageFoo *sets* the bit used for PageFoo.  We reserve a few high and
- * low bits so that an underflow or overflow of page_mapcount() won't be
- * mistaken for a page type value.
+ * For pages that are never mapped to userspace, page_type may be used.
+ * Because it is initialised to -1, we invert the sense of the bit,
+ * so __SetPageFoo *clears* the bit used for PageFoo, and __ClearPageFoo
+ * *sets* the bit used for PageFoo.  We reserve a few high and low bits
+ * so that an underflow or overflow of page_mapcount() won't be mistaken
+ * for a page type value.
  */
 
 #define PAGE_TYPE_BASE	0xf0000000
-/* Reserve		0x0000007f to catch underflows of page_mapcount */
-#define PAGE_MAPCOUNT_RESERVE	-128
-#define PG_buddy	0x00000080
-#define PG_offline	0x00000100
-#define PG_table	0x00000200
-#define PG_guard	0x00000400
+#define PG_buddy	0x00010000
+#define PG_offline	0x00020000
+#define PG_table	0x00040000
+#define PG_guard	0x00080000
+#define PG_slab		0x00100000
 
 #define PageType(page, flag)						\
 	((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE)
 
-static inline int page_has_type(struct page *page)
+#define PAGE_TYPE_MASK	0xffff0000
+
+static inline bool page_type_has_type(unsigned int page_type)
 {
-	return (int)page->page_type < PAGE_MAPCOUNT_RESERVE;
+	return ((int)page_type < (int)PAGE_TYPE_MASK);
 }
 
-#define PAGE_TYPE_OPS(uname, lname)					\
+static inline bool page_has_type(struct page *page)
+{
+	return page_type_has_type(page->page_type);
+}
+
+
+#define PAGE_TYPE_OPS(uname, lname, policy)				\
 static __always_inline int Page##uname(struct page *page)		\
 {									\
+	page = policy(page, 0);						\
+	return PageType(page, PG_##lname);				\
+}									\
+static __always_inline int folio_test_##lname(struct folio *folio)	\
+{									\
+	struct page *page = &folio->page;				\
+									\
 	return PageType(page, PG_##lname);				\
 }									\
 static __always_inline void __SetPage##uname(struct page *page)		\
 {									\
+	page = policy(page, 1);						\
+	VM_BUG_ON_PAGE(!PageType(page, 0), page);			\
+	page->page_type &= ~PG_##lname;					\
+}									\
+static __always_inline void __folio_set_##lname(struct folio *folio)	\
+{									\
+	struct page *page = &folio->page;				\
+									\
 	VM_BUG_ON_PAGE(!PageType(page, 0), page);			\
 	page->page_type &= ~PG_##lname;					\
 }									\
 static __always_inline void __ClearPage##uname(struct page *page)	\
 {									\
+	page = policy(page, 1);						\
+	VM_BUG_ON_PAGE(!Page##uname(page), page);			\
+	page->page_type |= PG_##lname;					\
+}									\
+static __always_inline void __folio_clear_##lname(struct folio *folio)	\
+{									\
+	struct page *page = &folio->page;				\
+									\
 	VM_BUG_ON_PAGE(!Page##uname(page), page);			\
 	page->page_type |= PG_##lname;					\
 }
@@ -950,7 +978,7 @@ static __always_inline void __ClearPage##uname(struct page *page)	\
  * 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, PF_ANY)
 
 /*
  * PageOffline() indicates that the page is logically offline although the
@@ -974,7 +1002,10 @@ 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, PF_ANY)
+
+/* PageSlab() indicates that the page is used by slab subsystem. */
+PAGE_TYPE_OPS(Slab, slab, PF_NO_TAIL)
 
 extern void page_offline_freeze(void);
 extern void page_offline_thaw(void);
@@ -984,12 +1015,12 @@ extern void page_offline_end(void);
 /*
  * Marks pages in use as page tables.
  */
-PAGE_TYPE_OPS(Table, table)
+PAGE_TYPE_OPS(Table, table, PF_ANY)
 
 /*
  * Marks guardpages used with debug_pagealloc.
  */
-PAGE_TYPE_OPS(Guard, guard)
+PAGE_TYPE_OPS(Guard, guard, PF_ANY)
 
 extern bool is_free_buddy_page(struct page *page);
 
@@ -1037,8 +1068,8 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page)
 	(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 | LRU_GEN_MASK)
+	 1UL << PG_active 	| 1UL << PG_unevictable |	\
+	 __PG_MLOCKED | LRU_GEN_MASK)
 
 /*
  * Flags checked when a page is prepped for return by the page allocator.
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index 412b5a46374c..8301912f8c25 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -113,7 +113,6 @@
 	{1UL << PG_lru,			"lru"		},		\
 	{1UL << PG_active,		"active"	},		\
 	{1UL << PG_workingset,		"workingset"	},		\
-	{1UL << PG_slab,		"slab"		},		\
 	{1UL << PG_owner_priv_1,	"owner_priv_1"	},		\
 	{1UL << PG_arch_1,		"arch_1"	},		\
 	{1UL << PG_reserved,		"reserved"	},		\
diff --git a/kernel/crash_core.c b/kernel/crash_core.c
index 87ef6096823f..1ea8198c26e1 100644
--- a/kernel/crash_core.c
+++ b/kernel/crash_core.c
@@ -482,13 +482,14 @@ static int __init crash_save_vmcoreinfo_init(void)
 	VMCOREINFO_NUMBER(PG_private);
 	VMCOREINFO_NUMBER(PG_swapcache);
 	VMCOREINFO_NUMBER(PG_swapbacked);
-	VMCOREINFO_NUMBER(PG_slab);
 #ifdef CONFIG_MEMORY_FAILURE
 	VMCOREINFO_NUMBER(PG_hwpoison);
 #endif
 	VMCOREINFO_NUMBER(PG_head_mask);
 #define PAGE_BUDDY_MAPCOUNT_VALUE	(~PG_buddy)
 	VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
+#define PAGE_SLAB_MAPCOUNT_VALUE	(~PG_slab)
+	VMCOREINFO_NUMBER(PAGE_SLAB_MAPCOUNT_VALUE);
 #ifdef CONFIG_HUGETLB_PAGE
 	VMCOREINFO_NUMBER(HUGETLB_PAGE_DTOR);
 #define PAGE_OFFLINE_MAPCOUNT_VALUE	(~PG_offline)
diff --git a/mm/slab.c b/mm/slab.c
index 7a269db050ee..eee46f71c4b8 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -2269,6 +2269,21 @@ void __kmem_cache_release(struct kmem_cache *cachep)
 	}
 }
 
+static inline unsigned int slab_get_active(struct slab *slab)
+{
+	return ~(slab->page_type | PG_slab);
+}
+
+static inline void slab_inc_active(struct slab *slab)
+{
+	slab->page_type--;
+}
+
+static inline void slab_dec_active(struct slab *slab)
+{
+	slab->page_type++;
+}
+
 /*
  * Get the memory for a slab management obj.
  *
@@ -2291,7 +2306,6 @@ static void *alloc_slabmgmt(struct kmem_cache *cachep,
 	void *addr = slab_address(slab);
 
 	slab->s_mem = addr + colour_off;
-	slab->active = 0;
 
 	if (OBJFREELIST_SLAB(cachep))
 		freelist = NULL;
@@ -2510,8 +2524,8 @@ static void *slab_get_obj(struct kmem_cache *cachep, struct slab *slab)
 {
 	void *objp;
 
-	objp = index_to_obj(cachep, slab, get_free_obj(slab, slab->active));
-	slab->active++;
+	objp = index_to_obj(cachep, slab, get_free_obj(slab, slab_get_active(slab)));
+	slab_inc_active(slab);
 
 	return objp;
 }
@@ -2524,7 +2538,7 @@ static void slab_put_obj(struct kmem_cache *cachep,
 	unsigned int i;
 
 	/* Verify double free bug */
-	for (i = slab->active; i < cachep->num; i++) {
+	for (i = slab_get_active(slab); i < cachep->num; i++) {
 		if (get_free_obj(slab, i) == objnr) {
 			pr_err("slab: double free detected in cache '%s', objp %px\n",
 			       cachep->name, objp);
@@ -2532,11 +2546,11 @@ static void slab_put_obj(struct kmem_cache *cachep,
 		}
 	}
 #endif
-	slab->active--;
+	slab_dec_active(slab);
 	if (!slab->freelist)
 		slab->freelist = objp + obj_offset(cachep);
 
-	set_free_obj(slab, slab->active, objnr);
+	set_free_obj(slab, slab_get_active(slab), objnr);
 }
 
 /*
@@ -2635,14 +2649,14 @@ static void cache_grow_end(struct kmem_cache *cachep, struct slab *slab)
 
 	raw_spin_lock(&n->list_lock);
 	n->total_slabs++;
-	if (!slab->active) {
+	if (!slab_get_active(slab)) {
 		list_add_tail(&slab->slab_list, &n->slabs_free);
 		n->free_slabs++;
 	} else
 		fixup_slab_list(cachep, n, slab, &list);
 
 	STATS_INC_GROWN(cachep);
-	n->free_objects += cachep->num - slab->active;
+	n->free_objects += cachep->num - slab_get_active(slab);
 	raw_spin_unlock(&n->list_lock);
 
 	fixup_objfreelist_debug(cachep, &list);
@@ -2744,7 +2758,7 @@ static inline void fixup_slab_list(struct kmem_cache *cachep,
 {
 	/* move slabp to correct slabp list: */
 	list_del(&slab->slab_list);
-	if (slab->active == cachep->num) {
+	if (slab_get_active(slab) == cachep->num) {
 		list_add(&slab->slab_list, &n->slabs_full);
 		if (OBJFREELIST_SLAB(cachep)) {
 #if DEBUG
@@ -2783,7 +2797,7 @@ static noinline struct slab *get_valid_first_slab(struct kmem_cache_node *n,
 
 	/* Move pfmemalloc slab to the end of list to speed up next search */
 	list_del(&slab->slab_list);
-	if (!slab->active) {
+	if (!slab_get_active(slab)) {
 		list_add_tail(&slab->slab_list, &n->slabs_free);
 		n->free_slabs++;
 	} else
@@ -2865,9 +2879,9 @@ static __always_inline int alloc_block(struct kmem_cache *cachep,
 	 * There must be at least one object available for
 	 * allocation.
 	 */
-	BUG_ON(slab->active >= cachep->num);
+	BUG_ON(slab_get_active(slab) >= cachep->num);
 
-	while (slab->active < cachep->num && batchcount--) {
+	while (slab_get_active(slab) < cachep->num && batchcount--) {
 		STATS_INC_ALLOCED(cachep);
 		STATS_INC_ACTIVE(cachep);
 		STATS_SET_HIGH(cachep);
@@ -3162,7 +3176,7 @@ static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags,
 	STATS_INC_ACTIVE(cachep);
 	STATS_SET_HIGH(cachep);
 
-	BUG_ON(slab->active == cachep->num);
+	BUG_ON(slab_get_active(slab) == cachep->num);
 
 	obj = slab_get_obj(cachep, slab);
 	n->free_objects--;
@@ -3297,7 +3311,7 @@ static void free_block(struct kmem_cache *cachep, void **objpp,
 		STATS_DEC_ACTIVE(cachep);
 
 		/* fixup slab chains */
-		if (slab->active == 0) {
+		if (slab_get_active(slab) == 0) {
 			list_add(&slab->slab_list, &n->slabs_free);
 			n->free_slabs++;
 		} else {
@@ -3352,7 +3366,7 @@ static void cache_flusharray(struct kmem_cache *cachep, struct array_cache *ac)
 		struct slab *slab;
 
 		list_for_each_entry(slab, &n->slabs_free, slab_list) {
-			BUG_ON(slab->active);
+			BUG_ON(slab_get_active(slab));
 
 			i++;
 		}
diff --git a/mm/slab.h b/mm/slab.h
index 7cc432969945..c6ffe6799436 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -20,7 +20,8 @@ struct slab {
 		};
 		struct rcu_head rcu_head;
 	};
-	unsigned int active;
+	/* lower half of page_type is used as active objects counter */
+	unsigned int page_type;
 
 #elif defined(CONFIG_SLUB)
 
-- 
2.32.0



^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type
  2022-12-18 10:18 [RFC v3 0/4] move PG_slab flag to page_type Hyeonggon Yoo
  2022-12-18 10:18 ` [RFC v3 1/4] mm/hwpoison: remove MF_MSG_SLAB from action_page_types Hyeonggon Yoo
  2022-12-18 10:18 ` [RFC v3 2/4] mm: move PG_slab flag to page_type Hyeonggon Yoo
@ 2022-12-18 10:19 ` Hyeonggon Yoo
  2022-12-18 19:32   ` kernel test robot
                     ` (2 more replies)
  2022-12-18 10:19 ` [RFC v3 4/4] mm/debug: use %pGt to print page_type in dump_page() Hyeonggon Yoo
  3 siblings, 3 replies; 25+ messages in thread
From: Hyeonggon Yoo @ 2022-12-18 10:19 UTC (permalink / raw)
  To: Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Vlastimil Babka, Roman Gushchin
  Cc: Hyeonggon Yoo,
	HORIGUCHI NAOYA(堀口 直也),
	Joe Perches, Petr Mladek, Andy Shevchenko, Matthew WilCox,
	David Hildenbrand, linux-mm, linux-kernel

%pGp format is used to print 'flags' field of struct page.
As some page flags (e.g. PG_buddy, see page-flags.h for more details)
are set in page_type field, introduce %pGt format which provides
human readable output of page_type.

Note that the sense of bits are different in page_type. if page_type is
0xffffffff, no flags are set. if PG_slab (0x00100000) flag is set,
page_type is 0xffefffff. Clearing a bit means we set the bit.

Bits in page_type are inverted when printing page type names.

Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
---
 Documentation/core-api/printk-formats.rst |  3 ++-
 include/trace/events/mmflags.h            |  7 ++++++
 lib/test_printf.c                         | 26 +++++++++++++++++++++++
 lib/vsprintf.c                            | 21 ++++++++++++++++++
 mm/debug.c                                |  5 +++++
 mm/internal.h                             |  1 +
 6 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst
index dbe1aacc79d0..582e965508eb 100644
--- a/Documentation/core-api/printk-formats.rst
+++ b/Documentation/core-api/printk-formats.rst
@@ -575,12 +575,13 @@ The field width is passed by value, the bitmap is passed by reference.
 Helper macros cpumask_pr_args() and nodemask_pr_args() are available to ease
 printing cpumask and nodemask.
 
-Flags bitfields such as page flags, gfp_flags
+Flags bitfields such as page flags, page_type, gfp_flags
 ---------------------------------------------
 
 ::
 
 	%pGp	0x17ffffc0002036(referenced|uptodate|lru|active|private|node=0|zone=2|lastcpupid=0x1fffff)
+	%pGt	0xffefffff(slab)
 	%pGg	GFP_USER|GFP_DMA32|GFP_NOWARN
 	%pGv	read|exec|mayread|maywrite|mayexec|denywrite
 
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index 8301912f8c25..57f52d00e761 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -138,6 +138,13 @@ IF_HAVE_PG_SKIP_KASAN_POISON(PG_skip_kasan_poison, "skip_kasan_poison")
 	__def_pageflag_names						\
 	) : "none"
 
+#define __def_pagetype_names						\
+	{PG_slab,			"slab"		},		\
+	{PG_offline,			"offline"	},		\
+	{PG_guard,			"guard"		},		\
+	{PG_table,			"table"		},		\
+	{PG_buddy,			"buddy"		}
+
 #if defined(CONFIG_X86)
 #define __VM_ARCH_SPECIFIC_1 {VM_PAT,     "pat"           }
 #elif defined(CONFIG_PPC)
diff --git a/lib/test_printf.c b/lib/test_printf.c
index d34dc636b81c..e0d0770d5eec 100644
--- a/lib/test_printf.c
+++ b/lib/test_printf.c
@@ -642,12 +642,26 @@ page_flags_test(int section, int node, int zone, int last_cpupid,
 	test(cmp_buf, "%pGp", &flags);
 }
 
+static void __init page_type_test(unsigned int page_type, const char *name,
+				  char *cmp_buf)
+{
+	unsigned long size;
+
+	size = scnprintf(cmp_buf, BUF_SIZE, "%#x(", page_type);
+	if (page_type_has_type(page_type))
+		size += scnprintf(cmp_buf + size, BUF_SIZE - size, "%s", name);
+
+	snprintf(cmp_buf + size, BUF_SIZE - size, ")");
+	test(cmp_buf, "%pGt", &page_type);
+}
+
 static void __init
 flags(void)
 {
 	unsigned long flags;
 	char *cmp_buffer;
 	gfp_t gfp;
+	unsigned int page_type;
 
 	cmp_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
 	if (!cmp_buffer)
@@ -687,6 +701,18 @@ flags(void)
 	gfp |= __GFP_ATOMIC;
 	test(cmp_buffer, "%pGg", &gfp);
 
+	page_type = ~0;
+	page_type_test(page_type, "", cmp_buffer);
+
+	page_type = 10;
+	page_type_test(page_type, "", cmp_buffer);
+
+	page_type = ~PG_slab;
+	page_type_test(page_type, "slab", cmp_buffer);
+
+	page_type = ~(PG_slab | PG_table | PG_buddy);
+	page_type_test(page_type, "slab|table|buddy", cmp_buffer);
+
 	kfree(cmp_buffer);
 }
 
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index be71a03c936a..fbe320b5e89f 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -2052,6 +2052,25 @@ char *format_page_flags(char *buf, char *end, unsigned long flags)
 	return buf;
 }
 
+static
+char *format_page_type(char *buf, char *end, unsigned int page_type)
+{
+	buf = number(buf, end, page_type, default_flag_spec);
+
+	if (buf < end)
+		*buf = '(';
+	buf++;
+
+	if (page_type_has_type(page_type))
+		buf = format_flags(buf, end, ~page_type, pagetype_names);
+
+	if (buf < end)
+		*buf = ')';
+	buf++;
+
+	return buf;
+}
+
 static noinline_for_stack
 char *flags_string(char *buf, char *end, void *flags_ptr,
 		   struct printf_spec spec, const char *fmt)
@@ -2065,6 +2084,8 @@ char *flags_string(char *buf, char *end, void *flags_ptr,
 	switch (fmt[1]) {
 	case 'p':
 		return format_page_flags(buf, end, *(unsigned long *)flags_ptr);
+	case 't':
+		return format_page_type(buf, end, *(unsigned int *)flags_ptr);
 	case 'v':
 		flags = *(unsigned long *)flags_ptr;
 		names = vmaflag_names;
diff --git a/mm/debug.c b/mm/debug.c
index 7f8e5f744e42..5ce6b359004a 100644
--- a/mm/debug.c
+++ b/mm/debug.c
@@ -36,6 +36,11 @@ const struct trace_print_flags pageflag_names[] = {
 	{0, NULL}
 };
 
+const struct trace_print_flags pagetype_names[] = {
+	__def_pagetype_names,
+	{0, NULL}
+};
+
 const struct trace_print_flags gfpflag_names[] = {
 	__def_gfpflag_names,
 	{0, NULL}
diff --git a/mm/internal.h b/mm/internal.h
index bcf75a8b032d..b4ba6fd6051c 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -773,6 +773,7 @@ static inline void flush_tlb_batched_pending(struct mm_struct *mm)
 #endif /* CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH */
 
 extern const struct trace_print_flags pageflag_names[];
+extern const struct trace_print_flags pagetype_names[];
 extern const struct trace_print_flags vmaflag_names[];
 extern const struct trace_print_flags gfpflag_names[];
 
-- 
2.32.0



^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [RFC v3 4/4] mm/debug: use %pGt to print page_type in dump_page()
  2022-12-18 10:18 [RFC v3 0/4] move PG_slab flag to page_type Hyeonggon Yoo
                   ` (2 preceding siblings ...)
  2022-12-18 10:19 ` [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type Hyeonggon Yoo
@ 2022-12-18 10:19 ` Hyeonggon Yoo
  3 siblings, 0 replies; 25+ messages in thread
From: Hyeonggon Yoo @ 2022-12-18 10:19 UTC (permalink / raw)
  To: Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Vlastimil Babka, Roman Gushchin
  Cc: Hyeonggon Yoo,
	HORIGUCHI NAOYA(堀口 直也),
	Joe Perches, Petr Mladek, Andy Shevchenko, Matthew WilCox,
	David Hildenbrand, linux-mm, linux-kernel

Some page flags are stored in page_type rather than flags field.
Use newly introduced page type %pGt in dump_page().

Below are some examples:

page:00000000e47d45a7 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10175e
flags: 0x200000000000000(node=0|zone=2)
page_type: 0xffffffff()
raw: 0200000000000000 0000000000000000 dead000000000122 0000000000000000
raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
page dumped because: just after alloc_pages()

page:00000000e47d45a7 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10175e
flags: 0x200000000000000(node=0|zone=2)
page_type: 0xffefffff(slab)
raw: 0200000000000000 0000000000000000 dead000000000122 0000000000000000
raw: 0000000000000000 0000000000000000 00000001ffefffff 0000000000000000
page dumped because: page with PG_slab set

page:00000000e47d45a7 refcount:1 mapcount:2 mapping:0000000000000000 index:0x0 pfn:0x10175e
flags: 0x200000000000000(node=0|zone=2)
page_type: 0x1()
raw: 0200000000000000 0000000000000000 dead000000000122 0000000000000000
raw: 0000000000000000 0000000000000000 0000000100000001 0000000000000000
page dumped because: page with _mapcount == 1

Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
---
 mm/debug.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/debug.c b/mm/debug.c
index 5ce6b359004a..d6a0eb0a9bb8 100644
--- a/mm/debug.c
+++ b/mm/debug.c
@@ -120,6 +120,8 @@ static void __dump_page(struct page *page)
 
 	pr_warn("%sflags: %pGp%s\n", type, &head->flags,
 		page_cma ? " CMA" : "");
+	pr_warn("page_type: %pGt\n", &head->page_type);
+
 	print_hex_dump(KERN_WARNING, "raw: ", DUMP_PREFIX_NONE, 32,
 			sizeof(unsigned long), page,
 			sizeof(struct page), false);
-- 
2.32.0



^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type
  2022-12-18 10:19 ` [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type Hyeonggon Yoo
@ 2022-12-18 19:32   ` kernel test robot
  2022-12-19  9:44   ` Andy Shevchenko
  2022-12-20 15:20   ` Petr Mladek
  2 siblings, 0 replies; 25+ messages in thread
From: kernel test robot @ 2022-12-18 19:32 UTC (permalink / raw)
  To: Hyeonggon Yoo; +Cc: oe-kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2092 bytes --]

Hi Hyeonggon,

[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on vbabka-slab/for-next]
[also build test WARNING on linus/master next-20221216]
[cannot apply to v6.1]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Hyeonggon-Yoo/move-PG_slab-flag-to-page_type/20221218-182037
base:   git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git for-next
patch link:    https://lore.kernel.org/r/20221218101901.373450-4-42.hyeyoo%40gmail.com
patch subject: [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type
reproduce:
        # https://github.com/intel-lab-lkp/linux/commit/638cb9a12fc29804f5c31a1f02e8e6da044b0981
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Hyeonggon-Yoo/move-PG_slab-flag-to-page_type/20221218-182037
        git checkout 638cb9a12fc29804f5c31a1f02e8e6da044b0981
        make menuconfig
        # enable CONFIG_COMPILE_TEST, CONFIG_WARN_MISSING_DOCUMENTS, CONFIG_WARN_ABI_ERRORS
        make htmldocs

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> Documentation/core-api/printk-formats.rst:579: WARNING: Title underline too short.

vim +579 Documentation/core-api/printk-formats.rst

b67ad18b06701b Documentation/printk-formats.txt          Randy Dunlap          2008-11-12  577  
638cb9a12fc298 Documentation/core-api/printk-formats.rst Hyeonggon Yoo         2022-12-18  578  Flags bitfields such as page flags, page_type, gfp_flags
b3ed23213eab1e Documentation/core-api/printk-formats.rst Tobin C. Harding      2017-12-20 @579  ---------------------------------------------
3b033380cb8dea Documentation/printk-formats.txt          Mauro Carvalho Chehab 2017-05-16  580  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

[-- Attachment #2: config --]
[-- Type: text/plain, Size: 38869 bytes --]

#
# Automatically generated file; DO NOT EDIT.
# Linux/x86_64 6.1.0-rc2 Kernel Configuration
#
CONFIG_CC_VERSION_TEXT="gcc-11 (Debian 11.3.0-8) 11.3.0"
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=110300
CONFIG_CLANG_VERSION=0
CONFIG_AS_IS_GNU=y
CONFIG_AS_VERSION=23900
CONFIG_LD_IS_BFD=y
CONFIG_LD_VERSION=23900
CONFIG_LLD_VERSION=0
CONFIG_CC_CAN_LINK=y
CONFIG_CC_CAN_LINK_STATIC=y
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
CONFIG_CC_HAS_ASM_INLINE=y
CONFIG_CC_HAS_NO_PROFILE_FN_ATTR=y
CONFIG_PAHOLE_VERSION=123
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_TABLE_SORT=y
CONFIG_THREAD_INFO_IN_TASK=y

#
# General setup
#
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_COMPILE_TEST=y
# CONFIG_WERROR is not set
CONFIG_LOCALVERSION=""
CONFIG_BUILD_SALT=""
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_HAVE_KERNEL_ZSTD=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not set
# CONFIG_KERNEL_LZ4 is not set
# CONFIG_KERNEL_ZSTD is not set
CONFIG_DEFAULT_INIT=""
CONFIG_DEFAULT_HOSTNAME="(none)"
# CONFIG_SYSVIPC is not set
# CONFIG_WATCH_QUEUE is not set
# CONFIG_CROSS_MEMORY_ATTACH is not set
# CONFIG_USELIB is not set
CONFIG_HAVE_ARCH_AUDITSYSCALL=y

#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_DOMAIN_HIERARCHY=y
CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR=y
CONFIG_GENERIC_IRQ_RESERVATION_MODE=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
# end of IRQ subsystem

CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_ARCH_CLOCKSOURCE_INIT=y
CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y

#
# Timers subsystem
#
CONFIG_HZ_PERIODIC=y
# CONFIG_NO_HZ_IDLE is not set
# CONFIG_NO_HZ is not set
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US=100
# end of Timers subsystem

CONFIG_HAVE_EBPF_JIT=y
CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y

#
# BPF subsystem
#
# CONFIG_BPF_SYSCALL is not set
# end of BPF subsystem

CONFIG_PREEMPT_NONE_BUILD=y
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
# CONFIG_PREEMPT_DYNAMIC is not set

#
# CPU/Task time and stats accounting
#
CONFIG_TICK_CPU_ACCOUNTING=y
# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
# CONFIG_IRQ_TIME_ACCOUNTING is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_PSI is not set
# end of CPU/Task time and stats accounting

CONFIG_CPU_ISOLATION=y

#
# RCU Subsystem
#
CONFIG_TINY_RCU=y
# CONFIG_RCU_EXPERT is not set
CONFIG_SRCU=y
CONFIG_TINY_SRCU=y
# end of RCU Subsystem

# CONFIG_IKCONFIG is not set
# CONFIG_IKHEADERS is not set
CONFIG_LOG_BUF_SHIFT=17
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y

#
# Scheduler features
#
# end of Scheduler features

CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y
CONFIG_CC_HAS_INT128=y
CONFIG_CC_IMPLICIT_FALLTHROUGH="-Wimplicit-fallthrough=5"
CONFIG_GCC12_NO_ARRAY_BOUNDS=y
CONFIG_ARCH_SUPPORTS_INT128=y
# CONFIG_CGROUPS is not set
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_TIME_NS is not set
# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
# CONFIG_CHECKPOINT_RESTORE is not set
# CONFIG_SCHED_AUTOGROUP is not set
# CONFIG_SYSFS_DEPRECATED is not set
# CONFIG_RELAY is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_BOOT_CONFIG is not set
# CONFIG_INITRAMFS_PRESERVE_MTIME is not set
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_LD_ORPHAN_WARN=y
CONFIG_SYSCTL=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_HAVE_PCSPKR_PLATFORM=y
# CONFIG_EXPERT is not set
CONFIG_MULTIUSER=y
CONFIG_SGETMASK_SYSCALL=y
CONFIG_SYSFS_SYSCALL=y
CONFIG_FHANDLE=y
CONFIG_POSIX_TIMERS=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_PCSPKR_PLATFORM=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_FUTEX_PI=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_IO_URING=y
CONFIG_ADVISE_SYSCALLS=y
CONFIG_MEMBARRIER=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_BASE_RELATIVE=y
CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
CONFIG_RSEQ=y
# CONFIG_EMBEDDED is not set
CONFIG_HAVE_PERF_EVENTS=y

#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
# end of Kernel Performance Events And Counters

# CONFIG_PROFILING is not set
# end of General setup

CONFIG_64BIT=y
CONFIG_X86_64=y
CONFIG_X86=y
CONFIG_INSTRUCTION_DECODER=y
CONFIG_OUTPUT_FORMAT="elf64-x86-64"
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_MMU=y
CONFIG_ARCH_MMAP_RND_BITS_MIN=28
CONFIG_ARCH_MMAP_RND_BITS_MAX=32
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_NR_GPIO=1024
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_AUDIT_ARCH=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_PGTABLE_LEVELS=4
CONFIG_CC_HAS_SANE_STACKPROTECTOR=y

#
# Processor type and features
#
# CONFIG_SMP is not set
CONFIG_X86_FEATURE_NAMES=y
CONFIG_X86_MPPARSE=y
# CONFIG_GOLDFISH is not set
# CONFIG_X86_CPU_RESCTRL is not set
# CONFIG_X86_EXTENDED_PLATFORM is not set
# CONFIG_SCHED_OMIT_FRAME_POINTER is not set
# CONFIG_HYPERVISOR_GUEST is not set
# CONFIG_MK8 is not set
# CONFIG_MPSC is not set
# CONFIG_MCORE2 is not set
# CONFIG_MATOM is not set
CONFIG_GENERIC_CPU=y
CONFIG_X86_INTERNODE_CACHE_SHIFT=6
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_TSC=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_CMOV=y
CONFIG_X86_MINIMUM_CPU_FAMILY=64
CONFIG_X86_DEBUGCTLMSR=y
CONFIG_IA32_FEAT_CTL=y
CONFIG_X86_VMX_FEATURE_NAMES=y
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_HYGON=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_CPU_SUP_ZHAOXIN=y
CONFIG_HPET_TIMER=y
CONFIG_DMI=y
CONFIG_NR_CPUS_RANGE_BEGIN=1
CONFIG_NR_CPUS_RANGE_END=1
CONFIG_NR_CPUS_DEFAULT=1
CONFIG_NR_CPUS=1
CONFIG_UP_LATE_INIT=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
# CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set
# CONFIG_X86_MCE is not set

#
# Performance monitoring
#
# CONFIG_PERF_EVENTS_AMD_POWER is not set
# CONFIG_PERF_EVENTS_AMD_UNCORE is not set
# CONFIG_PERF_EVENTS_AMD_BRS is not set
# end of Performance monitoring

CONFIG_X86_16BIT=y
CONFIG_X86_ESPFIX64=y
CONFIG_X86_VSYSCALL_EMULATION=y
# CONFIG_X86_IOPL_IOPERM is not set
# CONFIG_MICROCODE is not set
# CONFIG_X86_MSR is not set
# CONFIG_X86_CPUID is not set
# CONFIG_X86_5LEVEL is not set
CONFIG_X86_DIRECT_GBPAGES=y
# CONFIG_AMD_MEM_ENCRYPT is not set
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set
CONFIG_MTRR=y
# CONFIG_MTRR_SANITIZER is not set
CONFIG_X86_PAT=y
CONFIG_ARCH_USES_PG_UNCACHED=y
CONFIG_X86_UMIP=y
CONFIG_CC_HAS_IBT=y
# CONFIG_X86_KERNEL_IBT is not set
# CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS is not set
CONFIG_X86_INTEL_TSX_MODE_OFF=y
# CONFIG_X86_INTEL_TSX_MODE_ON is not set
# CONFIG_X86_INTEL_TSX_MODE_AUTO is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x1000000
# CONFIG_RELOCATABLE is not set
CONFIG_PHYSICAL_ALIGN=0x200000
CONFIG_LEGACY_VSYSCALL_XONLY=y
# CONFIG_LEGACY_VSYSCALL_NONE is not set
# CONFIG_CMDLINE_BOOL is not set
CONFIG_MODIFY_LDT_SYSCALL=y
# CONFIG_STRICT_SIGALTSTACK_SIZE is not set
CONFIG_HAVE_LIVEPATCH=y
# end of Processor type and features

CONFIG_CC_HAS_SLS=y
CONFIG_CC_HAS_RETURN_THUNK=y
# CONFIG_SPECULATION_MITIGATIONS is not set
CONFIG_ARCH_HAS_ADD_PAGES=y
CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y

#
# Power management and ACPI options
#
# CONFIG_SUSPEND is not set
# CONFIG_PM is not set
CONFIG_ARCH_SUPPORTS_ACPI=y
# CONFIG_ACPI is not set

#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set
# end of CPU Frequency scaling

#
# CPU Idle
#
# CONFIG_CPU_IDLE is not set
# end of CPU Idle
# end of Power management and ACPI options

#
# Bus options (PCI etc.)
#
CONFIG_ISA_DMA_API=y
# end of Bus options (PCI etc.)

#
# Binary Emulations
#
# CONFIG_IA32_EMULATION is not set
# CONFIG_X86_X32_ABI is not set
# end of Binary Emulations

CONFIG_HAVE_KVM=y
# CONFIG_VIRTUALIZATION is not set
CONFIG_AS_AVX512=y
CONFIG_AS_SHA1_NI=y
CONFIG_AS_SHA256_NI=y
CONFIG_AS_TPAUSE=y

#
# General architecture-dependent options
#
CONFIG_GENERIC_ENTRY=y
# CONFIG_JUMP_LABEL is not set
# CONFIG_STATIC_CALL_SELFTEST is not set
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_KPROBES_ON_FTRACE=y
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
CONFIG_HAVE_FUNCTION_ERROR_INJECTION=y
CONFIG_HAVE_NMI=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
CONFIG_ARCH_HAS_SET_MEMORY=y
CONFIG_ARCH_HAS_SET_DIRECT_MAP=y
CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y
CONFIG_ARCH_WANTS_NO_INSTR=y
CONFIG_HAVE_ASM_MODVERSIONS=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_RSEQ=y
CONFIG_HAVE_RUST=y
CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
CONFIG_HAVE_USER_RETURN_NOTIFIER=y
CONFIG_HAVE_PERF_EVENTS_NMI=y
CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE=y
CONFIG_MMU_GATHER_MERGE_VMAS=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
CONFIG_HAVE_CMPXCHG_LOCAL=y
CONFIG_HAVE_CMPXCHG_DOUBLE=y
CONFIG_HAVE_ARCH_SECCOMP=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
# CONFIG_SECCOMP is not set
CONFIG_HAVE_ARCH_STACKLEAK=y
CONFIG_HAVE_STACKPROTECTOR=y
# CONFIG_STACKPROTECTOR is not set
CONFIG_ARCH_SUPPORTS_LTO_CLANG=y
CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN=y
CONFIG_LTO_NONE=y
CONFIG_ARCH_SUPPORTS_CFI_CLANG=y
CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y
CONFIG_HAVE_CONTEXT_TRACKING_USER=y
CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_MOVE_PUD=y
CONFIG_HAVE_MOVE_PMD=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD=y
CONFIG_HAVE_ARCH_HUGE_VMAP=y
CONFIG_HAVE_ARCH_HUGE_VMALLOC=y
CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
CONFIG_HAVE_ARCH_SOFT_DIRTY=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK=y
CONFIG_SOFTIRQ_ON_OWN_STACK=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
CONFIG_HAVE_EXIT_THREAD=y
CONFIG_ARCH_MMAP_RND_BITS=28
CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
CONFIG_PAGE_SIZE_LESS_THAN_256KB=y
CONFIG_HAVE_OBJTOOL=y
CONFIG_HAVE_JUMP_LABEL_HACK=y
CONFIG_HAVE_NOINSTR_HACK=y
CONFIG_HAVE_NOINSTR_VALIDATION=y
CONFIG_HAVE_UACCESS_VALIDATION=y
CONFIG_HAVE_STACK_VALIDATION=y
CONFIG_HAVE_RELIABLE_STACKTRACE=y
# CONFIG_COMPAT_32BIT_TIME is not set
CONFIG_HAVE_ARCH_VMAP_STACK=y
# CONFIG_VMAP_STACK is not set
CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y
CONFIG_RANDOMIZE_KSTACK_OFFSET=y
# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set
CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
CONFIG_STRICT_KERNEL_RWX=y
CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y
CONFIG_ARCH_HAS_MEM_ENCRYPT=y
CONFIG_HAVE_STATIC_CALL=y
CONFIG_HAVE_STATIC_CALL_INLINE=y
CONFIG_HAVE_PREEMPT_DYNAMIC=y
CONFIG_HAVE_PREEMPT_DYNAMIC_CALL=y
CONFIG_ARCH_WANT_LD_ORPHAN_WARN=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK=y
CONFIG_ARCH_HAS_ELFCORE_COMPAT=y
CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH=y
CONFIG_DYNAMIC_SIGFRAME=y
CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG=y

#
# GCOV-based kernel profiling
#
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
# end of GCOV-based kernel profiling

CONFIG_HAVE_GCC_PLUGINS=y
# CONFIG_GCC_PLUGINS is not set
# end of General architecture-dependent options

CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
# CONFIG_BLOCK_LEGACY_AUTOLOAD is not set
# CONFIG_BLK_DEV_BSGLIB is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
# CONFIG_BLK_DEV_ZONED is not set
# CONFIG_BLK_WBT is not set
# CONFIG_BLK_SED_OPAL is not set
# CONFIG_BLK_INLINE_ENCRYPTION is not set

#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_EFI_PARTITION=y
# end of Partition Types

#
# IO Schedulers
#
# CONFIG_MQ_IOSCHED_DEADLINE is not set
# CONFIG_MQ_IOSCHED_KYBER is not set
# CONFIG_IOSCHED_BFQ is not set
# end of IO Schedulers

CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
CONFIG_INLINE_READ_UNLOCK=y
CONFIG_INLINE_READ_UNLOCK_IRQ=y
CONFIG_INLINE_WRITE_UNLOCK=y
CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y
CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y
CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y

#
# Executable file formats
#
# CONFIG_BINFMT_ELF is not set
# CONFIG_BINFMT_SCRIPT is not set
# CONFIG_BINFMT_MISC is not set
CONFIG_COREDUMP=y
# end of Executable file formats

#
# Memory Management options
#
# CONFIG_SWAP is not set

#
# SLAB allocator options
#
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLAB_MERGE_DEFAULT is not set
# CONFIG_SLAB_FREELIST_RANDOM is not set
# CONFIG_SLAB_FREELIST_HARDENED is not set
# CONFIG_SLUB_STATS is not set
# end of SLAB allocator options

# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_SPARSEMEM=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
# CONFIG_SPARSEMEM_VMEMMAP is not set
CONFIG_HAVE_FAST_GUP=y
CONFIG_EXCLUSIVE_SYSTEM_RAM=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
# CONFIG_MEMORY_HOTPLUG is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y
# CONFIG_COMPACTION is not set
# CONFIG_PAGE_REPORTING is not set
CONFIG_PHYS_ADDR_T_64BIT=y
# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_ARCH_WANTS_THP_SWAP=y
# CONFIG_TRANSPARENT_HUGEPAGE is not set
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
# CONFIG_CMA is not set
CONFIG_GENERIC_EARLY_IOREMAP=y
# CONFIG_IDLE_PAGE_TRACKING is not set
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_ARCH_HAS_CURRENT_STACK_POINTER=y
CONFIG_ARCH_HAS_PTE_DEVMAP=y
CONFIG_ZONE_DMA=y
CONFIG_ZONE_DMA32=y
CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_PERCPU_STATS is not set

#
# GUP_TEST needs to have DEBUG_FS enabled
#
CONFIG_ARCH_HAS_PTE_SPECIAL=y
CONFIG_SECRETMEM=y
# CONFIG_ANON_VMA_NAME is not set
# CONFIG_USERFAULTFD is not set
# CONFIG_LRU_GEN is not set

#
# Data Access Monitoring
#
# CONFIG_DAMON is not set
# end of Data Access Monitoring
# end of Memory Management options

# CONFIG_NET is not set

#
# Device Drivers
#
CONFIG_HAVE_EISA=y
# CONFIG_EISA is not set
CONFIG_HAVE_PCI=y
# CONFIG_PCI is not set
# CONFIG_PCCARD is not set

#
# Generic Driver Options
#
# CONFIG_UEVENT_HELPER is not set
# CONFIG_DEVTMPFS is not set
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set

#
# Firmware loader
#
CONFIG_FW_LOADER=y
CONFIG_EXTRA_FIRMWARE=""
# CONFIG_FW_LOADER_USER_HELPER is not set
# CONFIG_FW_LOADER_COMPRESS is not set
# CONFIG_FW_UPLOAD is not set
# end of Firmware loader

CONFIG_ALLOW_DEV_COREDUMP=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_CPU_VULNERABILITIES=y
# end of Generic Driver Options

#
# Bus devices
#
# CONFIG_ARM_INTEGRATOR_LM is not set
# CONFIG_BT1_APB is not set
# CONFIG_BT1_AXI is not set
# CONFIG_HISILICON_LPC is not set
# CONFIG_INTEL_IXP4XX_EB is not set
# CONFIG_QCOM_EBI2 is not set
# CONFIG_MHI_BUS is not set
# CONFIG_MHI_BUS_EP is not set
# end of Bus devices

#
# Firmware Drivers
#

#
# ARM System Control and Management Interface Protocol
#
# CONFIG_ARM_SCMI_PROTOCOL is not set
# end of ARM System Control and Management Interface Protocol

# CONFIG_EDD is not set
CONFIG_FIRMWARE_MEMMAP=y
# CONFIG_DMIID is not set
# CONFIG_DMI_SYSFS is not set
CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y
# CONFIG_FW_CFG_SYSFS is not set
# CONFIG_SYSFB_SIMPLEFB is not set
# CONFIG_BCM47XX_NVRAM is not set
# CONFIG_GOOGLE_FIRMWARE is not set

#
# Tegra firmware driver
#
# end of Tegra firmware driver
# end of Firmware Drivers

# CONFIG_GNSS is not set
# CONFIG_MTD is not set
# CONFIG_OF is not set
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
# CONFIG_PARPORT is not set
# CONFIG_BLK_DEV is not set

#
# NVME Support
#
# CONFIG_NVME_FC is not set
# end of NVME Support

#
# Misc devices
#
# CONFIG_DUMMY_IRQ is not set
# CONFIG_ATMEL_SSC is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_QCOM_COINCELL is not set
# CONFIG_SRAM is not set
# CONFIG_XILINX_SDFEC is not set
# CONFIG_C2PORT is not set

#
# EEPROM support
#
# CONFIG_EEPROM_93CX6 is not set
# end of EEPROM support

#
# Texas Instruments shared transport line discipline
#
# end of Texas Instruments shared transport line discipline

#
# Altera FPGA firmware download module (requires I2C)
#
# CONFIG_ECHO is not set
# CONFIG_PVPANIC is not set
# end of Misc devices

#
# SCSI device support
#
CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# end of SCSI device support

# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_TARGET_CORE is not set

#
# IEEE 1394 (FireWire) support
#
# CONFIG_FIREWIRE is not set
# end of IEEE 1394 (FireWire) support

# CONFIG_MACINTOSH_DRIVERS is not set

#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_SPARSEKMAP is not set
# CONFIG_INPUT_MATRIXKMAP is not set

#
# Userland interfaces
#
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_EVDEV is not set
# CONFIG_INPUT_EVBUG is not set

#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
# CONFIG_RMI4_CORE is not set

#
# Hardware I/O ports
#
# CONFIG_SERIO is not set
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
# CONFIG_GAMEPORT is not set
# end of Hardware I/O ports
# end of Input device support

#
# Character devices
#
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_LDISC_AUTOLOAD is not set

#
# Serial drivers
#
# CONFIG_SERIAL_8250 is not set

#
# Non-8250 serial port support
#
# CONFIG_SERIAL_AMBA_PL010 is not set
# CONFIG_SERIAL_MESON is not set
# CONFIG_SERIAL_CLPS711X is not set
# CONFIG_SERIAL_SAMSUNG is not set
# CONFIG_SERIAL_TEGRA is not set
# CONFIG_SERIAL_IMX is not set
# CONFIG_SERIAL_UARTLITE is not set
# CONFIG_SERIAL_SH_SCI is not set
# CONFIG_SERIAL_MSM is not set
# CONFIG_SERIAL_VT8500 is not set
# CONFIG_SERIAL_OMAP is not set
# CONFIG_SERIAL_LANTIQ is not set
# CONFIG_SERIAL_SCCNXP is not set
# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_BCM63XX is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
# CONFIG_SERIAL_MXS_AUART is not set
# CONFIG_SERIAL_MPS2_UART is not set
# CONFIG_SERIAL_ARC is not set
# CONFIG_SERIAL_FSL_LPUART is not set
# CONFIG_SERIAL_FSL_LINFLEXUART is not set
# CONFIG_SERIAL_ST_ASC is not set
# CONFIG_SERIAL_STM32 is not set
# CONFIG_SERIAL_OWL is not set
# CONFIG_SERIAL_RDA is not set
# CONFIG_SERIAL_LITEUART is not set
# CONFIG_SERIAL_SUNPLUS is not set
# end of Serial drivers

# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_NULL_TTY is not set
# CONFIG_SERIAL_DEV_BUS is not set
# CONFIG_VIRTIO_CONSOLE is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_ASPEED_KCS_IPMI_BMC is not set
# CONFIG_NPCM7XX_KCS_IPMI_BMC is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_MWAVE is not set
# CONFIG_DEVMEM is not set
# CONFIG_NVRAM is not set
# CONFIG_HANGCHECK_TIMER is not set
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
# CONFIG_RANDOM_TRUST_CPU is not set
# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
# end of Character devices

#
# I2C support
#
# CONFIG_I2C is not set
# end of I2C support

# CONFIG_I3C is not set
# CONFIG_SPI is not set
# CONFIG_SPMI is not set
# CONFIG_HSI is not set
# CONFIG_PPS is not set

#
# PTP clock support
#
CONFIG_PTP_1588_CLOCK_OPTIONAL=y

#
# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
#
# end of PTP clock support

# CONFIG_PINCTRL is not set
# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_RESET is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
CONFIG_BCMA_POSSIBLE=y
# CONFIG_BCMA is not set

#
# Multifunction device drivers
#
# CONFIG_MFD_SUN4I_GPADC is not set
# CONFIG_MFD_AT91_USART is not set
# CONFIG_MFD_MADERA is not set
# CONFIG_MFD_EXYNOS_LPASS is not set
# CONFIG_MFD_MXS_LRADC is not set
# CONFIG_MFD_MX25_TSADC is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_KEMPLD is not set
# CONFIG_MFD_MT6397 is not set
# CONFIG_MFD_PM8XXX is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_ABX500_CORE is not set
# CONFIG_MFD_SUN6I_PRCM is not set
# CONFIG_MFD_SYSCON is not set
# CONFIG_MFD_TI_AM335X_TSCADC is not set
# CONFIG_MFD_TQMX86 is not set
# CONFIG_MFD_STM32_LPTIMER is not set
# CONFIG_MFD_STM32_TIMERS is not set
# end of Multifunction device drivers

# CONFIG_REGULATOR is not set
# CONFIG_RC_CORE is not set

#
# CEC support
#
# CONFIG_MEDIA_CEC_SUPPORT is not set
# end of CEC support

# CONFIG_MEDIA_SUPPORT is not set

#
# Graphics support
#
# CONFIG_IMX_IPUV3_CORE is not set
# CONFIG_DRM is not set

#
# ARM devices
#
# end of ARM devices

#
# Frame buffer Devices
#
# CONFIG_FB is not set
# CONFIG_MMP_DISP is not set
# end of Frame buffer Devices

#
# Backlight & LCD device support
#
# CONFIG_LCD_CLASS_DEVICE is not set
# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
# end of Backlight & LCD device support

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=80
CONFIG_DUMMY_CONSOLE_ROWS=25
# end of Console display driver support
# end of Graphics support

# CONFIG_SOUND is not set

#
# HID support
#
# CONFIG_HID is not set
# end of HID support

CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_RTC_LIB=y
CONFIG_RTC_MC146818_LIB=y
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set

#
# DMABUF options
#
# CONFIG_SYNC_FILE is not set
# CONFIG_DMABUF_HEAPS is not set
# end of DMABUF options

# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
# CONFIG_VFIO is not set
# CONFIG_VIRT_DRIVERS is not set
# CONFIG_VIRTIO_MENU is not set
# CONFIG_VHOST_MENU is not set

#
# Microsoft Hyper-V guest support
#
# end of Microsoft Hyper-V guest support

# CONFIG_GREYBUS is not set
# CONFIG_COMEDI is not set
# CONFIG_STAGING is not set
# CONFIG_CHROME_PLATFORMS is not set
# CONFIG_MELLANOX_PLATFORM is not set
# CONFIG_OLPC_XO175 is not set
# CONFIG_SURFACE_PLATFORMS is not set
# CONFIG_X86_PLATFORM_DEVICES is not set
# CONFIG_COMMON_CLK is not set
# CONFIG_HWSPINLOCK is not set

#
# Clock Source drivers
#
CONFIG_CLKEVT_I8253=y
CONFIG_I8253_LOCK=y
CONFIG_CLKBLD_I8253=y
# CONFIG_BCM2835_TIMER is not set
# CONFIG_BCM_KONA_TIMER is not set
# CONFIG_DAVINCI_TIMER is not set
# CONFIG_DIGICOLOR_TIMER is not set
# CONFIG_OMAP_DM_TIMER is not set
# CONFIG_DW_APB_TIMER is not set
# CONFIG_FTTMR010_TIMER is not set
# CONFIG_IXP4XX_TIMER is not set
# CONFIG_MESON6_TIMER is not set
# CONFIG_OWL_TIMER is not set
# CONFIG_RDA_TIMER is not set
# CONFIG_SUN4I_TIMER is not set
# CONFIG_TEGRA_TIMER is not set
# CONFIG_VT8500_TIMER is not set
# CONFIG_NPCM7XX_TIMER is not set
# CONFIG_ASM9260_TIMER is not set
# CONFIG_CLKSRC_DBX500_PRCMU is not set
# CONFIG_CLPS711X_TIMER is not set
# CONFIG_MXS_TIMER is not set
# CONFIG_NSPIRE_TIMER is not set
# CONFIG_INTEGRATOR_AP_TIMER is not set
# CONFIG_CLKSRC_PISTACHIO is not set
# CONFIG_CLKSRC_STM32_LP is not set
# CONFIG_ARMV7M_SYSTICK is not set
# CONFIG_ATMEL_PIT is not set
# CONFIG_ATMEL_ST is not set
# CONFIG_CLKSRC_SAMSUNG_PWM is not set
# CONFIG_FSL_FTM_TIMER is not set
# CONFIG_OXNAS_RPS_TIMER is not set
# CONFIG_MTK_TIMER is not set
# CONFIG_SH_TIMER_CMT is not set
# CONFIG_SH_TIMER_MTU2 is not set
# CONFIG_RENESAS_OSTM is not set
# CONFIG_SH_TIMER_TMU is not set
# CONFIG_EM_TIMER_STI is not set
# CONFIG_CLKSRC_PXA is not set
# CONFIG_TIMER_IMX_SYS_CTR is not set
# CONFIG_CLKSRC_ST_LPC is not set
# CONFIG_GXP_TIMER is not set
# CONFIG_MSC313E_TIMER is not set
# CONFIG_MICROCHIP_PIT64B is not set
# end of Clock Source drivers

# CONFIG_MAILBOX is not set
# CONFIG_IOMMU_SUPPORT is not set

#
# Remoteproc drivers
#
# CONFIG_REMOTEPROC is not set
# end of Remoteproc drivers

#
# Rpmsg drivers
#
# CONFIG_RPMSG_VIRTIO is not set
# end of Rpmsg drivers

#
# SOC (System On Chip) specific Drivers
#

#
# Amlogic SoC drivers
#
# CONFIG_MESON_CANVAS is not set
# CONFIG_MESON_CLK_MEASURE is not set
# CONFIG_MESON_GX_SOCINFO is not set
# CONFIG_MESON_MX_SOCINFO is not set
# end of Amlogic SoC drivers

#
# Apple SoC drivers
#
# CONFIG_APPLE_SART is not set
# end of Apple SoC drivers

#
# ASPEED SoC drivers
#
# CONFIG_ASPEED_LPC_CTRL is not set
# CONFIG_ASPEED_LPC_SNOOP is not set
# CONFIG_ASPEED_UART_ROUTING is not set
# CONFIG_ASPEED_P2A_CTRL is not set
# CONFIG_ASPEED_SOCINFO is not set
# end of ASPEED SoC drivers

# CONFIG_AT91_SOC_ID is not set
# CONFIG_AT91_SOC_SFR is not set

#
# Broadcom SoC drivers
#
# CONFIG_SOC_BCM63XX is not set
# CONFIG_SOC_BRCMSTB is not set
# end of Broadcom SoC drivers

#
# NXP/Freescale QorIQ SoC drivers
#
# end of NXP/Freescale QorIQ SoC drivers

#
# fujitsu SoC drivers
#
# end of fujitsu SoC drivers

#
# i.MX SoC drivers
#
# CONFIG_SOC_IMX8M is not set
# CONFIG_SOC_IMX9 is not set
# end of i.MX SoC drivers

#
# IXP4xx SoC drivers
#
# CONFIG_IXP4XX_QMGR is not set
# CONFIG_IXP4XX_NPE is not set
# end of IXP4xx SoC drivers

#
# Enable LiteX SoC Builder specific drivers
#
# CONFIG_LITEX_SOC_CONTROLLER is not set
# end of Enable LiteX SoC Builder specific drivers

#
# MediaTek SoC drivers
#
# CONFIG_MTK_CMDQ is not set
# CONFIG_MTK_DEVAPC is not set
# CONFIG_MTK_INFRACFG is not set
# CONFIG_MTK_MMSYS is not set
# end of MediaTek SoC drivers

#
# Qualcomm SoC drivers
#
# CONFIG_QCOM_GENI_SE is not set
# CONFIG_QCOM_GSBI is not set
# CONFIG_QCOM_LLCC is not set
# CONFIG_QCOM_RPMH is not set
# CONFIG_QCOM_SPM is not set
# CONFIG_QCOM_ICC_BWMON is not set
# end of Qualcomm SoC drivers

# CONFIG_SOC_RENESAS is not set
# CONFIG_ROCKCHIP_GRF is not set
# CONFIG_SOC_SAMSUNG is not set
# CONFIG_SOC_TI is not set
# CONFIG_UX500_SOC_ID is not set

#
# Xilinx SoC drivers
#
# end of Xilinx SoC drivers
# end of SOC (System On Chip) specific Drivers

# CONFIG_PM_DEVFREQ is not set
# CONFIG_EXTCON is not set
# CONFIG_MEMORY is not set
# CONFIG_IIO is not set
# CONFIG_PWM is not set

#
# IRQ chip support
#
# CONFIG_AL_FIC is not set
# CONFIG_RENESAS_INTC_IRQPIN is not set
# CONFIG_RENESAS_IRQC is not set
# CONFIG_RENESAS_RZA1_IRQC is not set
# CONFIG_RENESAS_RZG2L_IRQC is not set
# CONFIG_SL28CPLD_INTC is not set
# CONFIG_TS4800_IRQ is not set
# CONFIG_INGENIC_TCU_IRQ is not set
# CONFIG_IRQ_UNIPHIER_AIDET is not set
# CONFIG_MESON_IRQ_GPIO is not set
# CONFIG_IMX_IRQSTEER is not set
# CONFIG_IMX_INTMUX is not set
# CONFIG_EXYNOS_IRQ_COMBINER is not set
# CONFIG_MST_IRQ is not set
# CONFIG_MCHP_EIC is not set
# CONFIG_SUNPLUS_SP7021_INTC is not set
# end of IRQ chip support

# CONFIG_IPACK_BUS is not set
# CONFIG_RESET_CONTROLLER is not set

#
# PHY Subsystem
#
# CONFIG_GENERIC_PHY is not set
# CONFIG_PHY_PISTACHIO_USB is not set
# CONFIG_PHY_CAN_TRANSCEIVER is not set

#
# PHY drivers for Broadcom platforms
#
# CONFIG_PHY_BCM63XX_USBH is not set
# CONFIG_BCM_KONA_USB2_PHY is not set
# end of PHY drivers for Broadcom platforms

# CONFIG_PHY_HI6220_USB is not set
# CONFIG_PHY_HI3660_USB is not set
# CONFIG_PHY_HI3670_USB is not set
# CONFIG_PHY_HI3670_PCIE is not set
# CONFIG_PHY_HISTB_COMBPHY is not set
# CONFIG_PHY_HISI_INNO_USB2 is not set
# CONFIG_PHY_PXA_28NM_HSIC is not set
# CONFIG_PHY_PXA_28NM_USB2 is not set
# CONFIG_PHY_PXA_USB is not set
# CONFIG_PHY_MMP3_USB is not set
# CONFIG_PHY_MMP3_HSIC is not set
# CONFIG_PHY_MT7621_PCI is not set
# CONFIG_PHY_RALINK_USB is not set
# CONFIG_PHY_RCAR_GEN3_USB3 is not set
# CONFIG_PHY_ROCKCHIP_DPHY_RX0 is not set
# CONFIG_PHY_ROCKCHIP_PCIE is not set
# CONFIG_PHY_ROCKCHIP_SNPS_PCIE3 is not set
# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set
# CONFIG_PHY_SAMSUNG_USB2 is not set
# CONFIG_PHY_ST_SPEAR1310_MIPHY is not set
# CONFIG_PHY_ST_SPEAR1340_MIPHY is not set
# CONFIG_PHY_TEGRA194_P2U is not set
# CONFIG_PHY_DA8XX_USB is not set
# CONFIG_OMAP_CONTROL_PHY is not set
# CONFIG_TI_PIPE3 is not set
# CONFIG_PHY_INTEL_KEEMBAY_EMMC is not set
# CONFIG_PHY_INTEL_KEEMBAY_USB is not set
# CONFIG_PHY_INTEL_LGM_EMMC is not set
# CONFIG_PHY_XILINX_ZYNQMP is not set
# end of PHY Subsystem

# CONFIG_POWERCAP is not set
# CONFIG_MCB is not set

#
# Performance monitor support
#
# CONFIG_ARM_CCN is not set
# CONFIG_ARM_CMN is not set
# CONFIG_FSL_IMX8_DDR_PMU is not set
# CONFIG_XGENE_PMU is not set
# CONFIG_ARM_DMC620_PMU is not set
# CONFIG_MARVELL_CN10K_TAD_PMU is not set
# CONFIG_ALIBABA_UNCORE_DRW_PMU is not set
# CONFIG_MARVELL_CN10K_DDR_PMU is not set
# end of Performance monitor support

# CONFIG_RAS is not set

#
# Android
#
# CONFIG_ANDROID_BINDER_IPC is not set
# end of Android

# CONFIG_DAX is not set
# CONFIG_NVMEM is not set

#
# HW tracing support
#
# CONFIG_STM is not set
# CONFIG_INTEL_TH is not set
# end of HW tracing support

# CONFIG_FPGA is not set
# CONFIG_TEE is not set
# CONFIG_SIOX is not set
# CONFIG_SLIMBUS is not set
# CONFIG_INTERCONNECT is not set
# CONFIG_COUNTER is not set
# CONFIG_PECI is not set
# CONFIG_HTE is not set
# end of Device Drivers

#
# File systems
#
CONFIG_DCACHE_WORD_ACCESS=y
# CONFIG_VALIDATE_FS_PARSER is not set
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
# CONFIG_EXT4_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_BTRFS_FS is not set
# CONFIG_NILFS2_FS is not set
# CONFIG_F2FS_FS is not set
CONFIG_EXPORTFS=y
# CONFIG_EXPORTFS_BLOCK_OPS is not set
CONFIG_FILE_LOCKING=y
# CONFIG_FS_ENCRYPTION is not set
# CONFIG_FS_VERITY is not set
# CONFIG_DNOTIFY is not set
# CONFIG_INOTIFY_USER is not set
# CONFIG_FANOTIFY is not set
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_FUSE_FS is not set
# CONFIG_OVERLAY_FS is not set

#
# Caches
#
# CONFIG_FSCACHE is not set
# end of Caches

#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
# CONFIG_UDF_FS is not set
# end of CD-ROM/DVD Filesystems

#
# DOS/FAT/EXFAT/NT Filesystems
#
# CONFIG_MSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_EXFAT_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS3_FS is not set
# end of DOS/FAT/EXFAT/NT Filesystems

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
# CONFIG_PROC_KCORE is not set
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
# CONFIG_PROC_CHILDREN is not set
CONFIG_PROC_PID_ARCH_STATUS=y
CONFIG_KERNFS=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLBFS is not set
CONFIG_ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y
CONFIG_ARCH_HAS_GIGANTIC_PAGE=y
# CONFIG_CONFIGFS_FS is not set
# end of Pseudo filesystems

# CONFIG_MISC_FILESYSTEMS is not set
# CONFIG_NLS is not set
# CONFIG_UNICODE is not set
CONFIG_IO_WQ=y
# end of File systems

#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY_DMESG_RESTRICT is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
# CONFIG_HARDENED_USERCOPY is not set
# CONFIG_FORTIFY_SOURCE is not set
# CONFIG_STATIC_USERMODEHELPER is not set
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,bpf"

#
# Kernel hardening options
#

#
# Memory initialization
#
CONFIG_INIT_STACK_NONE=y
# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
CONFIG_CC_HAS_ZERO_CALL_USED_REGS=y
# CONFIG_ZERO_CALL_USED_REGS is not set
# end of Memory initialization

CONFIG_RANDSTRUCT_NONE=y
# end of Kernel hardening options
# end of Security options

# CONFIG_CRYPTO is not set

#
# Library routines
#
# CONFIG_PACKING is not set
CONFIG_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
# CONFIG_CORDIC is not set
# CONFIG_PRIME_NUMBERS is not set
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_IOMAP=y
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
CONFIG_ARCH_HAS_FAST_MULTIPLIER=y
CONFIG_ARCH_USE_SYM_ANNOTATIONS=y

#
# Crypto library routines
#
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
# CONFIG_CRYPTO_LIB_CHACHA is not set
# CONFIG_CRYPTO_LIB_CURVE25519 is not set
CONFIG_CRYPTO_LIB_POLY1305_RSIZE=11
# CONFIG_CRYPTO_LIB_POLY1305 is not set
# end of Crypto library routines

# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
# CONFIG_CRC64_ROCKSOFT is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
# CONFIG_CRC32_SELFTEST is not set
CONFIG_CRC32_SLICEBY8=y
# CONFIG_CRC32_SLICEBY4 is not set
# CONFIG_CRC32_SARWATE is not set
# CONFIG_CRC32_BIT is not set
# CONFIG_CRC64 is not set
# CONFIG_CRC4 is not set
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
# CONFIG_CRC8 is not set
# CONFIG_RANDOM32_SELFTEST is not set
# CONFIG_XZ_DEC is not set
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HAS_DMA=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_SWIOTLB=y
# CONFIG_DMA_API_DEBUG is not set
# CONFIG_IRQ_POLL is not set
CONFIG_HAVE_GENERIC_VDSO=y
CONFIG_GENERIC_GETTIMEOFDAY=y
CONFIG_GENERIC_VDSO_TIME_NS=y
CONFIG_ARCH_HAS_PMEM_API=y
CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE=y
CONFIG_ARCH_HAS_COPY_MC=y
CONFIG_ARCH_STACKWALK=y
CONFIG_STACKDEPOT=y
CONFIG_SBITMAP=y
# CONFIG_PARMAN is not set
# CONFIG_OBJAGG is not set
# end of Library routines

#
# Kernel hacking
#

#
# printk and dmesg options
#
# CONFIG_PRINTK_TIME is not set
# CONFIG_PRINTK_CALLER is not set
# CONFIG_STACKTRACE_BUILD_ID is not set
CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
CONFIG_CONSOLE_LOGLEVEL_QUIET=4
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_DYNAMIC_DEBUG_CORE is not set
# CONFIG_SYMBOLIC_ERRNAME is not set
CONFIG_DEBUG_BUGVERBOSE=y
# end of printk and dmesg options

# CONFIG_DEBUG_KERNEL is not set

#
# Compile-time checks and compiler options
#
CONFIG_AS_HAS_NON_CONST_LEB128=y
CONFIG_FRAME_WARN=2048
# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_HEADERS_INSTALL is not set
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_SECTION_MISMATCH_WARN_ONLY=y
CONFIG_OBJTOOL=y
# end of Compile-time checks and compiler options

#
# Generic Kernel Debugging Instruments
#
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_DEBUG_FS is not set
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y
# CONFIG_UBSAN is not set
CONFIG_HAVE_ARCH_KCSAN=y
CONFIG_HAVE_KCSAN_COMPILER=y
# end of Generic Kernel Debugging Instruments

#
# Networking Debugging
#
# end of Networking Debugging

#
# Memory Debugging
#
# CONFIG_PAGE_EXTENSION is not set
CONFIG_SLUB_DEBUG=y
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_PAGE_TABLE_CHECK is not set
# CONFIG_PAGE_POISONING is not set
# CONFIG_DEBUG_RODATA_TEST is not set
CONFIG_ARCH_HAS_DEBUG_WX=y
# CONFIG_DEBUG_WX is not set
CONFIG_GENERIC_PTDUMP=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y
# CONFIG_DEBUG_VM_PGTABLE is not set
CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP=y
CONFIG_HAVE_ARCH_KASAN=y
CONFIG_HAVE_ARCH_KASAN_VMALLOC=y
CONFIG_CC_HAS_KASAN_GENERIC=y
CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS=y
# CONFIG_KASAN is not set
CONFIG_HAVE_ARCH_KFENCE=y
# CONFIG_KFENCE is not set
CONFIG_HAVE_ARCH_KMSAN=y
# end of Memory Debugging

#
# Debug Oops, Lockups and Hangs
#
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_PANIC_TIMEOUT=0
CONFIG_HARDLOCKUP_CHECK_TIMESTAMP=y
# end of Debug Oops, Lockups and Hangs

#
# Scheduler Debugging
#
# end of Scheduler Debugging

# CONFIG_DEBUG_TIMEKEEPING is not set

#
# Lock Debugging (spinlocks, mutexes, etc...)
#
CONFIG_LOCK_DEBUGGING_SUPPORT=y
# CONFIG_WW_MUTEX_SELFTEST is not set
# end of Lock Debugging (spinlocks, mutexes, etc...)

# CONFIG_DEBUG_IRQFLAGS is not set
CONFIG_STACKTRACE=y
# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set

#
# Debug kernel data structures
#
# CONFIG_BUG_ON_DATA_CORRUPTION is not set
# end of Debug kernel data structures

#
# RCU Debugging
#
# end of RCU Debugging

CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_HAVE_RETHOOK=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y
CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_FENTRY=y
CONFIG_HAVE_OBJTOOL_MCOUNT=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y
CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y
CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y

#
# x86 Debugging
#
# CONFIG_X86_VERBOSE_BOOTUP is not set
CONFIG_EARLY_PRINTK=y
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
CONFIG_IO_DELAY_0X80=y
# CONFIG_IO_DELAY_0XED is not set
# CONFIG_IO_DELAY_UDELAY is not set
# CONFIG_IO_DELAY_NONE is not set
CONFIG_UNWINDER_ORC=y
# CONFIG_UNWINDER_FRAME_POINTER is not set
# end of x86 Debugging

#
# Kernel Testing and Coverage
#
# CONFIG_KUNIT is not set
CONFIG_ARCH_HAS_KCOV=y
CONFIG_CC_HAS_SANCOV_TRACE_PC=y
# CONFIG_KCOV is not set
# CONFIG_RUNTIME_TESTING_MENU is not set
CONFIG_ARCH_USE_MEMTEST=y
# CONFIG_MEMTEST is not set
# end of Kernel Testing and Coverage

#
# Rust hacking
#
# end of Rust hacking

CONFIG_WARN_MISSING_DOCUMENTS=y
CONFIG_WARN_ABI_ERRORS=y
# end of Kernel hacking

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type
  2022-12-18 10:19 ` [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type Hyeonggon Yoo
  2022-12-18 19:32   ` kernel test robot
@ 2022-12-19  9:44   ` Andy Shevchenko
  2022-12-19 19:35     ` Randy Dunlap
  2022-12-20 15:20   ` Petr Mladek
  2 siblings, 1 reply; 25+ messages in thread
From: Andy Shevchenko @ 2022-12-19  9:44 UTC (permalink / raw)
  To: Hyeonggon Yoo
  Cc: Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Vlastimil Babka, Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也),
	Joe Perches, Petr Mladek, Matthew WilCox, David Hildenbrand,
	linux-mm, linux-kernel

On Sun, Dec 18, 2022 at 07:19:00PM +0900, Hyeonggon Yoo wrote:
> %pGp format is used to print 'flags' field of struct page.
> As some page flags (e.g. PG_buddy, see page-flags.h for more details)
> are set in page_type field, introduce %pGt format which provides
> human readable output of page_type.
> 
> Note that the sense of bits are different in page_type. if page_type is
> 0xffffffff, no flags are set. if PG_slab (0x00100000) flag is set,
> page_type is 0xffefffff. Clearing a bit means we set the bit.
> 
> Bits in page_type are inverted when printing page type names.

...

> +#define __def_pagetype_names						\
> +	{PG_slab,			"slab"		},		\
> +	{PG_offline,			"offline"	},		\
> +	{PG_guard,			"guard"		},		\
> +	{PG_table,			"table"		},		\
> +	{PG_buddy,			"buddy"		}

Wondering if it will be more robust to define a helper macro

#define DEF_PAGETYPE_NAME(_name)	{ PG_##_name, __stringify(_name) }
...
#undef DEF_PAGETYPE_MASK

In this case it decreases the chances of typo in the strings and flags.

-- 
With Best Regards,
Andy Shevchenko




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type
  2022-12-19  9:44   ` Andy Shevchenko
@ 2022-12-19 19:35     ` Randy Dunlap
  2022-12-20 10:58       ` Andy Shevchenko
  0 siblings, 1 reply; 25+ messages in thread
From: Randy Dunlap @ 2022-12-19 19:35 UTC (permalink / raw)
  To: Andy Shevchenko, Hyeonggon Yoo
  Cc: Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Vlastimil Babka, Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也), Joe Perches,
	Petr Mladek, Matthew WilCox, David Hildenbrand, linux-mm,
	linux-kernel



On 12/19/22 01:44, Andy Shevchenko wrote:
> On Sun, Dec 18, 2022 at 07:19:00PM +0900, Hyeonggon Yoo wrote:
>> %pGp format is used to print 'flags' field of struct page.
>> As some page flags (e.g. PG_buddy, see page-flags.h for more details)
>> are set in page_type field, introduce %pGt format which provides
>> human readable output of page_type.
>>
>> Note that the sense of bits are different in page_type. if page_type is
>> 0xffffffff, no flags are set. if PG_slab (0x00100000) flag is set,
>> page_type is 0xffefffff. Clearing a bit means we set the bit.
>>
>> Bits in page_type are inverted when printing page type names.
> 
> ...
> 
>> +#define __def_pagetype_names						\
>> +	{PG_slab,			"slab"		},		\
>> +	{PG_offline,			"offline"	},		\
>> +	{PG_guard,			"guard"		},		\
>> +	{PG_table,			"table"		},		\
>> +	{PG_buddy,			"buddy"		}
> 
> Wondering if it will be more robust to define a helper macro
> 
> #define DEF_PAGETYPE_NAME(_name)	{ PG_##_name, __stringify(_name) }
> ...
> #undef DEF_PAGETYPE_MASK
> 
> In this case it decreases the chances of typo in the strings and flags.

I'd say Yes.  (and #undef DEF_PAGETYPE_NAME methinks; or change both to _MASK)

-- 
~Randy


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type
  2022-12-19 19:35     ` Randy Dunlap
@ 2022-12-20 10:58       ` Andy Shevchenko
  2022-12-29 13:35         ` Hyeonggon Yoo
  0 siblings, 1 reply; 25+ messages in thread
From: Andy Shevchenko @ 2022-12-20 10:58 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Hyeonggon Yoo, Christoph Lameter, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Vlastimil Babka, Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也), Joe Perches,
	Petr Mladek, Matthew WilCox, David Hildenbrand, linux-mm,
	linux-kernel

On Mon, Dec 19, 2022 at 11:35:38AM -0800, Randy Dunlap wrote:
> On 12/19/22 01:44, Andy Shevchenko wrote:
> > On Sun, Dec 18, 2022 at 07:19:00PM +0900, Hyeonggon Yoo wrote:

...

> > #define DEF_PAGETYPE_NAME(_name)	{ PG_##_name, __stringify(_name) }
> > ...
> > #undef DEF_PAGETYPE_MASK
> > 
> > In this case it decreases the chances of typo in the strings and flags.
> 
> I'd say Yes.  (and #undef DEF_PAGETYPE_NAME methinks; or change both to _MASK)

Ah, it's me who used two different names for the same macro :-)

-- 
With Best Regards,
Andy Shevchenko




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type
  2022-12-18 10:19 ` [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type Hyeonggon Yoo
  2022-12-18 19:32   ` kernel test robot
  2022-12-19  9:44   ` Andy Shevchenko
@ 2022-12-20 15:20   ` Petr Mladek
  2022-12-29 13:30     ` Hyeonggon Yoo
  2 siblings, 1 reply; 25+ messages in thread
From: Petr Mladek @ 2022-12-20 15:20 UTC (permalink / raw)
  To: Hyeonggon Yoo
  Cc: Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Vlastimil Babka, Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也),
	Joe Perches, Andy Shevchenko, Matthew WilCox, David Hildenbrand,
	linux-mm, linux-kernel

On Sun 2022-12-18 19:19:00, Hyeonggon Yoo wrote:
> %pGp format is used to print 'flags' field of struct page.
> As some page flags (e.g. PG_buddy, see page-flags.h for more details)
> are set in page_type field, introduce %pGt format which provides
> human readable output of page_type.
> 
> Note that the sense of bits are different in page_type. if page_type is
> 0xffffffff, no flags are set. if PG_slab (0x00100000) flag is set,
> page_type is 0xffefffff. Clearing a bit means we set the bit.
> 
> Bits in page_type are inverted when printing page type names.
> 
> --- a/Documentation/core-api/printk-formats.rst
> +++ b/Documentation/core-api/printk-formats.rst
> @@ -575,12 +575,13 @@ The field width is passed by value, the bitmap is passed by reference.
>  Helper macros cpumask_pr_args() and nodemask_pr_args() are available to ease
>  printing cpumask and nodemask.
>  
> -Flags bitfields such as page flags, gfp_flags
> +Flags bitfields such as page flags, page_type, gfp_flags
>  ---------------------------------------------

Please, underline the entire title. Otherwise, "make htmldoc"
complains ;-)

    /prace/kernel/linux/Documentation/core-api/printk-formats.rst:579: WARNING: Title underline too short.
    Flags bitfields such as page flags, page_type, gfp_flags


>  
>  ::
>  
>  	%pGp	0x17ffffc0002036(referenced|uptodate|lru|active|private|node=0|zone=2|lastcpupid=0x1fffff)
> +	%pGt	0xffefffff(slab)
>  	%pGg	GFP_USER|GFP_DMA32|GFP_NOWARN
>  	%pGv	read|exec|mayread|maywrite|mayexec|denywrite
>  

Please, explain this also in the paragraph below these examples.
I would personally refactor it to an itemized list, something like:

<proposal>
For printing flags bitfields as a collection of symbolic constants that
would construct the value. The type of flags is given by the third
character. Currently supported are:

	- p - [p]age flags, expects value of type (``unsigned long *``)
	- t - page [t]ype, expects value of type (``unsigned int *``)
	- v - [v]ma_flags, expects value of type (``unsigned long *``)
	- g - [g]fp_flags, expects value of type (``gfp_t *``)

The flag names and print order depends on the particular type.
</proposal>

Rant:
Sigh, it looks a bit error prone when similar pointer modifiers
expects pointers to different types. I wish there was a way how
to check the passed pointer type at compilation time. But it
is generic problem with these %p* modifiers.


Otherwise the patch looks fine for the vsprinf side.

Best Regards,
Petr


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 1/4] mm/hwpoison: remove MF_MSG_SLAB from action_page_types
  2022-12-18 10:18 ` [RFC v3 1/4] mm/hwpoison: remove MF_MSG_SLAB from action_page_types Hyeonggon Yoo
@ 2022-12-20 23:53   ` HORIGUCHI NAOYA(堀口 直也)
  2022-12-21 17:00     ` Andy Shevchenko
  2022-12-29 13:17     ` Hyeonggon Yoo
  0 siblings, 2 replies; 25+ messages in thread
From: HORIGUCHI NAOYA(堀口 直也) @ 2022-12-20 23:53 UTC (permalink / raw)
  To: Hyeonggon Yoo
  Cc: Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Vlastimil Babka, Roman Gushchin, Joe Perches,
	Petr Mladek, Andy Shevchenko, Matthew WilCox, David Hildenbrand,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org

On Sun, Dec 18, 2022 at 07:18:58PM +0900, Hyeonggon Yoo wrote:
> As suggested by Naoya [1], identify_page_state() is never
> called when handling memory error on a slab page.
> 
> Clean this up before moving PG_slab flag to page_type in later patch.
> 
> [1] https://lore.kernel.org/linux-mm/Y2s+dnBsHAJu19ob@hyeyoo/#r
> 
> Suggested-by: Naoya Horiguchi <naoya.horiguchi@nec.com>
> Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>

Thank you for the patch,
I think there're a few other places to remove under include/.

  $ grep -inr MF_MSG_SLA include
  include/ras/ras_event.h:359:    EM ( MF_MSG_SLAB, "kernel slab page" )                          \
  include/linux/mm.h:3502:        MF_MSG_SLAB,

, so could you update them together?

Thanks,
Naoya Horiguchi

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 1/4] mm/hwpoison: remove MF_MSG_SLAB from action_page_types
  2022-12-20 23:53   ` HORIGUCHI NAOYA(堀口 直也)
@ 2022-12-21 17:00     ` Andy Shevchenko
  2022-12-29 13:18       ` Hyeonggon Yoo
  2022-12-29 13:17     ` Hyeonggon Yoo
  1 sibling, 1 reply; 25+ messages in thread
From: Andy Shevchenko @ 2022-12-21 17:00 UTC (permalink / raw)
  To: HORIGUCHI NAOYA(堀口 直也)
  Cc: Hyeonggon Yoo, Christoph Lameter, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Vlastimil Babka, Roman Gushchin,
	Joe Perches, Petr Mladek, Matthew WilCox, David Hildenbrand,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org

On Tue, Dec 20, 2022 at 11:53:11PM +0000, HORIGUCHI NAOYA(堀口 直也) wrote:
> On Sun, Dec 18, 2022 at 07:18:58PM +0900, Hyeonggon Yoo wrote:
> > As suggested by Naoya [1], identify_page_state() is never
> > called when handling memory error on a slab page.
> > 
> > Clean this up before moving PG_slab flag to page_type in later patch.

> > [1] https://lore.kernel.org/linux-mm/Y2s+dnBsHAJu19ob@hyeyoo/#r

You can make it to be a Link: tag.

-- 
With Best Regards,
Andy Shevchenko




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 1/4] mm/hwpoison: remove MF_MSG_SLAB from action_page_types
  2022-12-20 23:53   ` HORIGUCHI NAOYA(堀口 直也)
  2022-12-21 17:00     ` Andy Shevchenko
@ 2022-12-29 13:17     ` Hyeonggon Yoo
  1 sibling, 0 replies; 25+ messages in thread
From: Hyeonggon Yoo @ 2022-12-29 13:17 UTC (permalink / raw)
  To: HORIGUCHI NAOYA(堀口 直也)
  Cc: Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Vlastimil Babka, Roman Gushchin, Joe Perches,
	Petr Mladek, Andy Shevchenko, Matthew WilCox, David Hildenbrand,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org

On Tue, Dec 20, 2022 at 11:53:11PM +0000, HORIGUCHI NAOYA(堀口 直也) wrote:
> On Sun, Dec 18, 2022 at 07:18:58PM +0900, Hyeonggon Yoo wrote:
> > As suggested by Naoya [1], identify_page_state() is never
> > called when handling memory error on a slab page.
> > 
> > Clean this up before moving PG_slab flag to page_type in later patch.
> > 
> > [1] https://lore.kernel.org/linux-mm/Y2s+dnBsHAJu19ob@hyeyoo/#r
> > 
> > Suggested-by: Naoya Horiguchi <naoya.horiguchi@nec.com>
> > Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
> 
> Thank you for the patch,
> I think there're a few other places to remove under include/.
> 
>   $ grep -inr MF_MSG_SLA include
>   include/ras/ras_event.h:359:    EM ( MF_MSG_SLAB, "kernel slab page" )                          \
>   include/linux/mm.h:3502:        MF_MSG_SLAB,

> 
> , so could you update them together?

Oh, missed this. Will do in next version.

-- 
Thanks,
Hyeonggon


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 1/4] mm/hwpoison: remove MF_MSG_SLAB from action_page_types
  2022-12-21 17:00     ` Andy Shevchenko
@ 2022-12-29 13:18       ` Hyeonggon Yoo
  0 siblings, 0 replies; 25+ messages in thread
From: Hyeonggon Yoo @ 2022-12-29 13:18 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: HORIGUCHI NAOYA(堀口 直也),
	Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Vlastimil Babka, Roman Gushchin, Joe Perches,
	Petr Mladek, Matthew WilCox, David Hildenbrand,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org

On Wed, Dec 21, 2022 at 07:00:48PM +0200, Andy Shevchenko wrote:
> On Tue, Dec 20, 2022 at 11:53:11PM +0000, HORIGUCHI NAOYA(堀口 直也) wrote:
> > On Sun, Dec 18, 2022 at 07:18:58PM +0900, Hyeonggon Yoo wrote:
> > > As suggested by Naoya [1], identify_page_state() is never
> > > called when handling memory error on a slab page.
> > > 
> > > Clean this up before moving PG_slab flag to page_type in later patch.
> 
> > > [1] https://lore.kernel.org/linux-mm/Y2s+dnBsHAJu19ob@hyeyoo/#r
> 
> You can make it to be a Link: tag.

Will do in next version, thanks!

-- 
Thanks,
Hyeonggon


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type
  2022-12-20 15:20   ` Petr Mladek
@ 2022-12-29 13:30     ` Hyeonggon Yoo
  0 siblings, 0 replies; 25+ messages in thread
From: Hyeonggon Yoo @ 2022-12-29 13:30 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Vlastimil Babka, Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也),
	Joe Perches, Andy Shevchenko, Matthew WilCox, David Hildenbrand,
	linux-mm, linux-kernel

On Tue, Dec 20, 2022 at 04:20:26PM +0100, Petr Mladek wrote:
> On Sun 2022-12-18 19:19:00, Hyeonggon Yoo wrote:
> > %pGp format is used to print 'flags' field of struct page.
> > As some page flags (e.g. PG_buddy, see page-flags.h for more details)
> > are set in page_type field, introduce %pGt format which provides
> > human readable output of page_type.
> > 
> > Note that the sense of bits are different in page_type. if page_type is
> > 0xffffffff, no flags are set. if PG_slab (0x00100000) flag is set,
> > page_type is 0xffefffff. Clearing a bit means we set the bit.
> > 
> > Bits in page_type are inverted when printing page type names.
> > 
> > --- a/Documentation/core-api/printk-formats.rst
> > +++ b/Documentation/core-api/printk-formats.rst
> > @@ -575,12 +575,13 @@ The field width is passed by value, the bitmap is passed by reference.
> >  Helper macros cpumask_pr_args() and nodemask_pr_args() are available to ease
> >  printing cpumask and nodemask.
> >  
> > -Flags bitfields such as page flags, gfp_flags
> > +Flags bitfields such as page flags, page_type, gfp_flags
> >  ---------------------------------------------
> 
> Please, underline the entire title. Otherwise, "make htmldoc"
> complains ;-)
> 
>     /prace/kernel/linux/Documentation/core-api/printk-formats.rst:579: WARNING: Title underline too short.
>     Flags bitfields such as page flags, page_type, gfp_flags

Still not getting used to rst format ;)
Will fix, thanks!

> 
> 
> >  
> >  ::
> >  
> >  	%pGp	0x17ffffc0002036(referenced|uptodate|lru|active|private|node=0|zone=2|lastcpupid=0x1fffff)
> > +	%pGt	0xffefffff(slab)
> >  	%pGg	GFP_USER|GFP_DMA32|GFP_NOWARN
> >  	%pGv	read|exec|mayread|maywrite|mayexec|denywrite
> >  
> 
> Please, explain this also in the paragraph below these examples.
> I would personally refactor it to an itemized list, something like:
> 
> <proposal>
> For printing flags bitfields as a collection of symbolic constants that
> would construct the value. The type of flags is given by the third
> character. Currently supported are:
> 
> 	- p - [p]age flags, expects value of type (``unsigned long *``)
> 	- t - page [t]ype, expects value of type (``unsigned int *``)
> 	- v - [v]ma_flags, expects value of type (``unsigned long *``)
> 	- g - [g]fp_flags, expects value of type (``gfp_t *``)
> 
> The flag names and print order depends on the particular type.
> </proposal>

The proposal sounds reasonable to me,
will adjust in next version.

> Rant:
> Sigh, it looks a bit error prone when similar pointer modifiers
> expects pointers to different types. I wish there was a way how
> to check the passed pointer type at compilation time. But it
> is generic problem with these %p* modifiers.

From my limited knowledge, it seems that there is no way to check
this :/

> 
> Otherwise the patch looks fine for the vsprinf side.

Thank you for looking at this!

> 
> Best Regards,
> Petr

-- 
Thanks,
Hyeonggon


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type
  2022-12-20 10:58       ` Andy Shevchenko
@ 2022-12-29 13:35         ` Hyeonggon Yoo
  0 siblings, 0 replies; 25+ messages in thread
From: Hyeonggon Yoo @ 2022-12-29 13:35 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Randy Dunlap, Christoph Lameter, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Vlastimil Babka, Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也), Joe Perches,
	Petr Mladek, Matthew WilCox, David Hildenbrand, linux-mm,
	linux-kernel

On Tue, Dec 20, 2022 at 12:58:53PM +0200, Andy Shevchenko wrote:
> On Mon, Dec 19, 2022 at 11:35:38AM -0800, Randy Dunlap wrote:
> > On 12/19/22 01:44, Andy Shevchenko wrote:
> > > On Sun, Dec 18, 2022 at 07:19:00PM +0900, Hyeonggon Yoo wrote:
> 
> ...
> 
> > > #define DEF_PAGETYPE_NAME(_name)	{ PG_##_name, __stringify(_name) }
> > > ...
> > > #undef DEF_PAGETYPE_MASK
> > > 
> > > In this case it decreases the chances of typo in the strings and flags.
> > 
> > I'd say Yes.  (and #undef DEF_PAGETYPE_NAME methinks; or change both to _MASK)
> 
> Ah, it's me who used two different names for the same macro :-)

It seems like a good way to make fewer mistakes.
Will do in next version, thanks! :-)

-- 
Thanks,
Hyeonggon


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 2/4] mm: move PG_slab flag to page_type
  2022-12-18 10:18 ` [RFC v3 2/4] mm: move PG_slab flag to page_type Hyeonggon Yoo
@ 2023-01-12 16:27   ` Vlastimil Babka
  2023-01-30  4:34     ` Hyeonggon Yoo
  0 siblings, 1 reply; 25+ messages in thread
From: Vlastimil Babka @ 2023-01-12 16:27 UTC (permalink / raw)
  To: Hyeonggon Yoo, Christoph Lameter, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Roman Gushchin
  Cc: HORIGUCHI NAOYA(堀口 直也), Joe Perches,
	Petr Mladek, Andy Shevchenko, Matthew WilCox, David Hildenbrand,
	linux-mm, linux-kernel, Alexander Potapenko, Marco Elver

On 12/18/22 11:18, Hyeonggon Yoo wrote:
> For now, only SLAB uses _mapcount field as a number of active objects in
> a slab, and other slab allocators do not. As 16 bits are enough for that,
> use remaining 16 bits of _mapcount as page_type even when SLAB is used.
> And then move PG_slab flag to page_type.
> 
> As suggested by Matthew, store number of active objects in negative
> form and use helper when accessing or modifying it.
> 
> page_type is always placed in upper half of _mapcount to avoid
> confusing normal _mapcount as page_type. As underflow (actually I mean,
> yeah, overflow) is not a concern anymore, use more lower bits.
> 
> Add more folio helpers for PAGE_TYPE_OPS() not to break existing
> slab implementations. To preserve current behavior apply page policy
> in PAGE_TYPE_OPS() and use PF_NO_TAIL for slab pages and PF_ANY for others.
> 
> Remove PG_slab check from PAGE_FLAGS_CHECK_AT_FREE. buddy will still
> check if _mapcount is properly set at free.
> 
> Note that with this change, page_mapped() and folio_mapped() always return
> false for a slab page.
> 
> Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>

Seems like quite some changes to page_type to accomodate SLAB, which is
hopefully going away soon(TM). Could we perhaps avoid that?

- Alternative 1: convert only SLUB for now, let SLAB keep using PG_slab
until it's gone.

- Alternative 2: SLAB's s_mem field seems wasteful to be a full blown
pointer, it could share the word with "active" if it was an offset from
page_addr(), see how it's normally set up:

void *addr = slab_address(slab);
slab->s_mem = addr + colour_off;

so basically we would store the colour_off and perform this calculation
on-demand.

One caveat is KFENCE's kfence_guarded_alloc() which seems to be creating
some fake slab? And setting s_mem to something that maybe isn't an offset up
to 16 bits from slab_address(). That has to be investigated. Worst case,
SLAB is going away soon(TM) so it's fine if KFENCE only works with SLUB?

> ---
>  fs/proc/page.c                 | 13 ++----
>  include/linux/mm_types.h       | 11 +++--
>  include/linux/page-flags.h     | 77 ++++++++++++++++++++++++----------
>  include/trace/events/mmflags.h |  1 -
>  kernel/crash_core.c            |  3 +-
>  mm/slab.c                      | 44 ++++++++++++-------
>  mm/slab.h                      |  3 +-
>  7 files changed, 98 insertions(+), 54 deletions(-)
> 
> diff --git a/fs/proc/page.c b/fs/proc/page.c
> index 6249c347809a..e7524f21cefe 100644
> --- a/fs/proc/page.c
> +++ b/fs/proc/page.c
> @@ -67,7 +67,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
>  		 */
>  		ppage = pfn_to_online_page(pfn);
>  
> -		if (!ppage || PageSlab(ppage) || page_has_type(ppage))
> +		if (!ppage || page_has_type(ppage))
>  			pcount = 0;
>  		else
>  			pcount = page_mapcount(ppage);
> @@ -124,11 +124,8 @@ u64 stable_page_flags(struct page *page)
>  
>  	/*
>  	 * pseudo flags for the well known (anonymous) memory mapped pages
> -	 *
> -	 * Note that page->_mapcount is overloaded in SLOB/SLUB/SLQB, so the
> -	 * simple test in page_mapped() is not enough.
>  	 */
> -	if (!PageSlab(page) && page_mapped(page))
> +	if (page_mapped(page))
>  		u |= 1 << KPF_MMAP;
>  	if (PageAnon(page))
>  		u |= 1 << KPF_ANON;
> @@ -178,16 +175,14 @@ u64 stable_page_flags(struct page *page)
>  		u |= 1 << KPF_OFFLINE;
>  	if (PageTable(page))
>  		u |= 1 << KPF_PGTABLE;
> +	if (PageSlab(page))
> +		u |= 1 << KPF_SLAB;
>  
>  	if (page_is_idle(page))
>  		u |= 1 << KPF_IDLE;
>  
>  	u |= kpf_copy_bit(k, KPF_LOCKED,	PG_locked);
>  
> -	u |= kpf_copy_bit(k, KPF_SLAB,		PG_slab);
> -	if (PageTail(page) && PageSlab(compound_head(page)))
> -		u |= 1 << KPF_SLAB;
> -
>  	u |= kpf_copy_bit(k, KPF_ERROR,		PG_error);
>  	u |= kpf_copy_bit(k, KPF_DIRTY,		PG_dirty);
>  	u |= kpf_copy_bit(k, KPF_UPTODATE,	PG_uptodate);
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 3b8475007734..6b04ae65241d 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -207,10 +207,13 @@ struct page {
>  		atomic_t _mapcount;
>  
>  		/*
> -		 * If the page is neither PageSlab nor mappable to userspace,
> -		 * the value stored here may help determine what this page
> -		 * is used for.  See page-flags.h for a list of page types
> -		 * which are currently stored here.
> +		 * If the page is not mappable to userspace, the value
> +		 * stored here may help determine what this page is used for.
> +		 * See page-flags.h for a list of page types which are currently
> +		 * stored here.
> +		 *
> +		 * Note that only upper half is used for page types and lower
> +		 * half is reserved for SLAB.
>  		 */
>  		unsigned int page_type;
>  	};
> diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
> index 69e93a0c1277..07063d60efe3 100644
> --- a/include/linux/page-flags.h
> +++ b/include/linux/page-flags.h
> @@ -107,7 +107,6 @@ enum pageflags {
>  	PG_workingset,
>  	PG_waiters,		/* Page has waiters, check its waitqueue. Must be bit #7 and in the same byte as "PG_locked" */
>  	PG_error,
> -	PG_slab,
>  	PG_owner_priv_1,	/* Owner use. If pagecache, fs may use*/
>  	PG_arch_1,
>  	PG_reserved,
> @@ -482,7 +481,6 @@ PAGEFLAG(Active, active, PF_HEAD) __CLEARPAGEFLAG(Active, active, PF_HEAD)
>  	TESTCLEARFLAG(Active, active, PF_HEAD)
>  PAGEFLAG(Workingset, workingset, PF_HEAD)
>  	TESTCLEARFLAG(Workingset, workingset, PF_HEAD)
> -__PAGEFLAG(Slab, slab, PF_NO_TAIL)
>  __PAGEFLAG(SlobFree, slob_free, PF_NO_TAIL)
>  PAGEFLAG(Checked, checked, PF_NO_COMPOUND)	   /* Used by some filesystems */
>  
> @@ -906,42 +904,72 @@ static inline bool is_page_hwpoison(struct page *page)
>  }
>  
>  /*
> - * For pages that are never mapped to userspace (and aren't PageSlab),
> - * page_type may be used.  Because it is initialised to -1, we invert the
> - * sense of the bit, so __SetPageFoo *clears* the bit used for PageFoo, and
> - * __ClearPageFoo *sets* the bit used for PageFoo.  We reserve a few high and
> - * low bits so that an underflow or overflow of page_mapcount() won't be
> - * mistaken for a page type value.
> + * For pages that are never mapped to userspace, page_type may be used.
> + * Because it is initialised to -1, we invert the sense of the bit,
> + * so __SetPageFoo *clears* the bit used for PageFoo, and __ClearPageFoo
> + * *sets* the bit used for PageFoo.  We reserve a few high and low bits
> + * so that an underflow or overflow of page_mapcount() won't be mistaken
> + * for a page type value.
>   */
>  
>  #define PAGE_TYPE_BASE	0xf0000000
> -/* Reserve		0x0000007f to catch underflows of page_mapcount */
> -#define PAGE_MAPCOUNT_RESERVE	-128
> -#define PG_buddy	0x00000080
> -#define PG_offline	0x00000100
> -#define PG_table	0x00000200
> -#define PG_guard	0x00000400
> +#define PG_buddy	0x00010000
> +#define PG_offline	0x00020000
> +#define PG_table	0x00040000
> +#define PG_guard	0x00080000
> +#define PG_slab		0x00100000
>  
>  #define PageType(page, flag)						\
>  	((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE)
>  
> -static inline int page_has_type(struct page *page)
> +#define PAGE_TYPE_MASK	0xffff0000
> +
> +static inline bool page_type_has_type(unsigned int page_type)
>  {
> -	return (int)page->page_type < PAGE_MAPCOUNT_RESERVE;
> +	return ((int)page_type < (int)PAGE_TYPE_MASK);
>  }
>  
> -#define PAGE_TYPE_OPS(uname, lname)					\
> +static inline bool page_has_type(struct page *page)
> +{
> +	return page_type_has_type(page->page_type);
> +}
> +
> +
> +#define PAGE_TYPE_OPS(uname, lname, policy)				\
>  static __always_inline int Page##uname(struct page *page)		\
>  {									\
> +	page = policy(page, 0);						\
> +	return PageType(page, PG_##lname);				\
> +}									\
> +static __always_inline int folio_test_##lname(struct folio *folio)	\
> +{									\
> +	struct page *page = &folio->page;				\
> +									\
>  	return PageType(page, PG_##lname);				\
>  }									\
>  static __always_inline void __SetPage##uname(struct page *page)		\
>  {									\
> +	page = policy(page, 1);						\
> +	VM_BUG_ON_PAGE(!PageType(page, 0), page);			\
> +	page->page_type &= ~PG_##lname;					\
> +}									\
> +static __always_inline void __folio_set_##lname(struct folio *folio)	\
> +{									\
> +	struct page *page = &folio->page;				\
> +									\
>  	VM_BUG_ON_PAGE(!PageType(page, 0), page);			\
>  	page->page_type &= ~PG_##lname;					\
>  }									\
>  static __always_inline void __ClearPage##uname(struct page *page)	\
>  {									\
> +	page = policy(page, 1);						\
> +	VM_BUG_ON_PAGE(!Page##uname(page), page);			\
> +	page->page_type |= PG_##lname;					\
> +}									\
> +static __always_inline void __folio_clear_##lname(struct folio *folio)	\
> +{									\
> +	struct page *page = &folio->page;				\
> +									\
>  	VM_BUG_ON_PAGE(!Page##uname(page), page);			\
>  	page->page_type |= PG_##lname;					\
>  }
> @@ -950,7 +978,7 @@ static __always_inline void __ClearPage##uname(struct page *page)	\
>   * 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, PF_ANY)
>  
>  /*
>   * PageOffline() indicates that the page is logically offline although the
> @@ -974,7 +1002,10 @@ 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, PF_ANY)
> +
> +/* PageSlab() indicates that the page is used by slab subsystem. */
> +PAGE_TYPE_OPS(Slab, slab, PF_NO_TAIL)
>  
>  extern void page_offline_freeze(void);
>  extern void page_offline_thaw(void);
> @@ -984,12 +1015,12 @@ extern void page_offline_end(void);
>  /*
>   * Marks pages in use as page tables.
>   */
> -PAGE_TYPE_OPS(Table, table)
> +PAGE_TYPE_OPS(Table, table, PF_ANY)
>  
>  /*
>   * Marks guardpages used with debug_pagealloc.
>   */
> -PAGE_TYPE_OPS(Guard, guard)
> +PAGE_TYPE_OPS(Guard, guard, PF_ANY)
>  
>  extern bool is_free_buddy_page(struct page *page);
>  
> @@ -1037,8 +1068,8 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page)
>  	(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 | LRU_GEN_MASK)
> +	 1UL << PG_active 	| 1UL << PG_unevictable |	\
> +	 __PG_MLOCKED | LRU_GEN_MASK)
>  
>  /*
>   * Flags checked when a page is prepped for return by the page allocator.
> diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
> index 412b5a46374c..8301912f8c25 100644
> --- a/include/trace/events/mmflags.h
> +++ b/include/trace/events/mmflags.h
> @@ -113,7 +113,6 @@
>  	{1UL << PG_lru,			"lru"		},		\
>  	{1UL << PG_active,		"active"	},		\
>  	{1UL << PG_workingset,		"workingset"	},		\
> -	{1UL << PG_slab,		"slab"		},		\
>  	{1UL << PG_owner_priv_1,	"owner_priv_1"	},		\
>  	{1UL << PG_arch_1,		"arch_1"	},		\
>  	{1UL << PG_reserved,		"reserved"	},		\
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 87ef6096823f..1ea8198c26e1 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -482,13 +482,14 @@ static int __init crash_save_vmcoreinfo_init(void)
>  	VMCOREINFO_NUMBER(PG_private);
>  	VMCOREINFO_NUMBER(PG_swapcache);
>  	VMCOREINFO_NUMBER(PG_swapbacked);
> -	VMCOREINFO_NUMBER(PG_slab);
>  #ifdef CONFIG_MEMORY_FAILURE
>  	VMCOREINFO_NUMBER(PG_hwpoison);
>  #endif
>  	VMCOREINFO_NUMBER(PG_head_mask);
>  #define PAGE_BUDDY_MAPCOUNT_VALUE	(~PG_buddy)
>  	VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
> +#define PAGE_SLAB_MAPCOUNT_VALUE	(~PG_slab)
> +	VMCOREINFO_NUMBER(PAGE_SLAB_MAPCOUNT_VALUE);
>  #ifdef CONFIG_HUGETLB_PAGE
>  	VMCOREINFO_NUMBER(HUGETLB_PAGE_DTOR);
>  #define PAGE_OFFLINE_MAPCOUNT_VALUE	(~PG_offline)
> diff --git a/mm/slab.c b/mm/slab.c
> index 7a269db050ee..eee46f71c4b8 100644
> --- a/mm/slab.c
> +++ b/mm/slab.c
> @@ -2269,6 +2269,21 @@ void __kmem_cache_release(struct kmem_cache *cachep)
>  	}
>  }
>  
> +static inline unsigned int slab_get_active(struct slab *slab)
> +{
> +	return ~(slab->page_type | PG_slab);
> +}
> +
> +static inline void slab_inc_active(struct slab *slab)
> +{
> +	slab->page_type--;
> +}
> +
> +static inline void slab_dec_active(struct slab *slab)
> +{
> +	slab->page_type++;
> +}
> +
>  /*
>   * Get the memory for a slab management obj.
>   *
> @@ -2291,7 +2306,6 @@ static void *alloc_slabmgmt(struct kmem_cache *cachep,
>  	void *addr = slab_address(slab);
>  
>  	slab->s_mem = addr + colour_off;
> -	slab->active = 0;
>  
>  	if (OBJFREELIST_SLAB(cachep))
>  		freelist = NULL;
> @@ -2510,8 +2524,8 @@ static void *slab_get_obj(struct kmem_cache *cachep, struct slab *slab)
>  {
>  	void *objp;
>  
> -	objp = index_to_obj(cachep, slab, get_free_obj(slab, slab->active));
> -	slab->active++;
> +	objp = index_to_obj(cachep, slab, get_free_obj(slab, slab_get_active(slab)));
> +	slab_inc_active(slab);
>  
>  	return objp;
>  }
> @@ -2524,7 +2538,7 @@ static void slab_put_obj(struct kmem_cache *cachep,
>  	unsigned int i;
>  
>  	/* Verify double free bug */
> -	for (i = slab->active; i < cachep->num; i++) {
> +	for (i = slab_get_active(slab); i < cachep->num; i++) {
>  		if (get_free_obj(slab, i) == objnr) {
>  			pr_err("slab: double free detected in cache '%s', objp %px\n",
>  			       cachep->name, objp);
> @@ -2532,11 +2546,11 @@ static void slab_put_obj(struct kmem_cache *cachep,
>  		}
>  	}
>  #endif
> -	slab->active--;
> +	slab_dec_active(slab);
>  	if (!slab->freelist)
>  		slab->freelist = objp + obj_offset(cachep);
>  
> -	set_free_obj(slab, slab->active, objnr);
> +	set_free_obj(slab, slab_get_active(slab), objnr);
>  }
>  
>  /*
> @@ -2635,14 +2649,14 @@ static void cache_grow_end(struct kmem_cache *cachep, struct slab *slab)
>  
>  	raw_spin_lock(&n->list_lock);
>  	n->total_slabs++;
> -	if (!slab->active) {
> +	if (!slab_get_active(slab)) {
>  		list_add_tail(&slab->slab_list, &n->slabs_free);
>  		n->free_slabs++;
>  	} else
>  		fixup_slab_list(cachep, n, slab, &list);
>  
>  	STATS_INC_GROWN(cachep);
> -	n->free_objects += cachep->num - slab->active;
> +	n->free_objects += cachep->num - slab_get_active(slab);
>  	raw_spin_unlock(&n->list_lock);
>  
>  	fixup_objfreelist_debug(cachep, &list);
> @@ -2744,7 +2758,7 @@ static inline void fixup_slab_list(struct kmem_cache *cachep,
>  {
>  	/* move slabp to correct slabp list: */
>  	list_del(&slab->slab_list);
> -	if (slab->active == cachep->num) {
> +	if (slab_get_active(slab) == cachep->num) {
>  		list_add(&slab->slab_list, &n->slabs_full);
>  		if (OBJFREELIST_SLAB(cachep)) {
>  #if DEBUG
> @@ -2783,7 +2797,7 @@ static noinline struct slab *get_valid_first_slab(struct kmem_cache_node *n,
>  
>  	/* Move pfmemalloc slab to the end of list to speed up next search */
>  	list_del(&slab->slab_list);
> -	if (!slab->active) {
> +	if (!slab_get_active(slab)) {
>  		list_add_tail(&slab->slab_list, &n->slabs_free);
>  		n->free_slabs++;
>  	} else
> @@ -2865,9 +2879,9 @@ static __always_inline int alloc_block(struct kmem_cache *cachep,
>  	 * There must be at least one object available for
>  	 * allocation.
>  	 */
> -	BUG_ON(slab->active >= cachep->num);
> +	BUG_ON(slab_get_active(slab) >= cachep->num);
>  
> -	while (slab->active < cachep->num && batchcount--) {
> +	while (slab_get_active(slab) < cachep->num && batchcount--) {
>  		STATS_INC_ALLOCED(cachep);
>  		STATS_INC_ACTIVE(cachep);
>  		STATS_SET_HIGH(cachep);
> @@ -3162,7 +3176,7 @@ static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags,
>  	STATS_INC_ACTIVE(cachep);
>  	STATS_SET_HIGH(cachep);
>  
> -	BUG_ON(slab->active == cachep->num);
> +	BUG_ON(slab_get_active(slab) == cachep->num);
>  
>  	obj = slab_get_obj(cachep, slab);
>  	n->free_objects--;
> @@ -3297,7 +3311,7 @@ static void free_block(struct kmem_cache *cachep, void **objpp,
>  		STATS_DEC_ACTIVE(cachep);
>  
>  		/* fixup slab chains */
> -		if (slab->active == 0) {
> +		if (slab_get_active(slab) == 0) {
>  			list_add(&slab->slab_list, &n->slabs_free);
>  			n->free_slabs++;
>  		} else {
> @@ -3352,7 +3366,7 @@ static void cache_flusharray(struct kmem_cache *cachep, struct array_cache *ac)
>  		struct slab *slab;
>  
>  		list_for_each_entry(slab, &n->slabs_free, slab_list) {
> -			BUG_ON(slab->active);
> +			BUG_ON(slab_get_active(slab));
>  
>  			i++;
>  		}
> diff --git a/mm/slab.h b/mm/slab.h
> index 7cc432969945..c6ffe6799436 100644
> --- a/mm/slab.h
> +++ b/mm/slab.h
> @@ -20,7 +20,8 @@ struct slab {
>  		};
>  		struct rcu_head rcu_head;
>  	};
> -	unsigned int active;
> +	/* lower half of page_type is used as active objects counter */
> +	unsigned int page_type;
>  
>  #elif defined(CONFIG_SLUB)
>  



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 2/4] mm: move PG_slab flag to page_type
  2023-01-12 16:27   ` Vlastimil Babka
@ 2023-01-30  4:34     ` Hyeonggon Yoo
  2023-01-30  5:11       ` Matthew Wilcox
  0 siblings, 1 reply; 25+ messages in thread
From: Hyeonggon Yoo @ 2023-01-30  4:34 UTC (permalink / raw)
  To: Vlastimil Babka
  Cc: Christoph Lameter, Pekka Enberg, David Rientjes, Joonsoo Kim,
	Andrew Morton, Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也), Joe Perches,
	Petr Mladek, Andy Shevchenko, Matthew WilCox, David Hildenbrand,
	linux-mm, linux-kernel, Alexander Potapenko, Marco Elver

On Thu, Jan 12, 2023 at 05:27:24PM +0100, Vlastimil Babka wrote:
> On 12/18/22 11:18, Hyeonggon Yoo wrote:
> > For now, only SLAB uses _mapcount field as a number of active objects in
> > a slab, and other slab allocators do not. As 16 bits are enough for that,
> > use remaining 16 bits of _mapcount as page_type even when SLAB is used.
> > And then move PG_slab flag to page_type.
> > 
> > As suggested by Matthew, store number of active objects in negative
> > form and use helper when accessing or modifying it.
> > 
> > page_type is always placed in upper half of _mapcount to avoid
> > confusing normal _mapcount as page_type. As underflow (actually I mean,
> > yeah, overflow) is not a concern anymore, use more lower bits.
> > 
> > Add more folio helpers for PAGE_TYPE_OPS() not to break existing
> > slab implementations. To preserve current behavior apply page policy
> > in PAGE_TYPE_OPS() and use PF_NO_TAIL for slab pages and PF_ANY for others.
> > 
> > Remove PG_slab check from PAGE_FLAGS_CHECK_AT_FREE. buddy will still
> > check if _mapcount is properly set at free.
> > 
> > Note that with this change, page_mapped() and folio_mapped() always return
> > false for a slab page.
> > 
> > Signed-off-by: Hyeonggon Yoo <42.hyeyoo@gmail.com>
> 
> Seems like quite some changes to page_type to accomodate SLAB, which is
> hopefully going away soon(TM). Could we perhaps avoid that?

If it could be done with less changes, I'll try to avoid that.

>
> - Alternative 1: convert only SLUB for now, let SLAB keep using PG_slab
> until it's gone.
> 
> - Alternative 2: SLAB's s_mem field seems wasteful to be a full blown
> pointer, it could share the word with "active" if it was an offset from
> page_addr(), see how it's normally set up:
> 
> void *addr = slab_address(slab);
> slab->s_mem = addr + colour_off;
> 
> so basically we would store the colour_off and perform this calculation
> on-demand.

Thank you for suggestions, I prefer the latter approach.
Will refresh with that.

By the way, I think printk part is already ready so I sent this first.
( https://lore.kernel.org/linux-mm/20230130042514.2418-1-42.hyeyoo@gmail.com )

> One caveat is KFENCE's kfence_guarded_alloc() which seems to be creating
> some fake slab? And setting s_mem to something that maybe isn't an offset up
> to 16 bits from slab_address(). That has to be investigated. Worst case,
> SLAB is going away soon(TM) so it's fine if KFENCE only works with SLUB?

Will investigate, but if SLAB is going away anyway I guess that would be
okay.

> > ---
> >  fs/proc/page.c                 | 13 ++----
> >  include/linux/mm_types.h       | 11 +++--
> >  include/linux/page-flags.h     | 77 ++++++++++++++++++++++++----------
> >  include/trace/events/mmflags.h |  1 -
> >  kernel/crash_core.c            |  3 +-
> >  mm/slab.c                      | 44 ++++++++++++-------
> >  mm/slab.h                      |  3 +-
> >  7 files changed, 98 insertions(+), 54 deletions(-)
> > 
> > diff --git a/fs/proc/page.c b/fs/proc/page.c
> > index 6249c347809a..e7524f21cefe 100644
> > --- a/fs/proc/page.c
> > +++ b/fs/proc/page.c
> > @@ -67,7 +67,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
> >  		 */
> >  		ppage = pfn_to_online_page(pfn);
> >  
> > -		if (!ppage || PageSlab(ppage) || page_has_type(ppage))
> > +		if (!ppage || page_has_type(ppage))
> >  			pcount = 0;
> >  		else
> >  			pcount = page_mapcount(ppage);
> > @@ -124,11 +124,8 @@ u64 stable_page_flags(struct page *page)
> >  
> >  	/*
> >  	 * pseudo flags for the well known (anonymous) memory mapped pages
> > -	 *
> > -	 * Note that page->_mapcount is overloaded in SLOB/SLUB/SLQB, so the
> > -	 * simple test in page_mapped() is not enough.
> >  	 */
> > -	if (!PageSlab(page) && page_mapped(page))
> > +	if (page_mapped(page))
> >  		u |= 1 << KPF_MMAP;
> >  	if (PageAnon(page))
> >  		u |= 1 << KPF_ANON;
> > @@ -178,16 +175,14 @@ u64 stable_page_flags(struct page *page)
> >  		u |= 1 << KPF_OFFLINE;
> >  	if (PageTable(page))
> >  		u |= 1 << KPF_PGTABLE;
> > +	if (PageSlab(page))
> > +		u |= 1 << KPF_SLAB;
> >  
> >  	if (page_is_idle(page))
> >  		u |= 1 << KPF_IDLE;
> >  
> >  	u |= kpf_copy_bit(k, KPF_LOCKED,	PG_locked);
> >  
> > -	u |= kpf_copy_bit(k, KPF_SLAB,		PG_slab);
> > -	if (PageTail(page) && PageSlab(compound_head(page)))
> > -		u |= 1 << KPF_SLAB;
> > -
> >  	u |= kpf_copy_bit(k, KPF_ERROR,		PG_error);
> >  	u |= kpf_copy_bit(k, KPF_DIRTY,		PG_dirty);
> >  	u |= kpf_copy_bit(k, KPF_UPTODATE,	PG_uptodate);
> > diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> > index 3b8475007734..6b04ae65241d 100644
> > --- a/include/linux/mm_types.h
> > +++ b/include/linux/mm_types.h
> > @@ -207,10 +207,13 @@ struct page {
> >  		atomic_t _mapcount;
> >  
> >  		/*
> > -		 * If the page is neither PageSlab nor mappable to userspace,
> > -		 * the value stored here may help determine what this page
> > -		 * is used for.  See page-flags.h for a list of page types
> > -		 * which are currently stored here.
> > +		 * If the page is not mappable to userspace, the value
> > +		 * stored here may help determine what this page is used for.
> > +		 * See page-flags.h for a list of page types which are currently
> > +		 * stored here.
> > +		 *
> > +		 * Note that only upper half is used for page types and lower
> > +		 * half is reserved for SLAB.
> >  		 */
> >  		unsigned int page_type;
> >  	};
> > diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
> > index 69e93a0c1277..07063d60efe3 100644
> > --- a/include/linux/page-flags.h
> > +++ b/include/linux/page-flags.h
> > @@ -107,7 +107,6 @@ enum pageflags {
> >  	PG_workingset,
> >  	PG_waiters,		/* Page has waiters, check its waitqueue. Must be bit #7 and in the same byte as "PG_locked" */
> >  	PG_error,
> > -	PG_slab,
> >  	PG_owner_priv_1,	/* Owner use. If pagecache, fs may use*/
> >  	PG_arch_1,
> >  	PG_reserved,
> > @@ -482,7 +481,6 @@ PAGEFLAG(Active, active, PF_HEAD) __CLEARPAGEFLAG(Active, active, PF_HEAD)
> >  	TESTCLEARFLAG(Active, active, PF_HEAD)
> >  PAGEFLAG(Workingset, workingset, PF_HEAD)
> >  	TESTCLEARFLAG(Workingset, workingset, PF_HEAD)
> > -__PAGEFLAG(Slab, slab, PF_NO_TAIL)
> >  __PAGEFLAG(SlobFree, slob_free, PF_NO_TAIL)
> >  PAGEFLAG(Checked, checked, PF_NO_COMPOUND)	   /* Used by some filesystems */
> >  
> > @@ -906,42 +904,72 @@ static inline bool is_page_hwpoison(struct page *page)
> >  }
> >  
> >  /*
> > - * For pages that are never mapped to userspace (and aren't PageSlab),
> > - * page_type may be used.  Because it is initialised to -1, we invert the
> > - * sense of the bit, so __SetPageFoo *clears* the bit used for PageFoo, and
> > - * __ClearPageFoo *sets* the bit used for PageFoo.  We reserve a few high and
> > - * low bits so that an underflow or overflow of page_mapcount() won't be
> > - * mistaken for a page type value.
> > + * For pages that are never mapped to userspace, page_type may be used.
> > + * Because it is initialised to -1, we invert the sense of the bit,
> > + * so __SetPageFoo *clears* the bit used for PageFoo, and __ClearPageFoo
> > + * *sets* the bit used for PageFoo.  We reserve a few high and low bits
> > + * so that an underflow or overflow of page_mapcount() won't be mistaken
> > + * for a page type value.
> >   */
> >  
> >  #define PAGE_TYPE_BASE	0xf0000000
> > -/* Reserve		0x0000007f to catch underflows of page_mapcount */
> > -#define PAGE_MAPCOUNT_RESERVE	-128
> > -#define PG_buddy	0x00000080
> > -#define PG_offline	0x00000100
> > -#define PG_table	0x00000200
> > -#define PG_guard	0x00000400
> > +#define PG_buddy	0x00010000
> > +#define PG_offline	0x00020000
> > +#define PG_table	0x00040000
> > +#define PG_guard	0x00080000
> > +#define PG_slab		0x00100000
> >  
> >  #define PageType(page, flag)						\
> >  	((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE)
> >  
> > -static inline int page_has_type(struct page *page)
> > +#define PAGE_TYPE_MASK	0xffff0000
> > +
> > +static inline bool page_type_has_type(unsigned int page_type)
> >  {
> > -	return (int)page->page_type < PAGE_MAPCOUNT_RESERVE;
> > +	return ((int)page_type < (int)PAGE_TYPE_MASK);
> >  }
> >  
> > -#define PAGE_TYPE_OPS(uname, lname)					\
> > +static inline bool page_has_type(struct page *page)
> > +{
> > +	return page_type_has_type(page->page_type);
> > +}
> > +
> > +
> > +#define PAGE_TYPE_OPS(uname, lname, policy)				\
> >  static __always_inline int Page##uname(struct page *page)		\
> >  {									\
> > +	page = policy(page, 0);						\
> > +	return PageType(page, PG_##lname);				\
> > +}									\
> > +static __always_inline int folio_test_##lname(struct folio *folio)	\
> > +{									\
> > +	struct page *page = &folio->page;				\
> > +									\
> >  	return PageType(page, PG_##lname);				\
> >  }									\
> >  static __always_inline void __SetPage##uname(struct page *page)		\
> >  {									\
> > +	page = policy(page, 1);						\
> > +	VM_BUG_ON_PAGE(!PageType(page, 0), page);			\
> > +	page->page_type &= ~PG_##lname;					\
> > +}									\
> > +static __always_inline void __folio_set_##lname(struct folio *folio)	\
> > +{									\
> > +	struct page *page = &folio->page;				\
> > +									\
> >  	VM_BUG_ON_PAGE(!PageType(page, 0), page);			\
> >  	page->page_type &= ~PG_##lname;					\
> >  }									\
> >  static __always_inline void __ClearPage##uname(struct page *page)	\
> >  {									\
> > +	page = policy(page, 1);						\
> > +	VM_BUG_ON_PAGE(!Page##uname(page), page);			\
> > +	page->page_type |= PG_##lname;					\
> > +}									\
> > +static __always_inline void __folio_clear_##lname(struct folio *folio)	\
> > +{									\
> > +	struct page *page = &folio->page;				\
> > +									\
> >  	VM_BUG_ON_PAGE(!Page##uname(page), page);			\
> >  	page->page_type |= PG_##lname;					\
> >  }
> > @@ -950,7 +978,7 @@ static __always_inline void __ClearPage##uname(struct page *page)	\
> >   * 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, PF_ANY)
> >  
> >  /*
> >   * PageOffline() indicates that the page is logically offline although the
> > @@ -974,7 +1002,10 @@ 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, PF_ANY)
> > +
> > +/* PageSlab() indicates that the page is used by slab subsystem. */
> > +PAGE_TYPE_OPS(Slab, slab, PF_NO_TAIL)
> >  
> >  extern void page_offline_freeze(void);
> >  extern void page_offline_thaw(void);
> > @@ -984,12 +1015,12 @@ extern void page_offline_end(void);
> >  /*
> >   * Marks pages in use as page tables.
> >   */
> > -PAGE_TYPE_OPS(Table, table)
> > +PAGE_TYPE_OPS(Table, table, PF_ANY)
> >  
> >  /*
> >   * Marks guardpages used with debug_pagealloc.
> >   */
> > -PAGE_TYPE_OPS(Guard, guard)
> > +PAGE_TYPE_OPS(Guard, guard, PF_ANY)
> >  
> >  extern bool is_free_buddy_page(struct page *page);
> >  
> > @@ -1037,8 +1068,8 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page)
> >  	(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 | LRU_GEN_MASK)
> > +	 1UL << PG_active 	| 1UL << PG_unevictable |	\
> > +	 __PG_MLOCKED | LRU_GEN_MASK)
> >  
> >  /*
> >   * Flags checked when a page is prepped for return by the page allocator.
> > diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
> > index 412b5a46374c..8301912f8c25 100644
> > --- a/include/trace/events/mmflags.h
> > +++ b/include/trace/events/mmflags.h
> > @@ -113,7 +113,6 @@
> >  	{1UL << PG_lru,			"lru"		},		\
> >  	{1UL << PG_active,		"active"	},		\
> >  	{1UL << PG_workingset,		"workingset"	},		\
> > -	{1UL << PG_slab,		"slab"		},		\
> >  	{1UL << PG_owner_priv_1,	"owner_priv_1"	},		\
> >  	{1UL << PG_arch_1,		"arch_1"	},		\
> >  	{1UL << PG_reserved,		"reserved"	},		\
> > diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> > index 87ef6096823f..1ea8198c26e1 100644
> > --- a/kernel/crash_core.c
> > +++ b/kernel/crash_core.c
> > @@ -482,13 +482,14 @@ static int __init crash_save_vmcoreinfo_init(void)
> >  	VMCOREINFO_NUMBER(PG_private);
> >  	VMCOREINFO_NUMBER(PG_swapcache);
> >  	VMCOREINFO_NUMBER(PG_swapbacked);
> > -	VMCOREINFO_NUMBER(PG_slab);
> >  #ifdef CONFIG_MEMORY_FAILURE
> >  	VMCOREINFO_NUMBER(PG_hwpoison);
> >  #endif
> >  	VMCOREINFO_NUMBER(PG_head_mask);
> >  #define PAGE_BUDDY_MAPCOUNT_VALUE	(~PG_buddy)
> >  	VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
> > +#define PAGE_SLAB_MAPCOUNT_VALUE	(~PG_slab)
> > +	VMCOREINFO_NUMBER(PAGE_SLAB_MAPCOUNT_VALUE);
> >  #ifdef CONFIG_HUGETLB_PAGE
> >  	VMCOREINFO_NUMBER(HUGETLB_PAGE_DTOR);
> >  #define PAGE_OFFLINE_MAPCOUNT_VALUE	(~PG_offline)
> > diff --git a/mm/slab.c b/mm/slab.c
> > index 7a269db050ee..eee46f71c4b8 100644
> > --- a/mm/slab.c
> > +++ b/mm/slab.c
> > @@ -2269,6 +2269,21 @@ void __kmem_cache_release(struct kmem_cache *cachep)
> >  	}
> >  }
> >  
> > +static inline unsigned int slab_get_active(struct slab *slab)
> > +{
> > +	return ~(slab->page_type | PG_slab);
> > +}
> > +
> > +static inline void slab_inc_active(struct slab *slab)
> > +{
> > +	slab->page_type--;
> > +}
> > +
> > +static inline void slab_dec_active(struct slab *slab)
> > +{
> > +	slab->page_type++;
> > +}
> > +
> >  /*
> >   * Get the memory for a slab management obj.
> >   *
> > @@ -2291,7 +2306,6 @@ static void *alloc_slabmgmt(struct kmem_cache *cachep,
> >  	void *addr = slab_address(slab);
> >  
> >  	slab->s_mem = addr + colour_off;
> > -	slab->active = 0;
> >  
> >  	if (OBJFREELIST_SLAB(cachep))
> >  		freelist = NULL;
> > @@ -2510,8 +2524,8 @@ static void *slab_get_obj(struct kmem_cache *cachep, struct slab *slab)
> >  {
> >  	void *objp;
> >  
> > -	objp = index_to_obj(cachep, slab, get_free_obj(slab, slab->active));
> > -	slab->active++;
> > +	objp = index_to_obj(cachep, slab, get_free_obj(slab, slab_get_active(slab)));
> > +	slab_inc_active(slab);
> >  
> >  	return objp;
> >  }
> > @@ -2524,7 +2538,7 @@ static void slab_put_obj(struct kmem_cache *cachep,
> >  	unsigned int i;
> >  
> >  	/* Verify double free bug */
> > -	for (i = slab->active; i < cachep->num; i++) {
> > +	for (i = slab_get_active(slab); i < cachep->num; i++) {
> >  		if (get_free_obj(slab, i) == objnr) {
> >  			pr_err("slab: double free detected in cache '%s', objp %px\n",
> >  			       cachep->name, objp);
> > @@ -2532,11 +2546,11 @@ static void slab_put_obj(struct kmem_cache *cachep,
> >  		}
> >  	}
> >  #endif
> > -	slab->active--;
> > +	slab_dec_active(slab);
> >  	if (!slab->freelist)
> >  		slab->freelist = objp + obj_offset(cachep);
> >  
> > -	set_free_obj(slab, slab->active, objnr);
> > +	set_free_obj(slab, slab_get_active(slab), objnr);
> >  }
> >  
> >  /*
> > @@ -2635,14 +2649,14 @@ static void cache_grow_end(struct kmem_cache *cachep, struct slab *slab)
> >  
> >  	raw_spin_lock(&n->list_lock);
> >  	n->total_slabs++;
> > -	if (!slab->active) {
> > +	if (!slab_get_active(slab)) {
> >  		list_add_tail(&slab->slab_list, &n->slabs_free);
> >  		n->free_slabs++;
> >  	} else
> >  		fixup_slab_list(cachep, n, slab, &list);
> >  
> >  	STATS_INC_GROWN(cachep);
> > -	n->free_objects += cachep->num - slab->active;
> > +	n->free_objects += cachep->num - slab_get_active(slab);
> >  	raw_spin_unlock(&n->list_lock);
> >  
> >  	fixup_objfreelist_debug(cachep, &list);
> > @@ -2744,7 +2758,7 @@ static inline void fixup_slab_list(struct kmem_cache *cachep,
> >  {
> >  	/* move slabp to correct slabp list: */
> >  	list_del(&slab->slab_list);
> > -	if (slab->active == cachep->num) {
> > +	if (slab_get_active(slab) == cachep->num) {
> >  		list_add(&slab->slab_list, &n->slabs_full);
> >  		if (OBJFREELIST_SLAB(cachep)) {
> >  #if DEBUG
> > @@ -2783,7 +2797,7 @@ static noinline struct slab *get_valid_first_slab(struct kmem_cache_node *n,
> >  
> >  	/* Move pfmemalloc slab to the end of list to speed up next search */
> >  	list_del(&slab->slab_list);
> > -	if (!slab->active) {
> > +	if (!slab_get_active(slab)) {
> >  		list_add_tail(&slab->slab_list, &n->slabs_free);
> >  		n->free_slabs++;
> >  	} else
> > @@ -2865,9 +2879,9 @@ static __always_inline int alloc_block(struct kmem_cache *cachep,
> >  	 * There must be at least one object available for
> >  	 * allocation.
> >  	 */
> > -	BUG_ON(slab->active >= cachep->num);
> > +	BUG_ON(slab_get_active(slab) >= cachep->num);
> >  
> > -	while (slab->active < cachep->num && batchcount--) {
> > +	while (slab_get_active(slab) < cachep->num && batchcount--) {
> >  		STATS_INC_ALLOCED(cachep);
> >  		STATS_INC_ACTIVE(cachep);
> >  		STATS_SET_HIGH(cachep);
> > @@ -3162,7 +3176,7 @@ static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags,
> >  	STATS_INC_ACTIVE(cachep);
> >  	STATS_SET_HIGH(cachep);
> >  
> > -	BUG_ON(slab->active == cachep->num);
> > +	BUG_ON(slab_get_active(slab) == cachep->num);
> >  
> >  	obj = slab_get_obj(cachep, slab);
> >  	n->free_objects--;
> > @@ -3297,7 +3311,7 @@ static void free_block(struct kmem_cache *cachep, void **objpp,
> >  		STATS_DEC_ACTIVE(cachep);
> >  
> >  		/* fixup slab chains */
> > -		if (slab->active == 0) {
> > +		if (slab_get_active(slab) == 0) {
> >  			list_add(&slab->slab_list, &n->slabs_free);
> >  			n->free_slabs++;
> >  		} else {
> > @@ -3352,7 +3366,7 @@ static void cache_flusharray(struct kmem_cache *cachep, struct array_cache *ac)
> >  		struct slab *slab;
> >  
> >  		list_for_each_entry(slab, &n->slabs_free, slab_list) {
> > -			BUG_ON(slab->active);
> > +			BUG_ON(slab_get_active(slab));
> >  
> >  			i++;
> >  		}
> > diff --git a/mm/slab.h b/mm/slab.h
> > index 7cc432969945..c6ffe6799436 100644
> > --- a/mm/slab.h
> > +++ b/mm/slab.h
> > @@ -20,7 +20,8 @@ struct slab {
> >  		};
> >  		struct rcu_head rcu_head;
> >  	};
> > -	unsigned int active;
> > +	/* lower half of page_type is used as active objects counter */
> > +	unsigned int page_type;
> >  
> >  #elif defined(CONFIG_SLUB)
> >  
> 


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 2/4] mm: move PG_slab flag to page_type
  2023-01-30  4:34     ` Hyeonggon Yoo
@ 2023-01-30  5:11       ` Matthew Wilcox
  2023-02-03 16:00         ` Hyeonggon Yoo
  2023-02-03 16:04         ` David Hildenbrand
  0 siblings, 2 replies; 25+ messages in thread
From: Matthew Wilcox @ 2023-01-30  5:11 UTC (permalink / raw)
  To: Hyeonggon Yoo
  Cc: Vlastimil Babka, Christoph Lameter, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也), Joe Perches,
	Petr Mladek, Andy Shevchenko, David Hildenbrand, linux-mm,
	linux-kernel, Alexander Potapenko, Marco Elver

On Mon, Jan 30, 2023 at 01:34:59PM +0900, Hyeonggon Yoo wrote:
> > Seems like quite some changes to page_type to accomodate SLAB, which is
> > hopefully going away soon(TM). Could we perhaps avoid that?
> 
> If it could be done with less changes, I'll try to avoid that.

Let me outline the idea I had for removing PG_slab:

Observe that PG_reserved and PG_slab are mutually exclusive.  Also,
if PG_reserved is set, no other flags are set.  If PG_slab is set, only
PG_locked is used.  Many of the flags are only for use by anon/page
cache pages (eg referenced, uptodate, dirty, lru, active, workingset,
waiters, error, owner_priv_1, writeback, mappedtodisk, reclaim,
swapbacked, unevictable, mlocked).

Redefine PG_reserved as PG_kernel.  Now we can use the other _15_
flags to indicate pagetype, as long as PG_kernel is set.  So, eg
PageSlab() can now be (page->flags & PG_type) == PG_slab where

#define PG_kernel	0x00001
#define PG_type		(PG_kernel | 0x7fff0)
#define PG_slab		(PG_kernel | 0x00010)
#define PG_reserved	(PG_kernel | 0x00020)
#define PG_buddy	(PG_kernel | 0x00030)
#define PG_offline	(PG_kernel | 0x00040)
#define PG_table	(PG_kernel | 0x00050)
#define PG_guard	(PG_kernel | 0x00060)

That frees up the existing PG_slab, lets us drop the page_type field
altogether and gives us space to define all the page types we might
want (eg PG_vmalloc)

We'll want to reorganise all the flags which are for anon/file pages
into a contiguous block.  And now that I think about it, vmalloc pages
can be mapped to userspace, so they can get marked dirty, so only
14 bits are available.  Maybe rearrange to ...

PG_locked	0x000001
PG_writeback	0x000002
PG_head		0x000004
PG_dirty	0x000008
PG_owner_priv_1	0x000010
PG_arch_1	0x000020
PG_private	0x000040
PG_waiters	0x000080
PG_kernel	0x000100
PG_referenced	0x000200
PG_uptodate	0x000400
PG_lru		0x000800
PG_active	0x001000
PG_workingset	0x002000
PG_error	0x004000
PG_private_2	0x008000
PG_mappedtodisk	0x010000
PG_reclaim	0x020000
PG_swapbacked	0x040000
PG_unevictable	0x080000
PG_mlocked	0x100000

... or something.  There are a number of constraints and it may take
a few iterations to get this right.  Oh, and if this is the layout
we use, then:

PG_type		0x1fff00
PG_reserved	(PG_kernel | 0x200)
PG_slab		(PG_kernel | 0x400)
PG_buddy	(PG_kernel | 0x600)
PG_offline	(PG_kernel | 0x800)
PG_table	(PG_kernel | 0xa00)
PG_guard	(PG_kernel | 0xc00)
PG_vmalloc	(PG_kernel | 0xe00)

This is going to make show_page_flags() more complex :-P

Oh, and while we're doing this, we should just make PG_mlocked
unconditional.  NOMMU doesn't need the extra space in page flags
(for what?  their large number of NUMA nodes?)


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 2/4] mm: move PG_slab flag to page_type
  2023-01-30  5:11       ` Matthew Wilcox
@ 2023-02-03 16:00         ` Hyeonggon Yoo
  2023-02-03 16:19           ` Matthew Wilcox
  2023-02-03 16:04         ` David Hildenbrand
  1 sibling, 1 reply; 25+ messages in thread
From: Hyeonggon Yoo @ 2023-02-03 16:00 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Vlastimil Babka, Christoph Lameter, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也), Joe Perches,
	Petr Mladek, Andy Shevchenko, David Hildenbrand, linux-mm,
	linux-kernel, Alexander Potapenko, Marco Elver

On Mon, Jan 30, 2023 at 05:11:48AM +0000, Matthew Wilcox wrote:
> On Mon, Jan 30, 2023 at 01:34:59PM +0900, Hyeonggon Yoo wrote:
> > > Seems like quite some changes to page_type to accomodate SLAB, which is
> > > hopefully going away soon(TM). Could we perhaps avoid that?
> > 
> > If it could be done with less changes, I'll try to avoid that.
> 
> Let me outline the idea I had for removing PG_slab:
> 
> Observe that PG_reserved and PG_slab are mutually exclusive.  Also,
> if PG_reserved is set, no other flags are set.  If PG_slab is set, only
> PG_locked is used.  Many of the flags are only for use by anon/page
> cache pages (eg referenced, uptodate, dirty, lru, active, workingset,
> waiters, error, owner_priv_1, writeback, mappedtodisk, reclaim,
> swapbacked, unevictable, mlocked).
> 
> Redefine PG_reserved as PG_kernel.  Now we can use the other _15_
> flags to indicate pagetype, as long as PG_kernel is set. 

So PG_kernel is a new special flag, I thought it indicates
"not usermappable pages", but considering PG_vmalloc it's not.

> So, eg
> PageSlab() can now be (page->flags & PG_type) == PG_slab where

But if PG_xxx and PG_slab shares same bit, PG_xxx would be confused?

> #define PG_kernel	0x00001
> #define PG_type		(PG_kernel | 0x7fff0)
> #define PG_slab		(PG_kernel | 0x00010)
> #define PG_reserved	(PG_kernel | 0x00020)
> #define PG_buddy	(PG_kernel | 0x00030)
> #define PG_offline	(PG_kernel | 0x00040)
> #define PG_table	(PG_kernel | 0x00050)
> #define PG_guard	(PG_kernel | 0x00060)
> 
> That frees up the existing PG_slab, lets us drop the page_type field
> altogether and gives us space to define all the page types we might
> want (eg PG_vmalloc)
> 
> We'll want to reorganise all the flags which are for anon/file pages
> into a contiguous block.  And now that I think about it, vmalloc pages
> can be mapped to userspace, so they can get marked dirty, so only
> 14 bits are available.  Maybe rearrange to ...
> 
> PG_locked	0x000001
> PG_writeback	0x000002
> PG_head		0x000004

I think slab still needs PG_head,
but it seems to be okay with this layout.
(but these assumpstions are better documented, I think)

> PG_dirty	0x000008
> PG_owner_priv_1	0x000010
> PG_arch_1	0x000020
> PG_private	0x000040
> PG_waiters	0x000080
> PG_kernel	0x000100
> PG_referenced	0x000200
> PG_uptodate	0x000400
> PG_lru		0x000800
> PG_active	0x001000
> PG_workingset	0x002000
> PG_error	0x004000
> PG_private_2	0x008000
> PG_mappedtodisk	0x010000
> PG_reclaim	0x020000
> PG_swapbacked	0x040000
> PG_unevictable	0x080000
> PG_mlocked	0x100000
> 
> ... or something.  There are a number of constraints and it may take
> a few iterations to get this right.  Oh, and if this is the layout
> we use, then:
> 
> PG_type		0x1fff00
> PG_reserved	(PG_kernel | 0x200)
> PG_slab		(PG_kernel | 0x400)
> PG_buddy	(PG_kernel | 0x600)
> PG_offline	(PG_kernel | 0x800)
> PG_table	(PG_kernel | 0xa00)
> PG_guard	(PG_kernel | 0xc00)
> PG_vmalloc	(PG_kernel | 0xe00)

what is PG_vmalloc for, is it just an example for
explaining possible layout?

> This is going to make show_page_flags() more complex :-P
>
> Oh, and while we're doing this, we should just make PG_mlocked
> unconditional.  NOMMU doesn't need the extra space in page flags
> (for what?  their large number of NUMA nodes?)


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 2/4] mm: move PG_slab flag to page_type
  2023-01-30  5:11       ` Matthew Wilcox
  2023-02-03 16:00         ` Hyeonggon Yoo
@ 2023-02-03 16:04         ` David Hildenbrand
  2023-02-08  9:44           ` Mike Rapoport
  1 sibling, 1 reply; 25+ messages in thread
From: David Hildenbrand @ 2023-02-03 16:04 UTC (permalink / raw)
  To: Matthew Wilcox, Hyeonggon Yoo
  Cc: Vlastimil Babka, Christoph Lameter, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也), Joe Perches,
	Petr Mladek, Andy Shevchenko, linux-mm, linux-kernel,
	Alexander Potapenko, Marco Elver

On 30.01.23 06:11, Matthew Wilcox wrote:
> On Mon, Jan 30, 2023 at 01:34:59PM +0900, Hyeonggon Yoo wrote:
>>> Seems like quite some changes to page_type to accomodate SLAB, which is
>>> hopefully going away soon(TM). Could we perhaps avoid that?
>>
>> If it could be done with less changes, I'll try to avoid that.
> 
> Let me outline the idea I had for removing PG_slab:
> 
> Observe that PG_reserved and PG_slab are mutually exclusive.  Also,

I recall that there are SetPageReserved() calls on pages allocated via slab.

-- 
Thanks,

David / dhildenb



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 2/4] mm: move PG_slab flag to page_type
  2023-02-03 16:00         ` Hyeonggon Yoo
@ 2023-02-03 16:19           ` Matthew Wilcox
  2023-02-08 13:56             ` Hyeonggon Yoo
  0 siblings, 1 reply; 25+ messages in thread
From: Matthew Wilcox @ 2023-02-03 16:19 UTC (permalink / raw)
  To: Hyeonggon Yoo
  Cc: Vlastimil Babka, Christoph Lameter, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也), Joe Perches,
	Petr Mladek, Andy Shevchenko, David Hildenbrand, linux-mm,
	linux-kernel, Alexander Potapenko, Marco Elver

On Fri, Feb 03, 2023 at 04:00:08PM +0000, Hyeonggon Yoo wrote:
> On Mon, Jan 30, 2023 at 05:11:48AM +0000, Matthew Wilcox wrote:
> > On Mon, Jan 30, 2023 at 01:34:59PM +0900, Hyeonggon Yoo wrote:
> > > > Seems like quite some changes to page_type to accomodate SLAB, which is
> > > > hopefully going away soon(TM). Could we perhaps avoid that?
> > > 
> > > If it could be done with less changes, I'll try to avoid that.
> > 
> > Let me outline the idea I had for removing PG_slab:
> > 
> > Observe that PG_reserved and PG_slab are mutually exclusive.  Also,
> > if PG_reserved is set, no other flags are set.  If PG_slab is set, only
> > PG_locked is used.  Many of the flags are only for use by anon/page
> > cache pages (eg referenced, uptodate, dirty, lru, active, workingset,
> > waiters, error, owner_priv_1, writeback, mappedtodisk, reclaim,
> > swapbacked, unevictable, mlocked).
> > 
> > Redefine PG_reserved as PG_kernel.  Now we can use the other _15_
> > flags to indicate pagetype, as long as PG_kernel is set. 
> 
> So PG_kernel is a new special flag, I thought it indicates
> "not usermappable pages", but considering PG_vmalloc it's not.

Right, it means "The kernel allocated this page for its own purposes;
what that purpose is might be available by looking at PG_type".  ie
it's not-anon, not-page-cache.

> > So, eg
> > PageSlab() can now be (page->flags & PG_type) == PG_slab where
> 
> But if PG_xxx and PG_slab shares same bit, PG_xxx would be confused?

Correct.  Ideally those tests wouldn't be used on arbitrary pages,
only pages which are already confirmed to be anon or file.  I suspect
we haven't been super-careful about that in the past, and so there
would be some degree of "Oh, we need to fix this up".  But flags like
PG_mappedtodisk, PG_mlocked, PG_unevictable, PG_workingset should be
all gated behind "We know this is anon/file".

> > #define PG_kernel	0x00001
> > #define PG_type		(PG_kernel | 0x7fff0)
> > #define PG_slab		(PG_kernel | 0x00010)
> > #define PG_reserved	(PG_kernel | 0x00020)
> > #define PG_buddy	(PG_kernel | 0x00030)
> > #define PG_offline	(PG_kernel | 0x00040)
> > #define PG_table	(PG_kernel | 0x00050)
> > #define PG_guard	(PG_kernel | 0x00060)
> > 
> > That frees up the existing PG_slab, lets us drop the page_type field
> > altogether and gives us space to define all the page types we might
> > want (eg PG_vmalloc)
> > 
> > We'll want to reorganise all the flags which are for anon/file pages
> > into a contiguous block.  And now that I think about it, vmalloc pages
> > can be mapped to userspace, so they can get marked dirty, so only
> > 14 bits are available.  Maybe rearrange to ...
> > 
> > PG_locked	0x000001
> > PG_writeback	0x000002
> > PG_head		0x000004
> 
> I think slab still needs PG_head,
> but it seems to be okay with this layout.
> (but these assumpstions are better documented, I think)

Yes, slab need PG_head so it knows whether this is a multi-page slab or
not.  I forgot to mention it above as a bit that slab needs, but I put
it in the low bits here.

> > PG_dirty	0x000008
> > PG_owner_priv_1	0x000010
> > PG_arch_1	0x000020
> > PG_private	0x000040
> > PG_waiters	0x000080
> > PG_kernel	0x000100
> > PG_referenced	0x000200
> > PG_uptodate	0x000400
> > PG_lru		0x000800
> > PG_active	0x001000
> > PG_workingset	0x002000
> > PG_error	0x004000
> > PG_private_2	0x008000
> > PG_mappedtodisk	0x010000
> > PG_reclaim	0x020000
> > PG_swapbacked	0x040000
> > PG_unevictable	0x080000
> > PG_mlocked	0x100000
> > 
> > ... or something.  There are a number of constraints and it may take
> > a few iterations to get this right.  Oh, and if this is the layout
> > we use, then:
> > 
> > PG_type		0x1fff00
> > PG_reserved	(PG_kernel | 0x200)
> > PG_slab		(PG_kernel | 0x400)
> > PG_buddy	(PG_kernel | 0x600)
> > PG_offline	(PG_kernel | 0x800)
> > PG_table	(PG_kernel | 0xa00)
> > PG_guard	(PG_kernel | 0xc00)
> > PG_vmalloc	(PG_kernel | 0xe00)
> 
> what is PG_vmalloc for, is it just an example for
> explaining possible layout?

I really want to mark pages as being allocated from vmalloc.  It's
one of the things we could do to make debugging better.



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 2/4] mm: move PG_slab flag to page_type
  2023-02-03 16:04         ` David Hildenbrand
@ 2023-02-08  9:44           ` Mike Rapoport
  2023-02-08 10:13             ` David Hildenbrand
  0 siblings, 1 reply; 25+ messages in thread
From: Mike Rapoport @ 2023-02-08  9:44 UTC (permalink / raw)
  To: David Hildenbrand
  Cc: Matthew Wilcox, Hyeonggon Yoo, Vlastimil Babka, Christoph Lameter,
	Pekka Enberg, David Rientjes, Joonsoo Kim, Andrew Morton,
	Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也), Joe Perches,
	Petr Mladek, Andy Shevchenko, linux-mm, linux-kernel,
	Alexander Potapenko, Marco Elver

On Fri, Feb 03, 2023 at 05:04:01PM +0100, David Hildenbrand wrote:
> On 30.01.23 06:11, Matthew Wilcox wrote:
> > On Mon, Jan 30, 2023 at 01:34:59PM +0900, Hyeonggon Yoo wrote:
> > > > Seems like quite some changes to page_type to accomodate SLAB, which is
> > > > hopefully going away soon(TM). Could we perhaps avoid that?
> > > 
> > > If it could be done with less changes, I'll try to avoid that.
> > 
> > Let me outline the idea I had for removing PG_slab:
> > 
> > Observe that PG_reserved and PG_slab are mutually exclusive.  Also,
> 
> I recall that there are SetPageReserved() calls on pages allocated via slab.

I did a quick scan, and it seems that all allocated reserved pages come
from alloc_pages() or vmalloc().
 
BTW, looking at the current usage of SetPageReserved, it seems that some
are bogus/historical and some would justify a different page type if we are
to have 15 bits for PG_kernel.

> -- 
> Thanks,
> 
> David / dhildenb

-- 
Sincerely yours,
Mike.


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 2/4] mm: move PG_slab flag to page_type
  2023-02-08  9:44           ` Mike Rapoport
@ 2023-02-08 10:13             ` David Hildenbrand
  0 siblings, 0 replies; 25+ messages in thread
From: David Hildenbrand @ 2023-02-08 10:13 UTC (permalink / raw)
  To: Mike Rapoport
  Cc: Matthew Wilcox, Hyeonggon Yoo, Vlastimil Babka, Christoph Lameter,
	Pekka Enberg, David Rientjes, Joonsoo Kim, Andrew Morton,
	Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也), Joe Perches,
	Petr Mladek, Andy Shevchenko, linux-mm, linux-kernel,
	Alexander Potapenko, Marco Elver

On 08.02.23 10:44, Mike Rapoport wrote:
> On Fri, Feb 03, 2023 at 05:04:01PM +0100, David Hildenbrand wrote:
>> On 30.01.23 06:11, Matthew Wilcox wrote:
>>> On Mon, Jan 30, 2023 at 01:34:59PM +0900, Hyeonggon Yoo wrote:
>>>>> Seems like quite some changes to page_type to accomodate SLAB, which is
>>>>> hopefully going away soon(TM). Could we perhaps avoid that?
>>>>
>>>> If it could be done with less changes, I'll try to avoid that.
>>>
>>> Let me outline the idea I had for removing PG_slab:
>>>
>>> Observe that PG_reserved and PG_slab are mutually exclusive.  Also,
>>
>> I recall that there are SetPageReserved() calls on pages allocated via slab.
> 
> I did a quick scan, and it seems that all allocated reserved pages come
> from alloc_pages() or vmalloc().
>   

Thanks for checking, good that my memory was wrong :)

> BTW, looking at the current usage of SetPageReserved, it seems that some
> are bogus/historical and some would justify a different page type if we are
> to have 15 bits for PG_kernel.

I remember raising in the past that something like PG_hole might be helpful.

I also recall that most SetPageReserved usage in drivers is to make 
ioremap happy. PG_ioremappable or smth like that would be better.

So yes, that would even help to cleanup the existing PG_reserved usage.

-- 
Thanks,

David / dhildenb



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [RFC v3 2/4] mm: move PG_slab flag to page_type
  2023-02-03 16:19           ` Matthew Wilcox
@ 2023-02-08 13:56             ` Hyeonggon Yoo
  0 siblings, 0 replies; 25+ messages in thread
From: Hyeonggon Yoo @ 2023-02-08 13:56 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Vlastimil Babka, Christoph Lameter, Pekka Enberg, David Rientjes,
	Joonsoo Kim, Andrew Morton, Roman Gushchin,
	HORIGUCHI NAOYA(堀口 直也), Joe Perches,
	Petr Mladek, Andy Shevchenko, David Hildenbrand, linux-mm,
	linux-kernel, Alexander Potapenko, Marco Elver

On Fri, Feb 03, 2023 at 04:19:32PM +0000, Matthew Wilcox wrote:
> On Fri, Feb 03, 2023 at 04:00:08PM +0000, Hyeonggon Yoo wrote:
> > On Mon, Jan 30, 2023 at 05:11:48AM +0000, Matthew Wilcox wrote:
> > > On Mon, Jan 30, 2023 at 01:34:59PM +0900, Hyeonggon Yoo wrote:
> > > > > Seems like quite some changes to page_type to accomodate SLAB, which is
> > > > > hopefully going away soon(TM). Could we perhaps avoid that?
> > > > 
> > > > If it could be done with less changes, I'll try to avoid that.
> > > 
> > > Let me outline the idea I had for removing PG_slab:
> > > 
> > > Observe that PG_reserved and PG_slab are mutually exclusive.  Also,
> > > if PG_reserved is set, no other flags are set.  If PG_slab is set, only
> > > PG_locked is used.  Many of the flags are only for use by anon/page
> > > cache pages (eg referenced, uptodate, dirty, lru, active, workingset,
> > > waiters, error, owner_priv_1, writeback, mappedtodisk, reclaim,
> > > swapbacked, unevictable, mlocked).
> > > 
> > > Redefine PG_reserved as PG_kernel.  Now we can use the other _15_
> > > flags to indicate pagetype, as long as PG_kernel is set. 
> > 
> > So PG_kernel is a new special flag, I thought it indicates
> > "not usermappable pages", but considering PG_vmalloc it's not.
> 
> Right, it means "The kernel allocated this page for its own purposes;
> what that purpose is might be available by looking at PG_type".  ie
> it's not-anon, not-page-cache.
>
> > > So, eg
> > > PageSlab() can now be (page->flags & PG_type) == PG_slab where
> > 
> > But if PG_xxx and PG_slab shares same bit, PG_xxx would be confused?
> 
> Correct.  Ideally those tests wouldn't be used on arbitrary pages,
> only pages which are already confirmed to be anon or file.  I suspect
> we haven't been super-careful about that in the past, and so there
> would be some degree of "Oh, we need to fix this up".  But flags like
> PG_mappedtodisk, PG_mlocked, PG_unevictable, PG_workingset should be
> all gated behind "We know this is anon/file".

Okay. let's just try then!

> > > PG_dirty	0x000008
> > > PG_owner_priv_1	0x000010
> > > PG_arch_1	0x000020
> > > PG_private	0x000040
> > > PG_waiters	0x000080
> > > PG_kernel	0x000100
> > > PG_referenced	0x000200
> > > PG_uptodate	0x000400
> > > PG_lru		0x000800
> > > PG_active	0x001000
> > > PG_workingset	0x002000
> > > PG_error	0x004000
> > > PG_private_2	0x008000
> > > PG_mappedtodisk	0x010000
> > > PG_reclaim	0x020000
> > > PG_swapbacked	0x040000
> > > PG_unevictable	0x080000
> > > PG_mlocked	0x100000
> > > 
> > > ... or something.  There are a number of constraints and it may take
> > > a few iterations to get this right.  Oh, and if this is the layout
> > > we use, then:
> > > 
> > > PG_type		0x1fff00
> > > PG_reserved	(PG_kernel | 0x200)
> > > PG_slab		(PG_kernel | 0x400)
> > > PG_buddy	(PG_kernel | 0x600)
> > > PG_offline	(PG_kernel | 0x800)
> > > PG_table	(PG_kernel | 0xa00)
> > > PG_guard	(PG_kernel | 0xc00)
> > > PG_vmalloc	(PG_kernel | 0xe00)
> > 
> > what is PG_vmalloc for, is it just an example for
> > explaining possible layout?
> 
> I really want to mark pages as being allocated from vmalloc.  It's
> one of the things we could do to make debugging better.

Got it. Anyway, the proposed approach is not compatible with this series
so I'll try implementing new series based on your outline. 

Thanks!


^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2023-02-08 13:56 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-12-18 10:18 [RFC v3 0/4] move PG_slab flag to page_type Hyeonggon Yoo
2022-12-18 10:18 ` [RFC v3 1/4] mm/hwpoison: remove MF_MSG_SLAB from action_page_types Hyeonggon Yoo
2022-12-20 23:53   ` HORIGUCHI NAOYA(堀口 直也)
2022-12-21 17:00     ` Andy Shevchenko
2022-12-29 13:18       ` Hyeonggon Yoo
2022-12-29 13:17     ` Hyeonggon Yoo
2022-12-18 10:18 ` [RFC v3 2/4] mm: move PG_slab flag to page_type Hyeonggon Yoo
2023-01-12 16:27   ` Vlastimil Babka
2023-01-30  4:34     ` Hyeonggon Yoo
2023-01-30  5:11       ` Matthew Wilcox
2023-02-03 16:00         ` Hyeonggon Yoo
2023-02-03 16:19           ` Matthew Wilcox
2023-02-08 13:56             ` Hyeonggon Yoo
2023-02-03 16:04         ` David Hildenbrand
2023-02-08  9:44           ` Mike Rapoport
2023-02-08 10:13             ` David Hildenbrand
2022-12-18 10:19 ` [RFC v3 3/4] mm, printk: introduce new format %pGt for page_type Hyeonggon Yoo
2022-12-18 19:32   ` kernel test robot
2022-12-19  9:44   ` Andy Shevchenko
2022-12-19 19:35     ` Randy Dunlap
2022-12-20 10:58       ` Andy Shevchenko
2022-12-29 13:35         ` Hyeonggon Yoo
2022-12-20 15:20   ` Petr Mladek
2022-12-29 13:30     ` Hyeonggon Yoo
2022-12-18 10:19 ` [RFC v3 4/4] mm/debug: use %pGt to print page_type in dump_page() Hyeonggon Yoo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.