ANDROID: mm: add get_each_object_track function
Add and export get_each_object_track which helps in looping through all the slab objects of a page and gets the track structure of each object, also make track_item and track structure public, these will be used by the minidump module to get slab owner info. Includes commit 0e00d7c46b36 ("ANDROID: mm/slub: Fix Kasan issue with for_each_object_track") from android13-5.15 as a bug fix. Bug: 199236943 Change-Id: Id9922b57053be277f8042ad8199fbbf9faa984ef Signed-off-by: Vijayanand Jitta <vjitta@codeaurora.org> Signed-off-by: Jaskaran Singh <quic_jasksing@quicinc.com>
This commit is contained in:
parent
173c09996a
commit
97b7d85866
31
mm/slab.h
31
mm/slab.h
@ -282,6 +282,24 @@ void __kmem_cache_free(struct kmem_cache *s, void *x, unsigned long caller);
|
||||
|
||||
gfp_t kmalloc_fix_flags(gfp_t flags);
|
||||
|
||||
#ifdef CONFIG_SLUB
|
||||
/*
|
||||
* Tracking user of a slab.
|
||||
*/
|
||||
#define TRACK_ADDRS_COUNT 16
|
||||
struct track {
|
||||
unsigned long addr; /* Called from address */
|
||||
#ifdef CONFIG_STACKDEPOT
|
||||
depot_stack_handle_t handle;
|
||||
#endif
|
||||
int cpu; /* Was running on cpu */
|
||||
int pid; /* Pid context */
|
||||
unsigned long when; /* When did the operation occur */
|
||||
};
|
||||
|
||||
enum track_item { TRACK_ALLOC, TRACK_FREE };
|
||||
#endif
|
||||
|
||||
/* Functions provided by the slab allocators */
|
||||
int __kmem_cache_create(struct kmem_cache *, slab_flags_t flags);
|
||||
|
||||
@ -399,6 +417,10 @@ DECLARE_STATIC_KEY_FALSE(slub_debug_enabled);
|
||||
#endif
|
||||
extern void print_tracking(struct kmem_cache *s, void *object);
|
||||
long validate_slab_cache(struct kmem_cache *s);
|
||||
extern unsigned long get_each_object_track(struct kmem_cache *s,
|
||||
struct page *page, enum track_item alloc,
|
||||
int (*fn)(const struct kmem_cache *, const void *,
|
||||
const struct track *, void *), void *private);
|
||||
static inline bool __slub_debug_enabled(void)
|
||||
{
|
||||
return static_branch_unlikely(&slub_debug_enabled);
|
||||
@ -407,6 +429,15 @@ static inline bool __slub_debug_enabled(void)
|
||||
static inline void print_tracking(struct kmem_cache *s, void *object)
|
||||
{
|
||||
}
|
||||
#ifdef CONFIG_SLUB
|
||||
static inline unsigned long get_each_object_track(struct kmem_cache *s,
|
||||
struct page *page, enum track_item alloc,
|
||||
int (*fn)(const struct kmem_cache *, const void *,
|
||||
const struct track *, void *), void *private)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
static inline bool __slub_debug_enabled(void)
|
||||
{
|
||||
return false;
|
||||
|
52
mm/slub.c
52
mm/slub.c
@ -282,22 +282,6 @@ static inline bool kmem_cache_has_cpu_partial(struct kmem_cache *s)
|
||||
/* Use cmpxchg_double */
|
||||
#define __CMPXCHG_DOUBLE ((slab_flags_t __force)0x40000000U)
|
||||
|
||||
/*
|
||||
* Tracking user of a slab.
|
||||
*/
|
||||
#define TRACK_ADDRS_COUNT 16
|
||||
struct track {
|
||||
unsigned long addr; /* Called from address */
|
||||
#ifdef CONFIG_STACKDEPOT
|
||||
depot_stack_handle_t handle;
|
||||
#endif
|
||||
int cpu; /* Was running on cpu */
|
||||
int pid; /* Pid context */
|
||||
unsigned long when; /* When did the operation occur */
|
||||
};
|
||||
|
||||
enum track_item { TRACK_ALLOC, TRACK_FREE };
|
||||
|
||||
#ifdef CONFIG_SYSFS
|
||||
static int sysfs_slab_add(struct kmem_cache *);
|
||||
static int sysfs_slab_alias(struct kmem_cache *, const char *);
|
||||
@ -725,6 +709,42 @@ static struct track *get_track(struct kmem_cache *s, void *object,
|
||||
return kasan_reset_tag(p + alloc);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will be used to loop through all the slab objects in
|
||||
* a page to give track structure for each object, the function fn will
|
||||
* be using this track structure and extract required info into its private
|
||||
* data, the return value will be the number of track structures that are
|
||||
* processed.
|
||||
*/
|
||||
unsigned long get_each_object_track(struct kmem_cache *s,
|
||||
struct page *page, enum track_item alloc,
|
||||
int (*fn)(const struct kmem_cache *, const void *,
|
||||
const struct track *, void *), void *private)
|
||||
{
|
||||
void *p;
|
||||
struct track *t;
|
||||
int ret;
|
||||
unsigned long num_track = 0;
|
||||
struct slab *p_slab = page_slab(page);
|
||||
|
||||
if (!slub_debug || !(s->flags & SLAB_STORE_USER) || !p_slab)
|
||||
return 0;
|
||||
|
||||
slab_lock(p_slab);
|
||||
for_each_object(p, s, page_address(page), p_slab->objects) {
|
||||
t = get_track(s, p, alloc);
|
||||
metadata_access_enable();
|
||||
ret = fn(s, p, t, private);
|
||||
metadata_access_disable();
|
||||
if (ret < 0)
|
||||
break;
|
||||
num_track += 1;
|
||||
}
|
||||
slab_unlock(p_slab);
|
||||
return num_track;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(get_each_object_track, MINIDUMP);
|
||||
|
||||
#ifdef CONFIG_STACKDEPOT
|
||||
static noinline depot_stack_handle_t set_track_prepare(void)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user