linuxOS_D21X/source/linux-5.10/drivers/dma-buf/heaps/mpp_debugfs.c
2024-11-29 16:13:46 +08:00

106 lines
2.5 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* MPP HEAP DebugFS Interface
*
* Copyright (c) 2023 Huahui Mai <huahui.mai@artinchip.com>
*/
#include <linux/debugfs.h>
#include <linux/list.h>
#include <linux/kernel.h>
#include <linux/mm_types.h>
#include <linux/genalloc.h>
#include "mpp_heap.h"
static int mpp_count_get(void *data, u64 *val)
{
unsigned long *p = data;
*val = *p;
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(mpp_count_fops, mpp_count_get, NULL, "%llu\n");
static int mpp_used_get(void *data, u64 *val)
{
struct mpp_heap *mpp = data;
struct gen_pool *pool = mpp->pool;
struct gen_pool_chunk *chunk;
unsigned long used;
rcu_read_lock();
list_for_each_entry_rcu(chunk, &(pool)->chunks, next_chunk)
used = bitmap_weight(chunk->bits, (int)mpp->count);
rcu_read_unlock();
*val = (u64)used;
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(mpp_used_fops, mpp_used_get, NULL, "%llu\n");
static int mpp_maxchunk_get(void *data, u64 *val)
{
struct mpp_heap *mpp = data;
struct gen_pool *pool = mpp->pool;
unsigned long bitmap_maxno = mpp->count;
unsigned long maxchunk = 0;
unsigned long start, end = 0;
struct gen_pool_chunk *chunk;
rcu_read_lock();
list_for_each_entry_rcu(chunk, &(pool)->chunks, next_chunk) {
for (;;) {
start = find_next_zero_bit(chunk->bits, bitmap_maxno, end);
if (start >= bitmap_maxno)
break;
end = find_next_bit(chunk->bits, bitmap_maxno, start);
maxchunk = max(end - start, maxchunk);
}
}
rcu_read_unlock();
*val = (u64)maxchunk;
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(mpp_maxchunk_fops, mpp_maxchunk_get, NULL, "%llu\n");
static int __init mpp_debugfs_init(void)
{
struct mpp_heap *mpp = mpp_debugfs;
struct gen_pool_chunk *chunk;
struct gen_pool *pool;
struct dentry *root;
size_t chunk_size;
int order;
if (!mpp)
return -EINVAL;
pool = mpp->pool;
order = pool->min_alloc_order;
root = debugfs_create_dir("mpp", NULL);
rcu_read_lock();
/* MPP HEAP has only one chunk */
list_for_each_entry_rcu(chunk, &(pool)->chunks, next_chunk) {
chunk_size = chunk->end_addr - chunk->start_addr + 1;
mpp->dfs_bitmap.array = (u32 *)chunk->bits;
mpp->dfs_bitmap.n_elements = DIV_ROUND_UP(chunk_size >> order,
BITS_PER_BYTE * sizeof(u32));
}
rcu_read_unlock();
mpp->count = chunk_size >> order;
debugfs_create_file("count", 0444, root, &mpp->count, &mpp_count_fops);
debugfs_create_file("used", 0444, root, mpp, &mpp_used_fops);
debugfs_create_file("maxchunk", 0444, root, mpp, &mpp_maxchunk_fops);
debugfs_create_u32_array("bitmap", 0444, root, &mpp->dfs_bitmap);
return 0;
}
late_initcall(mpp_debugfs_init);