forked from Minki/linux
mm/vmalloc: fix numa spreading for large hash tables
Eric Dumazet reported a strange numa spreading info in [1], and found commit121e6f3258
("mm/vmalloc: hugepage vmalloc mappings") introduced this issue [2]. Dig into the difference before and after this patch, page allocation has some difference: before: alloc_large_system_hash __vmalloc __vmalloc_node(..., NUMA_NO_NODE, ...) __vmalloc_node_range __vmalloc_area_node alloc_page /* because NUMA_NO_NODE, so choose alloc_page branch */ alloc_pages_current alloc_page_interleave /* can be proved by print policy mode */ after: alloc_large_system_hash __vmalloc __vmalloc_node(..., NUMA_NO_NODE, ...) __vmalloc_node_range __vmalloc_area_node alloc_pages_node /* choose nid by nuam_mem_id() */ __alloc_pages_node(nid, ....) So after commit121e6f3258
("mm/vmalloc: hugepage vmalloc mappings"), it will allocate memory in current node instead of interleaving allocate memory. Link: https://lore.kernel.org/linux-mm/CANn89iL6AAyWhfxdHO+jaT075iOa3XcYn9k6JJc7JR2XYn6k_Q@mail.gmail.com/ [1] Link: https://lore.kernel.org/linux-mm/CANn89iLofTR=AK-QOZY87RdUZENCZUT4O6a0hvhu3_EwRMerOg@mail.gmail.com/ [2] Link: https://lkml.kernel.org/r/20211021080744.874701-2-chenwandun@huawei.com Fixes:121e6f3258
("mm/vmalloc: hugepage vmalloc mappings") Signed-off-by: Chen Wandun <chenwandun@huawei.com> Reported-by: Eric Dumazet <edumazet@google.com> Cc: Shakeel Butt <shakeelb@google.com> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Kefeng Wang <wangkefeng.wang@huawei.com> Cc: Hanjun Guo <guohanjun@huawei.com> Cc: Uladzislau Rezki <urezki@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
855d44434f
commit
ffb29b1c25
15
mm/vmalloc.c
15
mm/vmalloc.c
@ -2816,6 +2816,8 @@ vm_area_alloc_pages(gfp_t gfp, int nid,
|
||||
unsigned int order, unsigned int nr_pages, struct page **pages)
|
||||
{
|
||||
unsigned int nr_allocated = 0;
|
||||
struct page *page;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* For order-0 pages we make use of bulk allocator, if
|
||||
@ -2823,7 +2825,7 @@ vm_area_alloc_pages(gfp_t gfp, int nid,
|
||||
* to fails, fallback to a single page allocator that is
|
||||
* more permissive.
|
||||
*/
|
||||
if (!order) {
|
||||
if (!order && nid != NUMA_NO_NODE) {
|
||||
while (nr_allocated < nr_pages) {
|
||||
unsigned int nr, nr_pages_request;
|
||||
|
||||
@ -2848,7 +2850,7 @@ vm_area_alloc_pages(gfp_t gfp, int nid,
|
||||
if (nr != nr_pages_request)
|
||||
break;
|
||||
}
|
||||
} else
|
||||
} else if (order)
|
||||
/*
|
||||
* Compound pages required for remap_vmalloc_page if
|
||||
* high-order pages.
|
||||
@ -2856,11 +2858,12 @@ vm_area_alloc_pages(gfp_t gfp, int nid,
|
||||
gfp |= __GFP_COMP;
|
||||
|
||||
/* High-order pages or fallback path if "bulk" fails. */
|
||||
while (nr_allocated < nr_pages) {
|
||||
struct page *page;
|
||||
int i;
|
||||
|
||||
page = alloc_pages_node(nid, gfp, order);
|
||||
while (nr_allocated < nr_pages) {
|
||||
if (nid == NUMA_NO_NODE)
|
||||
page = alloc_pages(gfp, order);
|
||||
else
|
||||
page = alloc_pages_node(nid, gfp, order);
|
||||
if (unlikely(!page))
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user