#define pr_fmt(fmt) …
#include <linux/debugobjects.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/sched/task_stack.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/hash.h>
#include <linux/kmemleak.h>
#include <linux/cpu.h>
#define ODEBUG_HASH_BITS …
#define ODEBUG_HASH_SIZE …
#define ODEBUG_POOL_SIZE …
#define ODEBUG_POOL_MIN_LEVEL …
#define ODEBUG_POOL_PERCPU_SIZE …
#define ODEBUG_BATCH_SIZE …
#define ODEBUG_CHUNK_SHIFT …
#define ODEBUG_CHUNK_SIZE …
#define ODEBUG_CHUNK_MASK …
#define ODEBUG_FREE_WORK_MAX …
#define ODEBUG_FREE_WORK_DELAY …
struct debug_bucket { … };
struct debug_percpu_free { … };
static DEFINE_PER_CPU(struct debug_percpu_free, percpu_obj_pool);
static struct debug_bucket obj_hash[ODEBUG_HASH_SIZE];
static struct debug_obj obj_static_pool[ODEBUG_POOL_SIZE] __initdata;
static DEFINE_RAW_SPINLOCK(pool_lock);
static HLIST_HEAD(obj_pool);
static HLIST_HEAD(obj_to_free);
static int obj_pool_min_free = …;
static int obj_pool_free = …;
static int obj_pool_used;
static int obj_pool_max_used;
static bool obj_freeing;
static int obj_nr_tofree;
static int __data_racy debug_objects_maxchain __read_mostly;
static int __data_racy __maybe_unused debug_objects_maxchecked __read_mostly;
static int __data_racy debug_objects_fixups __read_mostly;
static int __data_racy debug_objects_warnings __read_mostly;
static int __data_racy debug_objects_enabled __read_mostly
= …;
static int __data_racy debug_objects_pool_size __read_mostly
= …;
static int __data_racy debug_objects_pool_min_level __read_mostly
= …;
static const struct debug_obj_descr *descr_test __read_mostly;
static struct kmem_cache *obj_cache __ro_after_init;
static int debug_objects_allocated;
static int debug_objects_freed;
static void free_obj_work(struct work_struct *work);
static DECLARE_DELAYED_WORK(debug_obj_work, free_obj_work);
static int __init enable_object_debug(char *str)
{ … }
static int __init disable_object_debug(char *str)
{ … }
early_param(…);
early_param(…);
static const char *obj_states[ODEBUG_STATE_MAX] = …;
static void fill_pool(void)
{ … }
static struct debug_obj *lookup_object(void *addr, struct debug_bucket *b)
{ … }
static struct debug_obj *__alloc_object(struct hlist_head *list)
{ … }
static struct debug_obj *
alloc_object(void *addr, struct debug_bucket *b, const struct debug_obj_descr *descr)
{ … }
static void free_obj_work(struct work_struct *work)
{ … }
static void __free_object(struct debug_obj *obj)
{ … }
static void free_object(struct debug_obj *obj)
{ … }
#ifdef CONFIG_HOTPLUG_CPU
static int object_cpu_offline(unsigned int cpu)
{ … }
#endif
static void debug_objects_oom(void)
{ … }
static struct debug_bucket *get_bucket(unsigned long addr)
{ … }
static void debug_print_object(struct debug_obj *obj, char *msg)
{ … }
static bool
debug_object_fixup(bool (*fixup)(void *addr, enum debug_obj_state state),
void * addr, enum debug_obj_state state)
{ … }
static void debug_object_is_on_stack(void *addr, int onstack)
{ … }
static struct debug_obj *lookup_object_or_alloc(void *addr, struct debug_bucket *b,
const struct debug_obj_descr *descr,
bool onstack, bool alloc_ifstatic)
{ … }
static void debug_objects_fill_pool(void)
{ … }
static void
__debug_object_init(void *addr, const struct debug_obj_descr *descr, int onstack)
{ … }
void debug_object_init(void *addr, const struct debug_obj_descr *descr)
{ … }
EXPORT_SYMBOL_GPL(…);
void debug_object_init_on_stack(void *addr, const struct debug_obj_descr *descr)
{ … }
EXPORT_SYMBOL_GPL(…);
int debug_object_activate(void *addr, const struct debug_obj_descr *descr)
{ … }
EXPORT_SYMBOL_GPL(…);
void debug_object_deactivate(void *addr, const struct debug_obj_descr *descr)
{ … }
EXPORT_SYMBOL_GPL(…);
void debug_object_destroy(void *addr, const struct debug_obj_descr *descr)
{ … }
EXPORT_SYMBOL_GPL(…);
void debug_object_free(void *addr, const struct debug_obj_descr *descr)
{ … }
EXPORT_SYMBOL_GPL(…);
void debug_object_assert_init(void *addr, const struct debug_obj_descr *descr)
{ … }
EXPORT_SYMBOL_GPL(…);
void
debug_object_active_state(void *addr, const struct debug_obj_descr *descr,
unsigned int expect, unsigned int next)
{ … }
EXPORT_SYMBOL_GPL(…);
#ifdef CONFIG_DEBUG_OBJECTS_FREE
static void __debug_check_no_obj_freed(const void *address, unsigned long size)
{ … }
void debug_check_no_obj_freed(const void *address, unsigned long size)
{ … }
#endif
#ifdef CONFIG_DEBUG_FS
static int debug_stats_show(struct seq_file *m, void *v)
{ … }
DEFINE_SHOW_ATTRIBUTE(…);
static int __init debug_objects_init_debugfs(void)
{ … }
__initcall(debug_objects_init_debugfs);
#else
static inline void debug_objects_init_debugfs(void) { }
#endif
#ifdef CONFIG_DEBUG_OBJECTS_SELFTEST
struct self_test { … };
static __initconst const struct debug_obj_descr descr_type_test;
static bool __init is_static_object(void *addr)
{ … }
static bool __init fixup_init(void *addr, enum debug_obj_state state)
{ … }
static bool __init fixup_activate(void *addr, enum debug_obj_state state)
{ … }
static bool __init fixup_destroy(void *addr, enum debug_obj_state state)
{ … }
static bool __init fixup_free(void *addr, enum debug_obj_state state)
{ … }
static int __init
check_results(void *addr, enum debug_obj_state state, int fixups, int warnings)
{ … }
static __initconst const struct debug_obj_descr descr_type_test = …;
static __initdata struct self_test obj = …;
static void __init debug_objects_selftest(void)
{ … }
#else
static inline void debug_objects_selftest(void) { }
#endif
void __init debug_objects_early_init(void)
{ … }
static int __init debug_objects_replace_static_objects(void)
{ … }
void __init debug_objects_mem_init(void)
{ … }