From 193b19fb78bf0d7963cf6febbba28418c9322980 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Fri, 31 May 2024 15:45:01 +0200 Subject: [PATCH] lx_emul: support compound pages Issue #5236 --- .../src/lib/lx_emul/shadow/mm/page_alloc.c | 45 +++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/repos/dde_linux/src/lib/lx_emul/shadow/mm/page_alloc.c b/repos/dde_linux/src/lib/lx_emul/shadow/mm/page_alloc.c index 53aab8cb41..32db9de306 100644 --- a/repos/dde_linux/src/lib/lx_emul/shadow/mm/page_alloc.c +++ b/repos/dde_linux/src/lib/lx_emul/shadow/mm/page_alloc.c @@ -20,6 +20,34 @@ #include + +static void prepare_compound_page(struct page *page, unsigned int order, gfp_t gfp) +{ + int i; + + if (!order || !(gfp & __GFP_COMP)) + return; + + __SetPageHead(page); + set_compound_order(page, order); + for (i = 1; i < compound_nr(page); i++) + set_compound_head(&page[i], page); +} + + +static void liquidate_compound_page(struct page *page) +{ + int i; + + if (!PageHead(page)) + return; + + for (i = 1; i < compound_nr(page); i++) + clear_compound_head(&page[i]); + ClearPageHead(page); +} + + static void lx_free_pages(struct page *page, bool force) { void * const virt_addr = page_address(page); @@ -29,6 +57,8 @@ static void lx_free_pages(struct page *page, bool force) else if (!put_page_testzero(page)) return; + liquidate_compound_page(page); + lx_emul_mem_free(virt_addr); } @@ -48,7 +78,7 @@ void free_pages(unsigned long addr,unsigned int order) static struct page * lx_alloc_pages(unsigned const nr_pages) { - void const *ptr = lx_emul_mem_alloc_aligned(PAGE_SIZE*nr_pages, PAGE_SIZE); + void const *ptr = lx_emul_mem_alloc_aligned(PAGE_SIZE*nr_pages, nr_pages*PAGE_SIZE); struct page *page = lx_emul_virt_to_page(ptr); init_page_count(page); @@ -95,17 +125,26 @@ struct page * __alloc_pages(gfp_t gfp, unsigned int order, int preferred_nid, nodemask_t * nodemask) #endif { - return lx_alloc_pages(1u << order); + struct page *page = lx_alloc_pages(1u << order); + + if (!page) + return 0; + + prepare_compound_page(page, order, gfp); + + return page; } -unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order) +unsigned long __get_free_pages(gfp_t gfp, unsigned int order) { struct page *page = lx_alloc_pages(1u << order); if (!page) return 0; + prepare_compound_page(page, order, gfp); + return (unsigned long)page_address(page); }