Commit c200d900 authored by Patrick Wang's avatar Patrick Wang Committed by akpm

mm: kmemleak: remove kmemleak_not_leak_phys() and the min_count argument to kmemleak_alloc_phys()

Patch series "mm: kmemleak: store objects allocated with physical address
separately and check when scan", v4.

The kmemleak_*_phys() interface uses "min_low_pfn" and "max_low_pfn" to
check address.  But on some architectures, kmemleak_*_phys() is called
before those two variables initialized.  The following steps will be
taken:

1) Add OBJECT_PHYS flag and rbtree for the objects allocated
   with physical address
2) Store physical address in objects if allocated with OBJECT_PHYS
3) Check the boundary when scan instead of in kmemleak_*_phys()

This patch set will solve:
https://lore.kernel.org/r/20220527032504.30341-1-yee.lee@mediatek.com
https://lore.kernel.org/r/9dd08bb5-f39e-53d8-f88d-bec598a08c93@gmail.com

v3: https://lore.kernel.org/r/20220609124950.1694394-1-patrick.wang.shcn@gmail.com
v2: https://lore.kernel.org/r/20220603035415.1243913-1-patrick.wang.shcn@gmail.com
v1: https://lore.kernel.org/r/20220531150823.1004101-1-patrick.wang.shcn@gmail.com


This patch (of 4):

Remove the unused kmemleak_not_leak_phys() function.  And remove the
min_count argument to kmemleak_alloc_phys() function, assume it's 0.

Link: https://lkml.kernel.org/r/20220611035551.1823303-1-patrick.wang.shcn@gmail.com
Link: https://lkml.kernel.org/r/20220611035551.1823303-2-patrick.wang.shcn@gmail.comSigned-off-by: default avatarPatrick Wang <patrick.wang.shcn@gmail.com>
Suggested-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Reviewed-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Cc: Yee Lee <yee.lee@mediatek.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent ed913b05
...@@ -174,7 +174,6 @@ mapping: ...@@ -174,7 +174,6 @@ mapping:
- ``kmemleak_alloc_phys`` - ``kmemleak_alloc_phys``
- ``kmemleak_free_part_phys`` - ``kmemleak_free_part_phys``
- ``kmemleak_not_leak_phys``
- ``kmemleak_ignore_phys`` - ``kmemleak_ignore_phys``
Dealing with false positives/negatives Dealing with false positives/negatives
......
...@@ -529,7 +529,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, ...@@ -529,7 +529,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n", pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n",
uname, &base, (unsigned long)(size / SZ_1M)); uname, &base, (unsigned long)(size / SZ_1M));
if (!nomap) if (!nomap)
kmemleak_alloc_phys(base, size, 0, 0); kmemleak_alloc_phys(base, size, 0);
} }
else else
pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n",
......
...@@ -29,10 +29,9 @@ extern void kmemleak_not_leak(const void *ptr) __ref; ...@@ -29,10 +29,9 @@ extern void kmemleak_not_leak(const void *ptr) __ref;
extern void kmemleak_ignore(const void *ptr) __ref; extern void kmemleak_ignore(const void *ptr) __ref;
extern void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) __ref; extern void kmemleak_scan_area(const void *ptr, size_t size, gfp_t gfp) __ref;
extern void kmemleak_no_scan(const void *ptr) __ref; extern void kmemleak_no_scan(const void *ptr) __ref;
extern void kmemleak_alloc_phys(phys_addr_t phys, size_t size, int min_count, extern void kmemleak_alloc_phys(phys_addr_t phys, size_t size,
gfp_t gfp) __ref; gfp_t gfp) __ref;
extern void kmemleak_free_part_phys(phys_addr_t phys, size_t size) __ref; extern void kmemleak_free_part_phys(phys_addr_t phys, size_t size) __ref;
extern void kmemleak_not_leak_phys(phys_addr_t phys) __ref;
extern void kmemleak_ignore_phys(phys_addr_t phys) __ref; extern void kmemleak_ignore_phys(phys_addr_t phys) __ref;
static inline void kmemleak_alloc_recursive(const void *ptr, size_t size, static inline void kmemleak_alloc_recursive(const void *ptr, size_t size,
...@@ -107,15 +106,12 @@ static inline void kmemleak_no_scan(const void *ptr) ...@@ -107,15 +106,12 @@ static inline void kmemleak_no_scan(const void *ptr)
{ {
} }
static inline void kmemleak_alloc_phys(phys_addr_t phys, size_t size, static inline void kmemleak_alloc_phys(phys_addr_t phys, size_t size,
int min_count, gfp_t gfp) gfp_t gfp)
{ {
} }
static inline void kmemleak_free_part_phys(phys_addr_t phys, size_t size) static inline void kmemleak_free_part_phys(phys_addr_t phys, size_t size)
{ {
} }
static inline void kmemleak_not_leak_phys(phys_addr_t phys)
{
}
static inline void kmemleak_ignore_phys(phys_addr_t phys) static inline void kmemleak_ignore_phys(phys_addr_t phys)
{ {
} }
......
...@@ -1125,15 +1125,13 @@ EXPORT_SYMBOL(kmemleak_no_scan); ...@@ -1125,15 +1125,13 @@ EXPORT_SYMBOL(kmemleak_no_scan);
* address argument * address argument
* @phys: physical address of the object * @phys: physical address of the object
* @size: size of the object * @size: size of the object
* @min_count: minimum number of references to this object.
* See kmemleak_alloc()
* @gfp: kmalloc() flags used for kmemleak internal memory allocations * @gfp: kmalloc() flags used for kmemleak internal memory allocations
*/ */
void __ref kmemleak_alloc_phys(phys_addr_t phys, size_t size, int min_count, void __ref kmemleak_alloc_phys(phys_addr_t phys, size_t size, gfp_t gfp)
gfp_t gfp)
{ {
if (PHYS_PFN(phys) >= min_low_pfn && PHYS_PFN(phys) < max_low_pfn) if (PHYS_PFN(phys) >= min_low_pfn && PHYS_PFN(phys) < max_low_pfn)
kmemleak_alloc(__va(phys), size, min_count, gfp); /* assume min_count 0 */
kmemleak_alloc(__va(phys), size, 0, gfp);
} }
EXPORT_SYMBOL(kmemleak_alloc_phys); EXPORT_SYMBOL(kmemleak_alloc_phys);
...@@ -1151,18 +1149,6 @@ void __ref kmemleak_free_part_phys(phys_addr_t phys, size_t size) ...@@ -1151,18 +1149,6 @@ void __ref kmemleak_free_part_phys(phys_addr_t phys, size_t size)
} }
EXPORT_SYMBOL(kmemleak_free_part_phys); EXPORT_SYMBOL(kmemleak_free_part_phys);
/**
* kmemleak_not_leak_phys - similar to kmemleak_not_leak but taking a physical
* address argument
* @phys: physical address of the object
*/
void __ref kmemleak_not_leak_phys(phys_addr_t phys)
{
if (PHYS_PFN(phys) >= min_low_pfn && PHYS_PFN(phys) < max_low_pfn)
kmemleak_not_leak(__va(phys));
}
EXPORT_SYMBOL(kmemleak_not_leak_phys);
/** /**
* kmemleak_ignore_phys - similar to kmemleak_ignore but taking a physical * kmemleak_ignore_phys - similar to kmemleak_ignore but taking a physical
* address argument * address argument
......
...@@ -1345,8 +1345,8 @@ __next_mem_pfn_range_in_zone(u64 *idx, struct zone *zone, ...@@ -1345,8 +1345,8 @@ __next_mem_pfn_range_in_zone(u64 *idx, struct zone *zone,
* from the regions with mirroring enabled and then retried from any * from the regions with mirroring enabled and then retried from any
* memory region. * memory region.
* *
* In addition, function sets the min_count to 0 using kmemleak_alloc_phys for * In addition, function using kmemleak_alloc_phys for allocated boot
* allocated boot memory block, so that it is never reported as leaks. * memory block, it is never reported as leaks.
* *
* Return: * Return:
* Physical address of allocated memory block on success, %0 on failure. * Physical address of allocated memory block on success, %0 on failure.
...@@ -1398,12 +1398,12 @@ phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size, ...@@ -1398,12 +1398,12 @@ phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
*/ */
if (end != MEMBLOCK_ALLOC_NOLEAKTRACE) if (end != MEMBLOCK_ALLOC_NOLEAKTRACE)
/* /*
* The min_count is set to 0 so that memblock allocated * Memblock allocated blocks are never reported as
* blocks are never reported as leaks. This is because many * leaks. This is because many of these blocks are
* of these blocks are only referred via the physical * only referred via the physical address which is
* address which is not looked up by kmemleak. * not looked up by kmemleak.
*/ */
kmemleak_alloc_phys(found, size, 0, 0); kmemleak_alloc_phys(found, size, 0);
return found; return found;
} }
......
...@@ -7,7 +7,7 @@ static inline void kmemleak_free_part_phys(phys_addr_t phys, size_t size) ...@@ -7,7 +7,7 @@ static inline void kmemleak_free_part_phys(phys_addr_t phys, size_t size)
} }
static inline void kmemleak_alloc_phys(phys_addr_t phys, size_t size, static inline void kmemleak_alloc_phys(phys_addr_t phys, size_t size,
int min_count, gfp_t gfp) gfp_t gfp)
{ {
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment