linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] mm: page_alloc: check the order of compound page event when the order is 0
       [not found] <CGME20231012012153epcas2p34b8e9e8a898ace8d50411cadf937ef5d@epcas2p3.samsung.com>
@ 2023-10-12  1:11 ` Hyesoo Yu
  2023-10-13 20:54   ` Vishal Moola
  0 siblings, 1 reply; 5+ messages in thread
From: Hyesoo Yu @ 2023-10-12  1:11 UTC (permalink / raw)
  Cc: Hyesoo Yu, Andrew Morton, linux-mm, linux-kernel

For compound pages, the head sets the PG_head flag and
the tail sets the compound_head to indicate the head page.
If a user allocates a compound page and frees it with a different
order, the compound page information will not be properly
initialized. To detect this problem, compound_page(page) and
the order are compared, but it is not checked when the order is 0.
That error should be checked regardless of the order.

Signed-off-by: Hyesoo Yu <hyesoo.yu@samsung.com>
---
 mm/page_alloc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 95546f376302..fc92ac93c7c8 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1078,6 +1078,7 @@ static __always_inline bool free_pages_prepare(struct page *page,
 	int bad = 0;
 	bool skip_kasan_poison = should_skip_kasan_poison(page, fpi_flags);
 	bool init = want_init_on_free();
+	bool compound = PageCompound(page);
 
 	VM_BUG_ON_PAGE(PageTail(page), page);
 
@@ -1096,16 +1097,15 @@ static __always_inline bool free_pages_prepare(struct page *page,
 		return false;
 	}
 
+	VM_BUG_ON_PAGE(compound && compound_order(page) != order, page);
+
 	/*
 	 * Check tail pages before head page information is cleared to
 	 * avoid checking PageCompound for order-0 pages.
 	 */
 	if (unlikely(order)) {
-		bool compound = PageCompound(page);
 		int i;
 
-		VM_BUG_ON_PAGE(compound && compound_order(page) != order, page);
-
 		if (compound)
 			page[1].flags &= ~PAGE_FLAGS_SECOND;
 		for (i = 1; i < (1 << order); i++) {
-- 
2.25.1



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

* Re: [PATCH] mm: page_alloc: check the order of compound page event when the order is 0
  2023-10-12  1:11 ` [PATCH] mm: page_alloc: check the order of compound page event when the order is 0 Hyesoo Yu
@ 2023-10-13 20:54   ` Vishal Moola
  2023-10-16  0:32     ` Hyesoo Yu
  0 siblings, 1 reply; 5+ messages in thread
From: Vishal Moola @ 2023-10-13 20:54 UTC (permalink / raw)
  To: Hyesoo Yu; +Cc: Andrew Morton, linux-mm, linux-kernel

On Thu, Oct 12, 2023 at 10:11:06AM +0900, Hyesoo Yu wrote:
> For compound pages, the head sets the PG_head flag and
> the tail sets the compound_head to indicate the head page.
> If a user allocates a compound page and frees it with a different
> order, the compound page information will not be properly
> initialized. To detect this problem, compound_page(page) and
> the order are compared, but it is not checked when the order is 0.
> That error should be checked regardless of the order.

I believe all compound pages are order >= 1, so this error can't occur
when the order is 0.


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

* Re: [PATCH] mm: page_alloc: check the order of compound page event when the order is 0
  2023-10-13 20:54   ` Vishal Moola
@ 2023-10-16  0:32     ` Hyesoo Yu
  2023-10-16  3:28       ` Vishal Moola
  0 siblings, 1 reply; 5+ messages in thread
From: Hyesoo Yu @ 2023-10-16  0:32 UTC (permalink / raw)
  To: Vishal Moola; +Cc: Andrew Morton, linux-mm, linux-kernel

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

On Fri, Oct 13, 2023 at 01:54:08PM -0700, Vishal Moola wrote:
> On Thu, Oct 12, 2023 at 10:11:06AM +0900, Hyesoo Yu wrote:
> > For compound pages, the head sets the PG_head flag and
> > the tail sets the compound_head to indicate the head page.
> > If a user allocates a compound page and frees it with a different
> > order, the compound page information will not be properly
> > initialized. To detect this problem, compound_page(page) and
> > the order are compared, but it is not checked when the order is 0.
> > That error should be checked regardless of the order.
> 
> I believe all compound pages are order >= 1, so this error can't occur
> when the order is 0.
> 

Yes. All compound pages are order >= 1.
However if the user uses the API incorrectly, the order value could be zero.

For example,

addr = alloc_pages(GFP_COMP, 2);
free_pages(addr, 0);

(struct page[16])0xFFFFFFFE21715100 = (
(flags = 0x4000000000000200, lru = (next = 0x0, prev = 0xDEAD000000000122),//  Clear PG_head
(flags = 0x4000000000000000, lru = (next = 0xFFFFFFFE21715101, prev = 0xFFFFFFFF00000201),  // Remain compound head

It is memory leak, and it also makes system stability problem.
on isolation_single_pageblock, That case makes infinite loops.

for (pfn = start_pfn; pfn < boundary_pfn; ) {
	if (PageCompound(page)) { // page[1] is compound page
		struct page *head = compound_head(page); // page[0]
		unsigned long head_pfn = page_to_pfn(head);
		unsigned long nr_pages = compound_nr(head); // nr_pages is 1 since page[0] is not compound page.

 		if (head_pfn + nr_pages <= boundary_pfn) {
			pfn = head_pfn + nr_pages; // pfn is set as page[1].
			continue;
		}
}

So, I guess, we have to check the incorrect use in free_pages_prepare.

Thanks,
Hyesoo Yu.

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



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

* Re: [PATCH] mm: page_alloc: check the order of compound page event when the order is 0
  2023-10-16  0:32     ` Hyesoo Yu
@ 2023-10-16  3:28       ` Vishal Moola
  2023-10-16  7:23         ` Hyesoo Yu
  0 siblings, 1 reply; 5+ messages in thread
From: Vishal Moola @ 2023-10-16  3:28 UTC (permalink / raw)
  To: Hyesoo Yu; +Cc: Andrew Morton, linux-mm, linux-kernel

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

On Sun, Oct 15, 2023 at 5:42 PM Hyesoo Yu <hyesoo.yu@samsung.com> wrote:
>
> On Fri, Oct 13, 2023 at 01:54:08PM -0700, Vishal Moola wrote:
> > On Thu, Oct 12, 2023 at 10:11:06AM +0900, Hyesoo Yu wrote:
> > > For compound pages, the head sets the PG_head flag and
> > > the tail sets the compound_head to indicate the head page.
> > > If a user allocates a compound page and frees it with a different
> > > order, the compound page information will not be properly
> > > initialized. To detect this problem, compound_page(page) and

s/compound_page/compound_order/

> > > the order are compared, but it is not checked when the order is 0.
> > > That error should be checked regardless of the order.

With this many mentions of "the order", it is easy to misinterpret "the
order"
to be referencing the page order rather than the order of pages we are
trying
to free. I recommend replacing "the order" with "the order argument" or
something similar for clarity.

> > I believe all compound pages are order >= 1, so this error can't occur
> > when the order is 0.
> >
>
> Yes. All compound pages are order >= 1.
> However if the user uses the API incorrectly, the order value could be
zero.

I see, thanks for clarifying that.

With the commit message changes above:
Reviewed-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>

> For example,
>
> addr = alloc_pages(GFP_COMP, 2);
> free_pages(addr, 0);
>
> (struct page[16])0xFFFFFFFE21715100 = (
> (flags = 0x4000000000000200, lru = (next = 0x0, prev =
0xDEAD000000000122),//  Clear PG_head
> (flags = 0x4000000000000000, lru = (next = 0xFFFFFFFE21715101, prev =
0xFFFFFFFF00000201),  // Remain compound head
>
> It is memory leak, and it also makes system stability problem.
> on isolation_single_pageblock, That case makes infinite loops.
>
> for (pfn = start_pfn; pfn < boundary_pfn; ) {
>         if (PageCompound(page)) { // page[1] is compound page
>                 struct page *head = compound_head(page); // page[0]
>                 unsigned long head_pfn = page_to_pfn(head);
>                 unsigned long nr_pages = compound_nr(head); // nr_pages
is 1 since page[0] is not compound page.
>
>                 if (head_pfn + nr_pages <= boundary_pfn) {
>                         pfn = head_pfn + nr_pages; // pfn is set as
page[1].
>                         continue;
>                 }
> }
>
> So, I guess, we have to check the incorrect use in free_pages_prepare.
>
> Thanks,
> Hyesoo Yu.

[-- Attachment #2: Type: text/html, Size: 3174 bytes --]

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

* Re: [PATCH] mm: page_alloc: check the order of compound page event when the order is 0
  2023-10-16  3:28       ` Vishal Moola
@ 2023-10-16  7:23         ` Hyesoo Yu
  0 siblings, 0 replies; 5+ messages in thread
From: Hyesoo Yu @ 2023-10-16  7:23 UTC (permalink / raw)
  To: Vishal Moola; +Cc: Andrew Morton, linux-mm, linux-kernel

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

On Sun, Oct 15, 2023 at 08:28:18PM -0700, Vishal Moola wrote:
> On Sun, Oct 15, 2023 at 5:42 PM Hyesoo Yu <hyesoo.yu@samsung.com> wrote:
> >
> > On Fri, Oct 13, 2023 at 01:54:08PM -0700, Vishal Moola wrote:
> > > On Thu, Oct 12, 2023 at 10:11:06AM +0900, Hyesoo Yu wrote:
> > > > For compound pages, the head sets the PG_head flag and
> > > > the tail sets the compound_head to indicate the head page.
> > > > If a user allocates a compound page and frees it with a different
> > > > order, the compound page information will not be properly
> > > > initialized. To detect this problem, compound_page(page) and
> 
> s/compound_page/compound_order/
> 
> > > > the order are compared, but it is not checked when the order is 0.
> > > > That error should be checked regardless of the order.
> 
> With this many mentions of "the order", it is easy to misinterpret "the
> order"
> to be referencing the page order rather than the order of pages we are
> trying
> to free. I recommend replacing "the order" with "the order argument" or
> something similar for clarity.
> 

What a good idea! I'll replace that. Thanks for your comments.

> > > I believe all compound pages are order >= 1, so this error can't occur
> > > when the order is 0.
> > >
> >
> > Yes. All compound pages are order >= 1.
> > However if the user uses the API incorrectly, the order value could be
> zero.
> 
> I see, thanks for clarifying that.
> 
> With the commit message changes above:
> Reviewed-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
> 

Okay, Thanks for review.

Regards.
Hyesoo Yu.

> > For example,
> >
> > addr = alloc_pages(GFP_COMP, 2);
> > free_pages(addr, 0);
> >
> > (struct page[16])0xFFFFFFFE21715100 = (
> > (flags = 0x4000000000000200, lru = (next = 0x0, prev =
> 0xDEAD000000000122),//  Clear PG_head
> > (flags = 0x4000000000000000, lru = (next = 0xFFFFFFFE21715101, prev =
> 0xFFFFFFFF00000201),  // Remain compound head
> >
> > It is memory leak, and it also makes system stability problem.
> > on isolation_single_pageblock, That case makes infinite loops.
> >
> > for (pfn = start_pfn; pfn < boundary_pfn; ) {
> >         if (PageCompound(page)) { // page[1] is compound page
> >                 struct page *head = compound_head(page); // page[0]
> >                 unsigned long head_pfn = page_to_pfn(head);
> >                 unsigned long nr_pages = compound_nr(head); // nr_pages
> is 1 since page[0] is not compound page.
> >
> >                 if (head_pfn + nr_pages <= boundary_pfn) {
> >                         pfn = head_pfn + nr_pages; // pfn is set as
> page[1].
> >                         continue;
> >                 }
> > }
> >
> > So, I guess, we have to check the incorrect use in free_pages_prepare.
> >
> > Thanks,
> > Hyesoo Yu.

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



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

end of thread, other threads:[~2023-10-16  7:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20231012012153epcas2p34b8e9e8a898ace8d50411cadf937ef5d@epcas2p3.samsung.com>
2023-10-12  1:11 ` [PATCH] mm: page_alloc: check the order of compound page event when the order is 0 Hyesoo Yu
2023-10-13 20:54   ` Vishal Moola
2023-10-16  0:32     ` Hyesoo Yu
2023-10-16  3:28       ` Vishal Moola
2023-10-16  7:23         ` Hyesoo Yu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox