wlan-ap-Telecominfraproject/feeds/qca/ipq53xx/files-6.1/lib/debug_mem_usage.c
John Crispin 008ca9618d
Some checks failed
Build OpenWrt/uCentral images / build (cig_wf186h) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf186w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf188n) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf189) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cig_wf196) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cybertan_eww631-a1) (push) Has been cancelled
Build OpenWrt/uCentral images / build (cybertan_eww631-b1) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap101) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap102) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap104) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap105) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap111) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_eap112) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101-6e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (edgecore_oap101e-6e) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_3) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4x_w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xe) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xi) (push) Has been cancelled
Build OpenWrt/uCentral images / build (hfcl_ion4xi_w) (push) Has been cancelled
Build OpenWrt/uCentral images / build (indio_um-305ax) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sercomm_ap72tip) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630c-311g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630w-211g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (sonicfi_rap630w-311g) (push) Has been cancelled
Build OpenWrt/uCentral images / build (udaya_a6-id2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (udaya_a6-od2) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr5018) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr6018) (push) Has been cancelled
Build OpenWrt/uCentral images / build (wallys_dr6018-v4) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_ax820) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_ax840) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap640) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap650) (push) Has been cancelled
Build OpenWrt/uCentral images / build (yuncore_fap655) (push) Has been cancelled
Build OpenWrt/uCentral images / trigger-testing (push) Has been cancelled
Build OpenWrt/uCentral images / create-x64_vm-ami (push) Has been cancelled
ipq95xx: import ath12.4-cs kernel and drivers
Signed-off-by: John Crispin <john@phrozen.org>
2024-10-20 09:25:13 +02:00

144 lines
3.3 KiB
C

/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2021, 2023, Qualcomm Innovation Center, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/debugobjects.h>
#include <linux/slab.h>
#include <linux/hash.h>
#define ODEBUG_HASH_BITS 14
#define ODEBUG_HASH_SIZE (1 << ODEBUG_HASH_BITS)
#define ODEBUG_CHUNK_SHIFT PAGE_SHIFT
int debug_mem_usage_enabled = 1;
struct debug_bucket {
struct hlist_head list;
raw_spinlock_t lock;
};
static struct debug_bucket mem_trace_hash[ODEBUG_HASH_SIZE];
static struct kmem_cache *obj_trace_cache;
static int __init disable_mem_usage_debug(char *str)
{
debug_mem_usage_enabled = 0;
return 0;
}
early_param("skip_mem_usage_tracking", disable_mem_usage_debug);
static struct debug_obj_trace *lookup_object_with_trace(void *addr,
struct debug_bucket *b)
{
struct debug_obj_trace *trace_obj;
hlist_for_each_entry(trace_obj, &b->list, node) {
if (trace_obj->addr == addr)
return trace_obj;
}
return NULL;
}
static struct debug_obj_trace *
alloc_object_trace(void *addr, struct debug_bucket *b)
{
struct debug_obj_trace *new = NULL;
gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
new = kmem_cache_zalloc(obj_trace_cache, gfp);
if (!new)
return new;
hlist_add_head(&new->node, &b->list);
return new;
}
static struct debug_bucket *get_bucket(unsigned long addr)
{
unsigned long hash;
hash = hash_long((addr >> ODEBUG_CHUNK_SHIFT), ODEBUG_HASH_BITS);
return &mem_trace_hash[hash];
}
void debug_object_trace_init(void *addr, void **stack, size_t size)
{
struct debug_bucket *db;
unsigned long flags;
struct debug_obj_trace *trace_obj;
db = get_bucket((unsigned long) addr);
raw_spin_lock_irqsave(&db->lock, flags);
trace_obj = lookup_object_with_trace(addr, db);
if (!trace_obj) {
trace_obj = alloc_object_trace(addr, db);
if (!trace_obj) {
pr_err("debug object allocation for size %zu failed\n",
sizeof(struct debug_obj_trace));
raw_spin_unlock_irqrestore(&db->lock, flags);
return;
}
trace_obj->addr = addr;
memcpy(trace_obj->stack, stack, 9 * sizeof(void *));
trace_obj->size = size;
} else {
memcpy(trace_obj->stack, stack, 9 * sizeof(void *));
trace_obj->size = size;
}
raw_spin_unlock_irqrestore(&db->lock, flags);
}
void debug_object_trace_free(void *addr)
{
struct debug_bucket *db;
struct debug_obj_trace *trace_obj;
unsigned long flags;
db = get_bucket((unsigned long) addr);
raw_spin_lock_irqsave(&db->lock, flags);
trace_obj = lookup_object_with_trace(addr, db);
if (!trace_obj)
goto out_unlock;
trace_obj->size = 0;
out_unlock:
raw_spin_unlock_irqrestore(&db->lock, flags);
}
void __init debug_mem_usage_init(void)
{
int i;
if (!debug_mem_usage_enabled)
return;
obj_trace_cache = kmem_cache_create("obj_trace_cache",
sizeof(struct debug_obj_trace), 0, 0, NULL);
for (i = 0; i < ODEBUG_HASH_SIZE; i++)
raw_spin_lock_init(&mem_trace_hash[i].lock);
}