[PATCH -mm 2/2] mm: page_idle: split 32bit page_idle's flag from the common flags

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



After we split page_owner's flag from the common page_ext flags, now
only 32bit page_idle is using the commt flags. Then we can define a flag
for 32bit page_idle only.
After this patch, the size of struct page_ext will be 0, so it won't
take extra memory overhead for the page_ext which don't use this flag.

Signed-off-by: Yafang Shao <laoar.shao@xxxxxxxxx>
---
 include/linux/page_ext.h  | 12 +-----------
 include/linux/page_idle.h | 39 +++++++++++++++++++++++++++++++++------
 mm/page_ext.c             | 10 ----------
 mm/page_idle.c            | 12 ++++++++++++
 4 files changed, 46 insertions(+), 27 deletions(-)

diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h
index c8ca4954145c..6515d2a62f34 100644
--- a/include/linux/page_ext.h
+++ b/include/linux/page_ext.h
@@ -15,14 +15,6 @@ struct page_ext_operations {
 };
 
 #ifdef CONFIG_PAGE_EXTENSION
-
-#if defined(CONFIG_PAGE_IDLE_FLAG) && !defined(CONFIG_64BIT)
-enum page_ext_flags {
-	PAGE_EXT_YOUNG,
-	PAGE_EXT_IDLE,
-};
-#endif
-
 /*
  * Page Extension can be considered as an extended mem_map.
  * A page_ext page is associated with every page descriptor. The
@@ -30,9 +22,7 @@ enum page_ext_flags {
  * All page_ext are allocated at boot or memory hotplug event,
  * then the page_ext for pfn always exists.
  */
-struct page_ext {
-	unsigned long flags;
-};
+struct page_ext {};
 
 extern bool early_page_ext;
 extern unsigned long page_ext_size;
diff --git a/include/linux/page_idle.h b/include/linux/page_idle.h
index 5cb7bd2078ec..4d1311fdae1d 100644
--- a/include/linux/page_idle.h
+++ b/include/linux/page_idle.h
@@ -9,6 +9,21 @@
 #ifdef CONFIG_PAGE_IDLE_FLAG
 
 #ifndef CONFIG_64BIT
+enum page_idle_flags {
+	PAGE_EXT_YOUNG,
+	PAGE_EXT_IDLE,
+};
+
+struct page_idle {
+	unsigned long flags;
+};
+
+extern struct page_ext_operations page_idle_ops;
+static inline struct page_idle *get_page_idle(struct page_ext *page_ext)
+{
+	return (void *)page_ext + page_idle_ops.offset;
+}
+
 /*
  * If there is not enough space to store Idle and Young bits in page flags, use
  * page ext flags instead.
@@ -16,12 +31,14 @@
 static inline bool folio_test_young(struct folio *folio)
 {
 	struct page_ext *page_ext = page_ext_get(&folio->page);
+	struct page_idle *pi;
 	bool page_young;
 
 	if (unlikely(!page_ext))
 		return false;
 
-	page_young = test_bit(PAGE_EXT_YOUNG, &page_ext->flags);
+	pi = get_page_idle(page_ext);
+	page_young = test_bit(PAGE_EXT_YOUNG, &pi->flags);
 	page_ext_put(page_ext);
 
 	return page_young;
@@ -30,23 +47,27 @@ static inline bool folio_test_young(struct folio *folio)
 static inline void folio_set_young(struct folio *folio)
 {
 	struct page_ext *page_ext = page_ext_get(&folio->page);
+	struct page_idle *pi;
 
 	if (unlikely(!page_ext))
 		return;
 
-	set_bit(PAGE_EXT_YOUNG, &page_ext->flags);
+	pi = get_page_idle(page_ext);
+	set_bit(PAGE_EXT_YOUNG, &pi->flags);
 	page_ext_put(page_ext);
 }
 
 static inline bool folio_test_clear_young(struct folio *folio)
 {
 	struct page_ext *page_ext = page_ext_get(&folio->page);
+	struct page_idle *pi;
 	bool page_young;
 
 	if (unlikely(!page_ext))
 		return false;
 
-	page_young = test_and_clear_bit(PAGE_EXT_YOUNG, &page_ext->flags);
+	pi = get_page_idle(page_ext);
+	page_young = test_and_clear_bit(PAGE_EXT_YOUNG, &pi->flags);
 	page_ext_put(page_ext);
 
 	return page_young;
@@ -55,12 +76,14 @@ static inline bool folio_test_clear_young(struct folio *folio)
 static inline bool folio_test_idle(struct folio *folio)
 {
 	struct page_ext *page_ext = page_ext_get(&folio->page);
+	struct page_idle *pi;
 	bool page_idle;
 
 	if (unlikely(!page_ext))
 		return false;
 
-	page_idle =  test_bit(PAGE_EXT_IDLE, &page_ext->flags);
+	pi = get_page_idle(page_ext);
+	page_idle =  test_bit(PAGE_EXT_IDLE, &pi->flags);
 	page_ext_put(page_ext);
 
 	return page_idle;
@@ -69,22 +92,26 @@ static inline bool folio_test_idle(struct folio *folio)
 static inline void folio_set_idle(struct folio *folio)
 {
 	struct page_ext *page_ext = page_ext_get(&folio->page);
+	struct page_idle *pi;
 
 	if (unlikely(!page_ext))
 		return;
 
-	set_bit(PAGE_EXT_IDLE, &page_ext->flags);
+	pi = get_page_idle(page_ext);
+	set_bit(PAGE_EXT_IDLE, &pi->flags);
 	page_ext_put(page_ext);
 }
 
 static inline void folio_clear_idle(struct folio *folio)
 {
 	struct page_ext *page_ext = page_ext_get(&folio->page);
+	struct page_idle *pi;
 
 	if (unlikely(!page_ext))
 		return;
 
-	clear_bit(PAGE_EXT_IDLE, &page_ext->flags);
+	pi = get_page_idle(page_ext);
+	clear_bit(PAGE_EXT_IDLE, &pi->flags);
 	page_ext_put(page_ext);
 }
 #endif /* !CONFIG_64BIT */
diff --git a/mm/page_ext.c b/mm/page_ext.c
index 4ee522fd381c..b3459bf08b78 100644
--- a/mm/page_ext.c
+++ b/mm/page_ext.c
@@ -64,16 +64,6 @@
 #define PAGE_EXT_INVALID       (0x1)
 #endif
 
-#if defined(CONFIG_PAGE_IDLE_FLAG) && !defined(CONFIG_64BIT)
-static bool need_page_idle(void)
-{
-	return true;
-}
-static struct page_ext_operations page_idle_ops __initdata = {
-	.need = need_page_idle,
-};
-#endif
-
 static struct page_ext_operations *page_ext_ops[] __initdata = {
 #ifdef CONFIG_PAGE_OWNER
 	&page_owner_ops,
diff --git a/mm/page_idle.c b/mm/page_idle.c
index bc08332a609c..ea1b08a541b3 100644
--- a/mm/page_idle.c
+++ b/mm/page_idle.c
@@ -18,6 +18,18 @@
 #define BITMAP_CHUNK_SIZE	sizeof(u64)
 #define BITMAP_CHUNK_BITS	(BITMAP_CHUNK_SIZE * BITS_PER_BYTE)
 
+#ifndef CONFIG_64BIT
+static bool need_page_idle(void)
+{
+	return true;
+}
+
+struct page_ext_operations page_idle_ops __initdata = {
+	.size = sizeof(struct page_idle),
+	.need = need_page_idle,
+};
+#endif
+
 /*
  * Idle page tracking only considers user memory pages, for other types of
  * pages the idle flag is always unset and an attempt to set it is silently
-- 
2.30.1 (Apple Git-130)





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux