Commit f0cd8087 authored by Guo Weikang's avatar Guo Weikang Committed by Euler
Browse files

mm/memmap: prevent double scanning of memmap by kmemleak

mainline inclusion
from mainline-v6.14-rc1
commit b2aad24b53333f1904a55d97e3fde2246ef05bb6
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IBK4CC

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b2aad24b53333f1904a55d97e3fde2246ef05bb6

--------------------------------

kmemleak explicitly scans the mem_map through the valid struct page
objects.  However, memmap_alloc() was also adding this memory to the gray
object list, causing it to be scanned twice.  Remove memmap_alloc() from
the scan list and add a comment to clarify the behavior.

Link: https://lore.kernel.org/lkml/CAOm6qn=FVeTpH54wGDFMHuCOeYtvoTx30ktnv9-w3Nh8RMofEA@mail.gmail.com/
Link: https://lkml.kernel.org/r/20250106021126.1678334-1-guoweikang.kernel@gmail.com


Signed-off-by: default avatarGuo Weikang <guoweikang.kernel@gmail.com>
Reviewed-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Cc: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarWang Lian <dev01404@linx-info.com>
parent f5ed0867
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -400,6 +400,10 @@ static inline int memblock_get_region_node(const struct memblock_region *r)
/* Flags for memblock allocation APIs */
#define MEMBLOCK_ALLOC_ANYWHERE	(~(phys_addr_t)0)
#define MEMBLOCK_ALLOC_ACCESSIBLE	0
/*
 *  MEMBLOCK_ALLOC_NOLEAKTRACE avoids kmemleak tracing. It implies
 *  MEMBLOCK_ALLOC_ACCESSIBLE
 */
#define MEMBLOCK_ALLOC_NOLEAKTRACE	1

/* We are using top down, so it is safe to use 0 here */
+6 −2
Original line number Diff line number Diff line
@@ -1642,13 +1642,17 @@ void __init *memmap_alloc(phys_addr_t size, phys_addr_t align,
{
	void *ptr;

	/*
	 * Kmemleak will explicitly scan mem_map by traversing all valid
	 * `struct *page`,so memblock does not need to be added to the scan list.
	 */
	if (exact_nid)
		ptr = memblock_alloc_exact_nid_raw(size, align, min_addr,
						   MEMBLOCK_ALLOC_ACCESSIBLE,
						   MEMBLOCK_ALLOC_NOLEAKTRACE,
						   nid);
	else
		ptr = memblock_alloc_try_nid_raw(size, align, min_addr,
						 MEMBLOCK_ALLOC_ACCESSIBLE,
						 MEMBLOCK_ALLOC_NOLEAKTRACE,
						 nid);

	if (ptr && size > 0)
+3 −2
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@
#include <asm/dma.h>
#include <asm/pgalloc.h>

#include "internal.h"

/*
 * Allocate a block of memory to be used to back the virtual memory map
 * or to back the page tables that are used to create the mapping.
@@ -42,8 +44,7 @@ static void * __ref __earlyonly_bootmem_alloc(int node,
				unsigned long align,
				unsigned long goal)
{
	return memblock_alloc_try_nid_raw(size, align, goal,
					       MEMBLOCK_ALLOC_ACCESSIBLE, node);
	return memmap_alloc(size, align, goal, node, false);
}

void * __meminit vmemmap_alloc_block(unsigned long size, int node)