mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 13:14:07 +08:00
mm/page_alloc: reuse tail struct pages for compound devmaps
Currently memmap_init_zone_device() ends up initializing 32768 pages when it only needs to initialize 128 given tail page reuse. That number is worse with 1GB compound pages, 262144 instead of 128. Update memmap_init_zone_device() to skip redundant initialization, detailed below. When a pgmap @vmemmap_shift is set, all pages are mapped at a given huge page alignment and use compound pages to describe them as opposed to a struct per 4K. With @vmemmap_shift > 0 and when struct pages are stored in ram (!altmap) most tail pages are reused. Consequently, the amount of unique struct pages is a lot smaller than the total amount of struct pages being mapped. The altmap path is left alone since it does not support memory savings based on compound pages devmap. Link: https://lkml.kernel.org/r/20220420155310.9712-6-joao.m.martins@oracle.com Signed-off-by: Joao Martins <joao.m.martins@oracle.com> Reviewed-by: Muchun Song <songmuchun@bytedance.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Jane Chu <jane.chu@oracle.com> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Matthew Wilcox <willy@infradead.org> Cc: Mike Kravetz <mike.kravetz@oracle.com> Cc: Vishal Verma <vishal.l.verma@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
4917f55b4e
commit
6fd3620b34
@ -6596,6 +6596,21 @@ static void __ref __init_zone_device_page(struct page *page, unsigned long pfn,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* With compound page geometry and when struct pages are stored in ram most
|
||||
* tail pages are reused. Consequently, the amount of unique struct pages to
|
||||
* initialize is a lot smaller that the total amount of struct pages being
|
||||
* mapped. This is a paired / mild layering violation with explicit knowledge
|
||||
* of how the sparse_vmemmap internals handle compound pages in the lack
|
||||
* of an altmap. See vmemmap_populate_compound_pages().
|
||||
*/
|
||||
static inline unsigned long compound_nr_pages(struct vmem_altmap *altmap,
|
||||
unsigned long nr_pages)
|
||||
{
|
||||
return is_power_of_2(sizeof(struct page)) &&
|
||||
!altmap ? 2 * (PAGE_SIZE / sizeof(struct page)) : nr_pages;
|
||||
}
|
||||
|
||||
static void __ref memmap_init_compound(struct page *head,
|
||||
unsigned long head_pfn,
|
||||
unsigned long zone_idx, int nid,
|
||||
@ -6660,7 +6675,7 @@ void __ref memmap_init_zone_device(struct zone *zone,
|
||||
continue;
|
||||
|
||||
memmap_init_compound(page, pfn, zone_idx, nid, pgmap,
|
||||
pfns_per_compound);
|
||||
compound_nr_pages(altmap, pfns_per_compound));
|
||||
}
|
||||
|
||||
pr_info("%s initialised %lu pages in %ums\n", __func__,
|
||||
|
Loading…
Reference in New Issue
Block a user