Skip to content

Commit 8e0c4ab

Browse files
Patrick Wangakpm00
authored andcommitted
mm: kmemleak: add OBJECT_PHYS flag for objects allocated with physical address
Add OBJECT_PHYS flag for object. This flag is used to identify the objects allocated with physical address. The create_object_phys() function is added as well to set that flag and is used by kmemleak_alloc_phys(). Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Patrick Wang <[email protected]> Suggested-by: Catalin Marinas <[email protected]> Reviewed-by: Catalin Marinas <[email protected]> Cc: Yee Lee <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent c200d90 commit 8e0c4ab

File tree

1 file changed

+31
-9
lines changed

1 file changed

+31
-9
lines changed

mm/kmemleak.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ struct kmemleak_object {
172172
#define OBJECT_NO_SCAN (1 << 2)
173173
/* flag set to fully scan the object when scan_area allocation failed */
174174
#define OBJECT_FULL_SCAN (1 << 3)
175+
/* flag set for object allocated with physical address */
176+
#define OBJECT_PHYS (1 << 4)
175177

176178
#define HEX_PREFIX " "
177179
/* number of bytes to print per line; must be 16 or 32 */
@@ -574,8 +576,9 @@ static int __save_stack_trace(unsigned long *trace)
574576
* Create the metadata (struct kmemleak_object) corresponding to an allocated
575577
* memory block and add it to the object_list and object_tree_root.
576578
*/
577-
static struct kmemleak_object *create_object(unsigned long ptr, size_t size,
578-
int min_count, gfp_t gfp)
579+
static struct kmemleak_object *__create_object(unsigned long ptr, size_t size,
580+
int min_count, gfp_t gfp,
581+
bool is_phys)
579582
{
580583
unsigned long flags;
581584
struct kmemleak_object *object, *parent;
@@ -595,7 +598,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size,
595598
INIT_HLIST_HEAD(&object->area_list);
596599
raw_spin_lock_init(&object->lock);
597600
atomic_set(&object->use_count, 1);
598-
object->flags = OBJECT_ALLOCATED;
601+
object->flags = OBJECT_ALLOCATED | (is_phys ? OBJECT_PHYS : 0);
599602
object->pointer = ptr;
600603
object->size = kfence_ksize((void *)ptr) ?: size;
601604
object->excess_ref = 0;
@@ -662,6 +665,20 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size,
662665
return object;
663666
}
664667

668+
/* Create kmemleak object which allocated with virtual address. */
669+
static struct kmemleak_object *create_object(unsigned long ptr, size_t size,
670+
int min_count, gfp_t gfp)
671+
{
672+
return __create_object(ptr, size, min_count, gfp, false);
673+
}
674+
675+
/* Create kmemleak object which allocated with physical address. */
676+
static struct kmemleak_object *create_object_phys(unsigned long ptr, size_t size,
677+
int min_count, gfp_t gfp)
678+
{
679+
return __create_object(ptr, size, min_count, gfp, true);
680+
}
681+
665682
/*
666683
* Mark the object as not allocated and schedule RCU freeing via put_object().
667684
*/
@@ -728,11 +745,11 @@ static void delete_object_part(unsigned long ptr, size_t size)
728745
start = object->pointer;
729746
end = object->pointer + object->size;
730747
if (ptr > start)
731-
create_object(start, ptr - start, object->min_count,
732-
GFP_KERNEL);
748+
__create_object(start, ptr - start, object->min_count,
749+
GFP_KERNEL, object->flags & OBJECT_PHYS);
733750
if (ptr + size < end)
734-
create_object(ptr + size, end - ptr - size, object->min_count,
735-
GFP_KERNEL);
751+
__create_object(ptr + size, end - ptr - size, object->min_count,
752+
GFP_KERNEL, object->flags & OBJECT_PHYS);
736753

737754
__delete_object(object);
738755
}
@@ -1129,9 +1146,14 @@ EXPORT_SYMBOL(kmemleak_no_scan);
11291146
*/
11301147
void __ref kmemleak_alloc_phys(phys_addr_t phys, size_t size, gfp_t gfp)
11311148
{
1149+
pr_debug("%s(0x%pa, %zu)\n", __func__, &phys, size);
1150+
11321151
if (PHYS_PFN(phys) >= min_low_pfn && PHYS_PFN(phys) < max_low_pfn)
1133-
/* assume min_count 0 */
1134-
kmemleak_alloc(__va(phys), size, 0, gfp);
1152+
/*
1153+
* Create object with OBJECT_PHYS flag and
1154+
* assume min_count 0.
1155+
*/
1156+
create_object_phys((unsigned long)__va(phys), size, 0, gfp);
11351157
}
11361158
EXPORT_SYMBOL(kmemleak_alloc_phys);
11371159

0 commit comments

Comments
 (0)