All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] Folio Prequel patches
@ 2021-04-30 14:55 Matthew Wilcox (Oracle)
  2021-04-30 14:55 ` [PATCH 1/8] mm: Optimise nth_page for contiguous memmap Matthew Wilcox (Oracle)
                   ` (8 more replies)
  0 siblings, 9 replies; 14+ messages in thread
From: Matthew Wilcox (Oracle) @ 2021-04-30 14:55 UTC (permalink / raw)
  To: linux-mm, linux-fsdevel, akpm; +Cc: Matthew Wilcox (Oracle)

These patches have all been posted before and not picked up yet.  I've
built the folio patches on top of them; while they are not necessarily
prerequisites in the conceptual sense, I'm not convinced that the
folio patches will build without them.  The nth_page patch is purely an
efficiency question, while patch 5 ("Make compound_head const-preserving")
is required for the current implementation of page_folio().  Patch 8
("Fix struct page layout on 32-bit systems") is required for the struct
folio layout to match struct page layout on said 32-bit systems (arm,
mips, ppc).

They are on top of next-20210430

Matthew Wilcox (Oracle) (8):
  mm: Optimise nth_page for contiguous memmap
  mm: Make __dump_page static
  mm/debug: Factor PagePoisoned out of __dump_page
  mm/page_owner: Constify dump_page_owner
  mm: Make compound_head const-preserving
  mm: Constify get_pfnblock_flags_mask and get_pfnblock_migratetype
  mm: Constify page_count and page_ref_count
  mm: Fix struct page layout on 32-bit systems

 include/linux/mm.h              |  4 ++++
 include/linux/mm_types.h        |  4 ++--
 include/linux/mmdebug.h         |  3 +--
 include/linux/page-flags.h      | 10 +++++-----
 include/linux/page_owner.h      |  6 +++---
 include/linux/page_ref.h        |  4 ++--
 include/linux/pageblock-flags.h |  2 +-
 include/net/page_pool.h         | 12 +++++++++++-
 mm/debug.c                      | 25 +++++++------------------
 mm/page_alloc.c                 | 16 ++++++++--------
 mm/page_owner.c                 |  2 +-
 net/core/page_pool.c            | 12 +++++++-----
 12 files changed, 52 insertions(+), 48 deletions(-)

-- 
2.30.2


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

* [PATCH 1/8] mm: Optimise nth_page for contiguous memmap
  2021-04-30 14:55 [PATCH 0/8] Folio Prequel patches Matthew Wilcox (Oracle)
@ 2021-04-30 14:55 ` Matthew Wilcox (Oracle)
  2021-04-30 14:55 ` [PATCH 2/8] mm: Make __dump_page static Matthew Wilcox (Oracle)
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Matthew Wilcox (Oracle) @ 2021-04-30 14:55 UTC (permalink / raw)
  To: linux-mm, linux-fsdevel, akpm
  Cc: Matthew Wilcox (Oracle), Christoph Hellwig, David Hildenbrand, Zi Yan

If the memmap is virtually contiguous (either because we're using
a virtually mapped memmap or because we don't support a discontig
memmap at all), then we can implement nth_page() by simple addition.
Contrary to popular belief, the compiler is not able to optimise this
itself for a vmemmap configuration.  This reduces one example user (sg.c)
by four instructions:

        struct page *page = nth_page(rsv_schp->pages[k], offset >> PAGE_SHIFT);

before:
   49 8b 45 70             mov    0x70(%r13),%rax
   48 63 c9                movslq %ecx,%rcx
   48 c1 eb 0c             shr    $0xc,%rbx
   48 8b 04 c8             mov    (%rax,%rcx,8),%rax
   48 2b 05 00 00 00 00    sub    0x0(%rip),%rax
           R_X86_64_PC32      vmemmap_base-0x4
   48 c1 f8 06             sar    $0x6,%rax
   48 01 d8                add    %rbx,%rax
   48 c1 e0 06             shl    $0x6,%rax
   48 03 05 00 00 00 00    add    0x0(%rip),%rax
           R_X86_64_PC32      vmemmap_base-0x4

after:
   49 8b 45 70             mov    0x70(%r13),%rax
   48 63 c9                movslq %ecx,%rcx
   48 c1 eb 0c             shr    $0xc,%rbx
   48 c1 e3 06             shl    $0x6,%rbx
   48 03 1c c8             add    (%rax,%rcx,8),%rbx

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Zi Yan <ziy@nvidia.com>
---
 include/linux/mm.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 25b9041f9925..2327f99b121f 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -234,7 +234,11 @@ int overcommit_policy_handler(struct ctl_table *, int, void *, size_t *,
 int __add_to_page_cache_locked(struct page *page, struct address_space *mapping,
 		pgoff_t index, gfp_t gfp, void **shadowp);
 
+#if defined(CONFIG_SPARSEMEM) && !defined(CONFIG_SPARSEMEM_VMEMMAP)
 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
+#else
+#define nth_page(page,n) ((page) + (n))
+#endif
 
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE)
-- 
2.30.2


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

* [PATCH 2/8] mm: Make __dump_page static
  2021-04-30 14:55 [PATCH 0/8] Folio Prequel patches Matthew Wilcox (Oracle)
  2021-04-30 14:55 ` [PATCH 1/8] mm: Optimise nth_page for contiguous memmap Matthew Wilcox (Oracle)
@ 2021-04-30 14:55 ` Matthew Wilcox (Oracle)
  2021-04-30 14:55 ` [PATCH 3/8] mm/debug: Factor PagePoisoned out of __dump_page Matthew Wilcox (Oracle)
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Matthew Wilcox (Oracle) @ 2021-04-30 14:55 UTC (permalink / raw)
  To: linux-mm, linux-fsdevel, akpm
  Cc: Matthew Wilcox (Oracle),
	William Kucharski, Vlastimil Babka, Anshuman Khandual

The only caller of __dump_page() now opencodes dump_page(), so
remove it as an externally visible symbol.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: William Kucharski <william.kucharski@oracle.com>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
 include/linux/mmdebug.h | 3 +--
 mm/debug.c              | 2 +-
 mm/page_alloc.c         | 3 +--
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h
index 5d0767cb424a..1935d4c72d10 100644
--- a/include/linux/mmdebug.h
+++ b/include/linux/mmdebug.h
@@ -9,8 +9,7 @@ struct page;
 struct vm_area_struct;
 struct mm_struct;
 
-extern void dump_page(struct page *page, const char *reason);
-extern void __dump_page(struct page *page, const char *reason);
+void dump_page(struct page *page, const char *reason);
 void dump_vma(const struct vm_area_struct *vma);
 void dump_mm(const struct mm_struct *mm);
 
diff --git a/mm/debug.c b/mm/debug.c
index 0bdda8407f71..84cdcd0f7bd3 100644
--- a/mm/debug.c
+++ b/mm/debug.c
@@ -42,7 +42,7 @@ const struct trace_print_flags vmaflag_names[] = {
 	{0, NULL}
 };
 
-void __dump_page(struct page *page, const char *reason)
+static void __dump_page(struct page *page, const char *reason)
 {
 	struct page *head = compound_head(page);
 	struct address_space *mapping;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index a2fe714aed93..f23702e7c564 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -658,8 +658,7 @@ static void bad_page(struct page *page, const char *reason)
 
 	pr_alert("BUG: Bad page state in process %s  pfn:%05lx\n",
 		current->comm, page_to_pfn(page));
-	__dump_page(page, reason);
-	dump_page_owner(page);
+	dump_page(page, reason);
 
 	print_modules();
 	dump_stack();
-- 
2.30.2


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

* [PATCH 3/8] mm/debug: Factor PagePoisoned out of __dump_page
  2021-04-30 14:55 [PATCH 0/8] Folio Prequel patches Matthew Wilcox (Oracle)
  2021-04-30 14:55 ` [PATCH 1/8] mm: Optimise nth_page for contiguous memmap Matthew Wilcox (Oracle)
  2021-04-30 14:55 ` [PATCH 2/8] mm: Make __dump_page static Matthew Wilcox (Oracle)
@ 2021-04-30 14:55 ` Matthew Wilcox (Oracle)
  2021-05-12  3:29   ` Kefeng Wang
  2021-04-30 14:55 ` [PATCH 4/8] mm/page_owner: Constify dump_page_owner Matthew Wilcox (Oracle)
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 14+ messages in thread
From: Matthew Wilcox (Oracle) @ 2021-04-30 14:55 UTC (permalink / raw)
  To: linux-mm, linux-fsdevel, akpm
  Cc: Matthew Wilcox (Oracle),
	William Kucharski, Vlastimil Babka, Anshuman Khandual

Move the PagePoisoned test into dump_page().  Skip the hex print
for poisoned pages -- we know they're full of ffffffff.  Move the
reason printing from __dump_page() to dump_page().

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: William Kucharski <william.kucharski@oracle.com>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
 mm/debug.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/mm/debug.c b/mm/debug.c
index 84cdcd0f7bd3..e73fe0a8ec3d 100644
--- a/mm/debug.c
+++ b/mm/debug.c
@@ -42,11 +42,10 @@ const struct trace_print_flags vmaflag_names[] = {
 	{0, NULL}
 };
 
-static void __dump_page(struct page *page, const char *reason)
+static void __dump_page(struct page *page)
 {
 	struct page *head = compound_head(page);
 	struct address_space *mapping;
-	bool page_poisoned = PagePoisoned(page);
 	bool compound = PageCompound(page);
 	/*
 	 * Accessing the pageblock without the zone lock. It could change to
@@ -58,16 +57,6 @@ static void __dump_page(struct page *page, const char *reason)
 	int mapcount;
 	char *type = "";
 
-	/*
-	 * If struct page is poisoned don't access Page*() functions as that
-	 * leads to recursive loop. Page*() check for poisoned pages, and calls
-	 * dump_page() when detected.
-	 */
-	if (page_poisoned) {
-		pr_warn("page:%px is uninitialized and poisoned", page);
-		goto hex_only;
-	}
-
 	if (page < head || (page >= head + MAX_ORDER_NR_PAGES)) {
 		/*
 		 * Corrupt page, so we cannot call page_mapping. Instead, do a
@@ -173,8 +162,6 @@ static void __dump_page(struct page *page, const char *reason)
 
 	pr_warn("%sflags: %#lx(%pGp)%s\n", type, head->flags, &head->flags,
 		page_cma ? " CMA" : "");
-
-hex_only:
 	print_hex_dump(KERN_WARNING, "raw: ", DUMP_PREFIX_NONE, 32,
 			sizeof(unsigned long), page,
 			sizeof(struct page), false);
@@ -182,14 +169,16 @@ static void __dump_page(struct page *page, const char *reason)
 		print_hex_dump(KERN_WARNING, "head: ", DUMP_PREFIX_NONE, 32,
 			sizeof(unsigned long), head,
 			sizeof(struct page), false);
-
-	if (reason)
-		pr_warn("page dumped because: %s\n", reason);
 }
 
 void dump_page(struct page *page, const char *reason)
 {
-	__dump_page(page, reason);
+	if (PagePoisoned(page))
+		pr_warn("page:%p is uninitialized and poisoned", page);
+	else
+		__dump_page(page);
+	if (reason)
+		pr_warn("page dumped because: %s\n", reason);
 	dump_page_owner(page);
 }
 EXPORT_SYMBOL(dump_page);
-- 
2.30.2


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

* [PATCH 4/8] mm/page_owner: Constify dump_page_owner
  2021-04-30 14:55 [PATCH 0/8] Folio Prequel patches Matthew Wilcox (Oracle)
                   ` (2 preceding siblings ...)
  2021-04-30 14:55 ` [PATCH 3/8] mm/debug: Factor PagePoisoned out of __dump_page Matthew Wilcox (Oracle)
@ 2021-04-30 14:55 ` Matthew Wilcox (Oracle)
  2021-04-30 14:55 ` [PATCH 5/8] mm: Make compound_head const-preserving Matthew Wilcox (Oracle)
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Matthew Wilcox (Oracle) @ 2021-04-30 14:55 UTC (permalink / raw)
  To: linux-mm, linux-fsdevel, akpm
  Cc: Matthew Wilcox (Oracle),
	William Kucharski, Vlastimil Babka, Anshuman Khandual

dump_page_owner() only uses struct page to find the page_ext, and
lookup_page_ext() already takes a const argument.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: William Kucharski <william.kucharski@oracle.com>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
 include/linux/page_owner.h | 6 +++---
 mm/page_owner.c            | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h
index 3468794f83d2..719bfe5108c5 100644
--- a/include/linux/page_owner.h
+++ b/include/linux/page_owner.h
@@ -14,7 +14,7 @@ extern void __set_page_owner(struct page *page,
 extern void __split_page_owner(struct page *page, unsigned int nr);
 extern void __copy_page_owner(struct page *oldpage, struct page *newpage);
 extern void __set_page_owner_migrate_reason(struct page *page, int reason);
-extern void __dump_page_owner(struct page *page);
+extern void __dump_page_owner(const struct page *page);
 extern void pagetypeinfo_showmixedcount_print(struct seq_file *m,
 					pg_data_t *pgdat, struct zone *zone);
 
@@ -46,7 +46,7 @@ static inline void set_page_owner_migrate_reason(struct page *page, int reason)
 	if (static_branch_unlikely(&page_owner_inited))
 		__set_page_owner_migrate_reason(page, reason);
 }
-static inline void dump_page_owner(struct page *page)
+static inline void dump_page_owner(const struct page *page)
 {
 	if (static_branch_unlikely(&page_owner_inited))
 		__dump_page_owner(page);
@@ -69,7 +69,7 @@ static inline void copy_page_owner(struct page *oldpage, struct page *newpage)
 static inline void set_page_owner_migrate_reason(struct page *page, int reason)
 {
 }
-static inline void dump_page_owner(struct page *page)
+static inline void dump_page_owner(const struct page *page)
 {
 }
 #endif /* CONFIG_PAGE_OWNER */
diff --git a/mm/page_owner.c b/mm/page_owner.c
index adfabb560eb9..f51a57e92aa3 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -392,7 +392,7 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn,
 	return -ENOMEM;
 }
 
-void __dump_page_owner(struct page *page)
+void __dump_page_owner(const struct page *page)
 {
 	struct page_ext *page_ext = lookup_page_ext(page);
 	struct page_owner *page_owner;
-- 
2.30.2


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

* [PATCH 5/8] mm: Make compound_head const-preserving
  2021-04-30 14:55 [PATCH 0/8] Folio Prequel patches Matthew Wilcox (Oracle)
                   ` (3 preceding siblings ...)
  2021-04-30 14:55 ` [PATCH 4/8] mm/page_owner: Constify dump_page_owner Matthew Wilcox (Oracle)
@ 2021-04-30 14:55 ` Matthew Wilcox (Oracle)
  2021-04-30 14:55 ` [PATCH 6/8] mm: Constify get_pfnblock_flags_mask and get_pfnblock_migratetype Matthew Wilcox (Oracle)
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Matthew Wilcox (Oracle) @ 2021-04-30 14:55 UTC (permalink / raw)
  To: linux-mm, linux-fsdevel, akpm
  Cc: Matthew Wilcox (Oracle),
	William Kucharski, Vlastimil Babka, Anshuman Khandual

If you pass a const pointer to compound_head(), you get a const pointer
back; if you pass a mutable pointer, you get a mutable pointer back.
Also remove an unnecessary forward definition of struct page; we're about
to dereference page->compound_head, so it must already have been defined.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: William Kucharski <william.kucharski@oracle.com>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
 include/linux/page-flags.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 04a34c08e0a6..d8e26243db25 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -177,17 +177,17 @@ enum pageflags {
 
 #ifndef __GENERATING_BOUNDS_H
 
-struct page;	/* forward declaration */
-
-static inline struct page *compound_head(struct page *page)
+static inline unsigned long _compound_head(const struct page *page)
 {
 	unsigned long head = READ_ONCE(page->compound_head);
 
 	if (unlikely(head & 1))
-		return (struct page *) (head - 1);
-	return page;
+		return head - 1;
+	return (unsigned long)page;
 }
 
+#define compound_head(page)	((typeof(page))_compound_head(page))
+
 static __always_inline int PageTail(struct page *page)
 {
 	return READ_ONCE(page->compound_head) & 1;
-- 
2.30.2


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

* [PATCH 6/8] mm: Constify get_pfnblock_flags_mask and get_pfnblock_migratetype
  2021-04-30 14:55 [PATCH 0/8] Folio Prequel patches Matthew Wilcox (Oracle)
                   ` (4 preceding siblings ...)
  2021-04-30 14:55 ` [PATCH 5/8] mm: Make compound_head const-preserving Matthew Wilcox (Oracle)
@ 2021-04-30 14:55 ` Matthew Wilcox (Oracle)
  2021-04-30 14:55 ` [PATCH 7/8] mm: Constify page_count and page_ref_count Matthew Wilcox (Oracle)
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Matthew Wilcox (Oracle) @ 2021-04-30 14:55 UTC (permalink / raw)
  To: linux-mm, linux-fsdevel, akpm
  Cc: Matthew Wilcox (Oracle),
	William Kucharski, Vlastimil Babka, Anshuman Khandual

The struct page is not modified by these routines, so it can be marked
const.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: William Kucharski <william.kucharski@oracle.com>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
 include/linux/pageblock-flags.h |  2 +-
 mm/page_alloc.c                 | 13 +++++++------
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/linux/pageblock-flags.h b/include/linux/pageblock-flags.h
index fff52ad370c1..973fd731a520 100644
--- a/include/linux/pageblock-flags.h
+++ b/include/linux/pageblock-flags.h
@@ -54,7 +54,7 @@ extern unsigned int pageblock_order;
 /* Forward declaration */
 struct page;
 
-unsigned long get_pfnblock_flags_mask(struct page *page,
+unsigned long get_pfnblock_flags_mask(const struct page *page,
 				unsigned long pfn,
 				unsigned long mask);
 
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index f23702e7c564..5a1e5b624594 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -474,7 +474,7 @@ static inline bool defer_init(int nid, unsigned long pfn, unsigned long end_pfn)
 #endif
 
 /* Return a pointer to the bitmap storing bits affecting a block of pages */
-static inline unsigned long *get_pageblock_bitmap(struct page *page,
+static inline unsigned long *get_pageblock_bitmap(const struct page *page,
 							unsigned long pfn)
 {
 #ifdef CONFIG_SPARSEMEM
@@ -484,7 +484,7 @@ static inline unsigned long *get_pageblock_bitmap(struct page *page,
 #endif /* CONFIG_SPARSEMEM */
 }
 
-static inline int pfn_to_bitidx(struct page *page, unsigned long pfn)
+static inline int pfn_to_bitidx(const struct page *page, unsigned long pfn)
 {
 #ifdef CONFIG_SPARSEMEM
 	pfn &= (PAGES_PER_SECTION-1);
@@ -495,7 +495,7 @@ static inline int pfn_to_bitidx(struct page *page, unsigned long pfn)
 }
 
 static __always_inline
-unsigned long __get_pfnblock_flags_mask(struct page *page,
+unsigned long __get_pfnblock_flags_mask(const struct page *page,
 					unsigned long pfn,
 					unsigned long mask)
 {
@@ -520,13 +520,14 @@ unsigned long __get_pfnblock_flags_mask(struct page *page,
  *
  * Return: pageblock_bits flags
  */
-unsigned long get_pfnblock_flags_mask(struct page *page, unsigned long pfn,
-					unsigned long mask)
+unsigned long get_pfnblock_flags_mask(const struct page *page,
+					unsigned long pfn, unsigned long mask)
 {
 	return __get_pfnblock_flags_mask(page, pfn, mask);
 }
 
-static __always_inline int get_pfnblock_migratetype(struct page *page, unsigned long pfn)
+static __always_inline int get_pfnblock_migratetype(const struct page *page,
+					unsigned long pfn)
 {
 	return __get_pfnblock_flags_mask(page, pfn, MIGRATETYPE_MASK);
 }
-- 
2.30.2


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

* [PATCH 7/8] mm: Constify page_count and page_ref_count
  2021-04-30 14:55 [PATCH 0/8] Folio Prequel patches Matthew Wilcox (Oracle)
                   ` (5 preceding siblings ...)
  2021-04-30 14:55 ` [PATCH 6/8] mm: Constify get_pfnblock_flags_mask and get_pfnblock_migratetype Matthew Wilcox (Oracle)
@ 2021-04-30 14:55 ` Matthew Wilcox (Oracle)
  2021-04-30 14:55 ` [PATCH 8/8] mm: Fix struct page layout on 32-bit systems Matthew Wilcox (Oracle)
  2021-05-10 16:12 ` [PATCH 0/8] Folio Prequel patches Matteo Croce
  8 siblings, 0 replies; 14+ messages in thread
From: Matthew Wilcox (Oracle) @ 2021-04-30 14:55 UTC (permalink / raw)
  To: linux-mm, linux-fsdevel, akpm
  Cc: Matthew Wilcox (Oracle),
	William Kucharski, Vlastimil Babka, Anshuman Khandual

Now that compound_head() accepts a const struct page pointer, these two
functions can be marked as not modifying the page pointer they are passed.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: William Kucharski <william.kucharski@oracle.com>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
---
 include/linux/page_ref.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/page_ref.h b/include/linux/page_ref.h
index f3318f34fc54..7ad46f45df39 100644
--- a/include/linux/page_ref.h
+++ b/include/linux/page_ref.h
@@ -62,12 +62,12 @@ static inline void __page_ref_unfreeze(struct page *page, int v)
 
 #endif
 
-static inline int page_ref_count(struct page *page)
+static inline int page_ref_count(const struct page *page)
 {
 	return atomic_read(&page->_refcount);
 }
 
-static inline int page_count(struct page *page)
+static inline int page_count(const struct page *page)
 {
 	return atomic_read(&compound_head(page)->_refcount);
 }
-- 
2.30.2


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

* [PATCH 8/8] mm: Fix struct page layout on 32-bit systems
  2021-04-30 14:55 [PATCH 0/8] Folio Prequel patches Matthew Wilcox (Oracle)
                   ` (6 preceding siblings ...)
  2021-04-30 14:55 ` [PATCH 7/8] mm: Constify page_count and page_ref_count Matthew Wilcox (Oracle)
@ 2021-04-30 14:55 ` Matthew Wilcox (Oracle)
  2021-05-10 16:12 ` [PATCH 0/8] Folio Prequel patches Matteo Croce
  8 siblings, 0 replies; 14+ messages in thread
From: Matthew Wilcox (Oracle) @ 2021-04-30 14:55 UTC (permalink / raw)
  To: linux-mm, linux-fsdevel, akpm
  Cc: Matthew Wilcox (Oracle), Ilias Apalodimas, Jesper Dangaard Brouer

32-bit architectures which expect 8-byte alignment for 8-byte integers
and need 64-bit DMA addresses (arm, mips, ppc) had their struct page
inadvertently expanded in 2019.  When the dma_addr_t was added, it forced
the alignment of the union to 8 bytes, which inserted a 4 byte gap between
'flags' and the union.

Fix this by storing the dma_addr_t in one or two adjacent unsigned longs.
This restores the alignment to that of an unsigned long.  We always
store the low bits in the first word to prevent the PageTail bit from
being inadvertently set on a big endian platform.  If that happened,
get_user_pages_fast() racing against a page which was freed and
reallocated to the page_pool could dereference a bogus compound_head(),
which would be hard to trace back to this cause.

Fixes: c25fff7171be ("mm: add dma_addr_t to struct page")
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
 include/linux/mm_types.h |  4 ++--
 include/net/page_pool.h  | 12 +++++++++++-
 net/core/page_pool.c     | 12 +++++++-----
 3 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 6613b26a8894..5aacc1c10a45 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -97,10 +97,10 @@ struct page {
 		};
 		struct {	/* page_pool used by netstack */
 			/**
-			 * @dma_addr: might require a 64-bit value even on
+			 * @dma_addr: might require a 64-bit value on
 			 * 32-bit architectures.
 			 */
-			dma_addr_t dma_addr;
+			unsigned long dma_addr[2];
 		};
 		struct {	/* slab, slob and slub */
 			union {
diff --git a/include/net/page_pool.h b/include/net/page_pool.h
index 6d517a37c18b..b4b6de909c93 100644
--- a/include/net/page_pool.h
+++ b/include/net/page_pool.h
@@ -198,7 +198,17 @@ static inline void page_pool_recycle_direct(struct page_pool *pool,
 
 static inline dma_addr_t page_pool_get_dma_addr(struct page *page)
 {
-	return page->dma_addr;
+	dma_addr_t ret = page->dma_addr[0];
+	if (sizeof(dma_addr_t) > sizeof(unsigned long))
+		ret |= (dma_addr_t)page->dma_addr[1] << 16 << 16;
+	return ret;
+}
+
+static inline void page_pool_set_dma_addr(struct page *page, dma_addr_t addr)
+{
+	page->dma_addr[0] = addr;
+	if (sizeof(dma_addr_t) > sizeof(unsigned long))
+		page->dma_addr[1] = upper_32_bits(addr);
 }
 
 static inline bool is_page_pool_compiled_in(void)
diff --git a/net/core/page_pool.c b/net/core/page_pool.c
index 9ec1aa9640ad..3c4c4c7a0402 100644
--- a/net/core/page_pool.c
+++ b/net/core/page_pool.c
@@ -174,8 +174,10 @@ static void page_pool_dma_sync_for_device(struct page_pool *pool,
 					  struct page *page,
 					  unsigned int dma_sync_size)
 {
+	dma_addr_t dma_addr = page_pool_get_dma_addr(page);
+
 	dma_sync_size = min(dma_sync_size, pool->p.max_len);
-	dma_sync_single_range_for_device(pool->p.dev, page->dma_addr,
+	dma_sync_single_range_for_device(pool->p.dev, dma_addr,
 					 pool->p.offset, dma_sync_size,
 					 pool->p.dma_dir);
 }
@@ -195,7 +197,7 @@ static bool page_pool_dma_map(struct page_pool *pool, struct page *page)
 	if (dma_mapping_error(pool->p.dev, dma))
 		return false;
 
-	page->dma_addr = dma;
+	page_pool_set_dma_addr(page, dma);
 
 	if (pool->p.flags & PP_FLAG_DMA_SYNC_DEV)
 		page_pool_dma_sync_for_device(pool, page, pool->p.max_len);
@@ -331,13 +333,13 @@ void page_pool_release_page(struct page_pool *pool, struct page *page)
 		 */
 		goto skip_dma_unmap;
 
-	dma = page->dma_addr;
+	dma = page_pool_get_dma_addr(page);
 
-	/* When page is unmapped, it cannot be returned our pool */
+	/* When page is unmapped, it cannot be returned to our pool */
 	dma_unmap_page_attrs(pool->p.dev, dma,
 			     PAGE_SIZE << pool->p.order, pool->p.dma_dir,
 			     DMA_ATTR_SKIP_CPU_SYNC);
-	page->dma_addr = 0;
+	page_pool_set_dma_addr(page, 0);
 skip_dma_unmap:
 	/* This may be the last page returned, releasing the pool, so
 	 * it is not safe to reference pool afterwards.
-- 
2.30.2


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

* Re: [PATCH 0/8] Folio Prequel patches
  2021-04-30 14:55 [PATCH 0/8] Folio Prequel patches Matthew Wilcox (Oracle)
                   ` (7 preceding siblings ...)
  2021-04-30 14:55 ` [PATCH 8/8] mm: Fix struct page layout on 32-bit systems Matthew Wilcox (Oracle)
@ 2021-05-10 16:12 ` Matteo Croce
  2021-05-10 16:29   ` Matthew Wilcox
  8 siblings, 1 reply; 14+ messages in thread
From: Matteo Croce @ 2021-05-10 16:12 UTC (permalink / raw)
  To: Matthew Wilcox (Oracle); +Cc: linux-mm, linux-fsdevel, akpm

On Fri, 30 Apr 2021 15:55:41 +0100
"Matthew Wilcox (Oracle)" <willy@infradead.org> wrote:

> These patches have all been posted before and not picked up yet.  I've
> built the folio patches on top of them; while they are not necessarily
> prerequisites in the conceptual sense, I'm not convinced that the
> folio patches will build without them.  The nth_page patch is purely
> an efficiency question, while patch 5 ("Make compound_head
> const-preserving") is required for the current implementation of
> page_folio().  Patch 8 ("Fix struct page layout on 32-bit systems")
> is required for the struct folio layout to match struct page layout
> on said 32-bit systems (arm, mips, ppc).
> 
> They are on top of next-20210430
> 

I'm running them since a couple days on an arm64 machine which uses the
page_pool API. No issues so far.

Regards,
-- 
per aspera ad upstream

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

* Re: [PATCH 0/8] Folio Prequel patches
  2021-05-10 16:12 ` [PATCH 0/8] Folio Prequel patches Matteo Croce
@ 2021-05-10 16:29   ` Matthew Wilcox
  0 siblings, 0 replies; 14+ messages in thread
From: Matthew Wilcox @ 2021-05-10 16:29 UTC (permalink / raw)
  To: Matteo Croce; +Cc: linux-mm, linux-fsdevel, akpm

On Mon, May 10, 2021 at 06:12:45PM +0200, Matteo Croce wrote:
> On Fri, 30 Apr 2021 15:55:41 +0100
> "Matthew Wilcox (Oracle)" <willy@infradead.org> wrote:
> 
> > These patches have all been posted before and not picked up yet.  I've
> > built the folio patches on top of them; while they are not necessarily
> > prerequisites in the conceptual sense, I'm not convinced that the
> > folio patches will build without them.  The nth_page patch is purely
> > an efficiency question, while patch 5 ("Make compound_head
> > const-preserving") is required for the current implementation of
> > page_folio().  Patch 8 ("Fix struct page layout on 32-bit systems")
> > is required for the struct folio layout to match struct page layout
> > on said 32-bit systems (arm, mips, ppc).
> > 
> > They are on top of next-20210430
> > 
> 
> I'm running them since a couple days on an arm64 machine which uses the
> page_pool API. No issues so far.

Thanks!  Andrew picked up the first seven of these patches last night,
and I resent the eighth one today:

https://lore.kernel.org/linux-mm/20210510153211.1504886-1-willy@infradead.org/


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

* Re: [PATCH 3/8] mm/debug: Factor PagePoisoned out of __dump_page
  2021-04-30 14:55 ` [PATCH 3/8] mm/debug: Factor PagePoisoned out of __dump_page Matthew Wilcox (Oracle)
@ 2021-05-12  3:29   ` Kefeng Wang
  2021-05-12  3:38     ` Matthew Wilcox
  0 siblings, 1 reply; 14+ messages in thread
From: Kefeng Wang @ 2021-05-12  3:29 UTC (permalink / raw)
  To: Matthew Wilcox (Oracle), linux-mm, linux-fsdevel, akpm
  Cc: William Kucharski, Vlastimil Babka, Anshuman Khandual



On 2021/4/30 22:55, Matthew Wilcox (Oracle) wrote:
> Move the PagePoisoned test into dump_page().  Skip the hex print
> for poisoned pages -- we know they're full of ffffffff.  Move the
> reason printing from __dump_page() to dump_page().
> 
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> Reviewed-by: William Kucharski <william.kucharski@oracle.com>
> Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
> Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
>   mm/debug.c | 25 +++++++------------------
>   1 file changed, 7 insertions(+), 18 deletions(-)
> 
> diff --git a/mm/debug.c b/mm/debug.c
> index 84cdcd0f7bd3..e73fe0a8ec3d 100644
> --- a/mm/debug.c
> +++ b/mm/debug.c
> @@ -42,11 +42,10 @@ const struct trace_print_flags vmaflag_names[] = {
>   	{0, NULL}
>   };
>   
> -static void __dump_page(struct page *page, const char *reason)
> +static void __dump_page(struct page *page)
>   {
>   	struct page *head = compound_head(page);
>   	struct address_space *mapping;
> -	bool page_poisoned = PagePoisoned(page);
>   	bool compound = PageCompound(page);
>   	/*
>   	 * Accessing the pageblock without the zone lock. It could change to
> @@ -58,16 +57,6 @@ static void __dump_page(struct page *page, const char *reason)
>   	int mapcount;
>   	char *type = "";
>   
> -	/*
> -	 * If struct page is poisoned don't access Page*() functions as that
> -	 * leads to recursive loop. Page*() check for poisoned pages, and calls
> -	 * dump_page() when detected.
> -	 */
> -	if (page_poisoned) {
> -		pr_warn("page:%px is uninitialized and poisoned", page);
> -		goto hex_only;
> -	}
> -
>   	if (page < head || (page >= head + MAX_ORDER_NR_PAGES)) {
>   		/*
>   		 * Corrupt page, so we cannot call page_mapping. Instead, do a
> @@ -173,8 +162,6 @@ static void __dump_page(struct page *page, const char *reason)
>   
>   	pr_warn("%sflags: %#lx(%pGp)%s\n", type, head->flags, &head->flags,
>   		page_cma ? " CMA" : "");
> -
> -hex_only:
>   	print_hex_dump(KERN_WARNING, "raw: ", DUMP_PREFIX_NONE, 32,
>   			sizeof(unsigned long), page,
>   			sizeof(struct page), false);
> @@ -182,14 +169,16 @@ static void __dump_page(struct page *page, const char *reason)
>   		print_hex_dump(KERN_WARNING, "head: ", DUMP_PREFIX_NONE, 32,
>   			sizeof(unsigned long), head,
>   			sizeof(struct page), false);
> -
> -	if (reason)
> -		pr_warn("page dumped because: %s\n", reason);
>   }
>   
>   void dump_page(struct page *page, const char *reason)
>   {
> -	__dump_page(page, reason);
> +	if (PagePoisoned(page))
> +		pr_warn("page:%p is uninitialized and poisoned", page);
> +	else
> +		__dump_page(page);

Hi Matthew, dump_page_owenr() should be called when !PagePoisoned, right?


> +	if (reason)
> +		pr_warn("page dumped because: %s\n", reason);
>   	dump_page_owner(page);
>   }
>   EXPORT_SYMBOL(dump_page);
> 

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

* Re: [PATCH 3/8] mm/debug: Factor PagePoisoned out of __dump_page
  2021-05-12  3:29   ` Kefeng Wang
@ 2021-05-12  3:38     ` Matthew Wilcox
  2021-05-12  3:53       ` Kefeng Wang
  0 siblings, 1 reply; 14+ messages in thread
From: Matthew Wilcox @ 2021-05-12  3:38 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: linux-mm, linux-fsdevel, akpm, William Kucharski,
	Vlastimil Babka, Anshuman Khandual

On Wed, May 12, 2021 at 11:29:06AM +0800, Kefeng Wang wrote:
> >   void dump_page(struct page *page, const char *reason)
> >   {
> > -	__dump_page(page, reason);
> > +	if (PagePoisoned(page))
> > +		pr_warn("page:%p is uninitialized and poisoned", page);
> > +	else
> > +		__dump_page(page);
> 
> Hi Matthew, dump_page_owenr() should be called when !PagePoisoned, right?
> 
> 
> > +	if (reason)
> > +		pr_warn("page dumped because: %s\n", reason);
> >   	dump_page_owner(page);
> >   }
> >   EXPORT_SYMBOL(dump_page);

dump_page_owner() is called whether the page is Poisoned or not ...
both before and after this patch.  Is there a problem with that?


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

* Re: [PATCH 3/8] mm/debug: Factor PagePoisoned out of __dump_page
  2021-05-12  3:38     ` Matthew Wilcox
@ 2021-05-12  3:53       ` Kefeng Wang
  0 siblings, 0 replies; 14+ messages in thread
From: Kefeng Wang @ 2021-05-12  3:53 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: linux-mm, linux-fsdevel, akpm, William Kucharski,
	Vlastimil Babka, Anshuman Khandual



On 2021/5/12 11:38, Matthew Wilcox wrote:
> On Wed, May 12, 2021 at 11:29:06AM +0800, Kefeng Wang wrote:
>>>    void dump_page(struct page *page, const char *reason)
>>>    {
>>> -	__dump_page(page, reason);
>>> +	if (PagePoisoned(page))
>>> +		pr_warn("page:%p is uninitialized and poisoned", page);
>>> +	else
>>> +		__dump_page(page);
>>
>> Hi Matthew, dump_page_owenr() should be called when !PagePoisoned, right?
>>
>>
>>> +	if (reason)
>>> +		pr_warn("page dumped because: %s\n", reason);
>>>    	dump_page_owner(page);
>>>    }
>>>    EXPORT_SYMBOL(dump_page);
> 
> dump_page_owner() is called whether the page is Poisoned or not ...
> both before and after this patch.  Is there a problem with that?

struct page_ext *page_ext = lookup_page_ext(page);

   unsigned long pfn = page_to_pfn(page);
   struct mem_section *section = __pfn_to_section(pfn);
   if (!section->page_ext)

If page is Poisoned, I guess the section maybe NULL,
so section->page_ext may meet NULL pointer dereference,
is it possible?


> 
> .
> 

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

end of thread, other threads:[~2021-05-12  3:53 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-30 14:55 [PATCH 0/8] Folio Prequel patches Matthew Wilcox (Oracle)
2021-04-30 14:55 ` [PATCH 1/8] mm: Optimise nth_page for contiguous memmap Matthew Wilcox (Oracle)
2021-04-30 14:55 ` [PATCH 2/8] mm: Make __dump_page static Matthew Wilcox (Oracle)
2021-04-30 14:55 ` [PATCH 3/8] mm/debug: Factor PagePoisoned out of __dump_page Matthew Wilcox (Oracle)
2021-05-12  3:29   ` Kefeng Wang
2021-05-12  3:38     ` Matthew Wilcox
2021-05-12  3:53       ` Kefeng Wang
2021-04-30 14:55 ` [PATCH 4/8] mm/page_owner: Constify dump_page_owner Matthew Wilcox (Oracle)
2021-04-30 14:55 ` [PATCH 5/8] mm: Make compound_head const-preserving Matthew Wilcox (Oracle)
2021-04-30 14:55 ` [PATCH 6/8] mm: Constify get_pfnblock_flags_mask and get_pfnblock_migratetype Matthew Wilcox (Oracle)
2021-04-30 14:55 ` [PATCH 7/8] mm: Constify page_count and page_ref_count Matthew Wilcox (Oracle)
2021-04-30 14:55 ` [PATCH 8/8] mm: Fix struct page layout on 32-bit systems Matthew Wilcox (Oracle)
2021-05-10 16:12 ` [PATCH 0/8] Folio Prequel patches Matteo Croce
2021-05-10 16:29   ` Matthew Wilcox

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.