* [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; 4+ 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 related [flat|nested] 4+ 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; 4+ 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] 4+ 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 [not found] ` <CAOzc2pxGyZUGju07aid06FpSgFFA45tr0wU-yH4yUipKMPaP=Q@mail.gmail.com> 0 siblings, 1 reply; 4+ 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] 4+ messages in thread
[parent not found: <CAOzc2pxGyZUGju07aid06FpSgFFA45tr0wU-yH4yUipKMPaP=Q@mail.gmail.com>]
* Re: [PATCH] mm: page_alloc: check the order of compound page event when the order is 0 [not found] ` <CAOzc2pxGyZUGju07aid06FpSgFFA45tr0wU-yH4yUipKMPaP=Q@mail.gmail.com> @ 2023-10-16 7:23 ` Hyesoo Yu 0 siblings, 0 replies; 4+ 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] 4+ messages in thread
end of thread, other threads:[~2023-10-16 7:33 UTC | newest]
Thread overview: 4+ 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
[not found] ` <CAOzc2pxGyZUGju07aid06FpSgFFA45tr0wU-yH4yUipKMPaP=Q@mail.gmail.com>
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