CMA ๋๋ฒ๊น (CMA DebugFS)
๊ฐ์ (Overview)
CMA DebugFS๋ ๋ฐํ์์ CMA ์์ญ์ ์ํ๋ฅผ ๊ด์ฐฐํ๊ณ ํ
์คํธํ ์ ์๋ ๋๋ฒ๊น
์ธํฐํ์ด์ค์
๋๋ค. CONFIG_CMA_DEBUGFS ์ต์
์ด ํ์ฑํ๋๋ฉด /sys/kernel/debug/cma/ ๋๋ ํ ๋ฆฌ์ ๊ฐ CMA ์์ญ๋ณ ํ์ ๋๋ ํ ๋ฆฌ๊ฐ ์์ฑ๋๋ฉฐ, ํ ๋น/ํด์ ํ
์คํธ, ๋นํธ๋งต ๋คํ, ์ฌ์ฉ๋ ํ์ธ ๋ฑ์ ์์
์ ์ํํ ์ ์์ต๋๋ค. ์ด ์ธํฐํ์ด์ค๋ ์ฃผ๋ก CMA ์์ญ ์ค๊ณ ์ ๋ฉํฐ ๋ ์ธ์ง ๊ตฌ์ฑ์ด ์ฌ๋ฐ๋ฅธ์ง ํ์ธํ๊ฑฐ๋, unmovable ํ์ด์ง ์นจํฌ๋ก ์ธํ ํ ๋น ์คํจ๋ฅผ ์ง๋จํ ๋ ํ์ฉ๋ฉ๋๋ค.
Linux 7.0์์ CMA DebugFS๋ ๋ฉํฐ ๋ ์ธ์ง(multi-range) ์ง์์ ๋ฐ์ํ์ฌ ๊ฐ ๋ ์ธ์ง๋ณ ๋นํธ๋งต๊ณผ base PFN์ ๊ฐ๋ณ์ ์ผ๋ก ๋
ธ์ถํฉ๋๋ค. ๋ํ cma_alloc/cma_free ๋๋ฒ๊ทธ ํ์ผ์ ํตํด ์๋์ผ๋ก ํ ๋น/ํด์ ๋ฅผ ์ํํ ์ ์์ด, ์ค์ ๋๋ผ์ด๋ฒ ์์ด๋ CMA ๋์์ ๊ฒ์ฆํ ์ ์์ต๋๋ค.
์์ค ํ์ผ:
mm/cma_debug.c โ DebugFS ์ธํฐํ์ด์ค ๊ตฌํ (212์ค)
mm/cma.h โ ๋ด๋ถ ๊ตฌ์กฐ์ฒด (cma, cma_memrange)
include/linux/cma.h โ ์ธ๋ถ API ํค๋
๋น ๋ฅธ ์ ๊ฒ ๋ช ๋ น
# CMA ์์ญ ๋๋ฒ๊ทธ ๋๋ ํ ๋ฆฌ ํ์ธ
sudo ls /sys/kernel/debug/cma/
# CMA ์์ญ๋ณ ์ด ํ์ด์ง ์ / ์ฌ์ฉ ์ค์ธ ํ์ด์ง ์ / ์ต๋ ์ฐ์ ๋น ๋ธ๋ก
cat /sys/kernel/debug/cma/cma-0/count
cat /sys/kernel/debug/cma/cma-0/used
cat /sys/kernel/debug/cma/cma-0/maxchunk
# order_per_bit ํ์ธ (๋นํธ๋งต ํด์๋)
cat /sys/kernel/debug/cma/cma-0/order_per_bit
# ๋ฉํฐ ๋ ์ธ์ง ๊ฐ ๋ฒ์์ base PFN ํ์ธ
cat /sys/kernel/debug/cma/cma-0/ranges/0/base_pfn
cat /sys/kernel/debug/cma/cma-0/ranges/1/base_pfn
# ๋ฉํฐ ๋ ์ธ์ง ๋นํธ๋งต ํ์ธ (ํ
์คํธ๋ก ์ถ๋ ฅ)
cat /sys/kernel/debug/cma/cma-0/ranges/0/bitmap
# ์๋ ํ ๋น ํ
์คํธ (16 ํ์ด์ง ํ ๋น)
echo 16 | sudo tee /sys/kernel/debug/cma/cma-0/alloc
# ์๋ ํด์ ํ
์คํธ (16 ํ์ด์ง ํด์ )
echo 16 | sudo tee /sys/kernel/debug/cma/cma-0/free
# /proc/meminfo์์ CMA ํํฉ ํ์ธ
cat /proc/meminfo | grep -i cma
# CMA pageblock ๋ง์ด๊ทธ๋ ์ด์
ํ์
ํ์ธ
cat /proc/pagetypeinfo | grep CMA
# dmesg์์ CMA ๊ด๋ จ ๋ฉ์์ง ํ์ธ
dmesg | grep -i cma
ํต์ฌ ์๋ฃ๊ตฌ์กฐ
struct cma_mem โ ๋๋ฒ๊ทธ ํ ๋น ์ถ์ (`mm/cma_debug.c:18-22`)
struct cma_mem {
struct hlist_node node; // ํด์ ๋ฆฌ์คํธ ๋
ธ๋ (mem_head ์ฐ๊ฒฐ)
struct page *p; // ํ ๋น๋ ํ์ด์ง ์์ ์ฃผ์
unsigned long n; // ํ ๋น๋ ํ์ด์ง ์
};
์ค๋ช
: cma_alloc/cma_free ๋๋ฒ๊ทธ ํ์ผ์ ํตํด ์๋ ํ ๋น๋ ํ์ด์ง ๋ธ๋ก์ ์ถ์ ํฉ๋๋ค. cma ๊ตฌ์กฐ์ฒด์ mem_head ํด์ ๋ฆฌ์คํธ์ ์ฐ๊ฒฐ๋๋ฉฐ, free ํธ์ถ ์ ์ด ๋ฆฌ์คํธ์์ ๊บผ๋ด์ด ์์ฐจ์ ์ผ๋ก ํด์ ํฉ๋๋ค.
struct cma โ CMA ์์ญ ๊ด๋ฆฌ์ (`mm/cma.h:39-65`)
struct cma {
unsigned long count; // ์ด ํ์ด์ง ์
unsigned long available_count; // ์ฌ์ฉ ๊ฐ๋ฅํ ํ์ด์ง ์
unsigned int order_per_bit; // ๋นํธ๋งต 1๋นํธ๋น ํ์ด์ง ์ (2^order)
spinlock_t lock; // ๋นํธ๋งต ๋์์ฑ ์ ์ด
struct mutex alloc_mutex; // ํ ๋น ์ ์ง๋ ฌํ
struct hlist_head mem_head; // ๋๋ฒ๊ทธ ํ ๋น ๋ฆฌ์คํธ (CONFIG_CMA_DEBUGFS)
spinlock_t mem_head_lock; // mem_head ๋์์ฑ ์ ์ด
char name[CMA_MAX_NAME]; // ์์ญ ์ด๋ฆ
int nranges; // ์ค์ ๋ ์ธ์ง ์ (1~8)
struct cma_memrange ranges[CMA_MAX_RANGES]; // ๋ฉํฐ ๋ ์ธ์ง ๋ฐฐ์ด
unsigned long flags; // CMA_ACTIVATED ๋ฑ ํ๋๊ทธ
int nid; // NUMA ๋
ธ๋ ID
};
์ค๋ช
: mem_head์ mem_head_lock์ CONFIG_CMA_DEBUGFS๊ฐ ํ์ฑํ๋ ๋๋ง ์กด์ฌํ๋ฉฐ, ์๋ ํ ๋น๋ cma_mem ํญ๋ชฉ๋ค์ ํด์ ๋ฆฌ์คํธ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค. available_count๋ count - used๋ก ๊ณ์ฐ๋๋ฉฐ, cma_used_get()์ด ์ด ๊ฐ์ ์ฝ์ต๋๋ค.
struct cma_memrange โ ๊ฐ๋ณ ๋ฌผ๋ฆฌ ๋ฒ์ (`mm/cma.h:26-36`)
struct cma_memrange {
unsigned long base_pfn; // ๋ฒ์ ์์ PFN
unsigned long count; // ๋ฒ์ ๋ด ํ์ด์ง ์
union {
unsigned long early_pfn; // cma_reserve_early()์์ ์ฌ์ฉ
unsigned long *bitmap; // ํ์ฑํ ํ ํ ๋น ๋นํธ๋งต
};
struct debugfs_u32_array dfs_bitmap; // debugfs ๋นํธ๋งต ๋
ธ์ถ์ฉ
};
์ค๋ช
: dfs_bitmap์ cma_debugfs_add_one()์์ bitmap ํ๋๋ฅผ ์ง์ ํ ๋นํ์ฌ debugfs์ u32 ๋ฐฐ์ด๋ก ๋
ธ์ถํฉ๋๋ค. array๋ bitmap์ ์์ ์ฃผ์๋ฅผ, n_elements๋ cma_bitmap_maxno() ๊ณ์ฐ๊ฐ์ ์ ์ฅํฉ๋๋ค.
cma_debugfs_fops โ debugfs ํ์ผ ์ด์ ์ฒด๊ณ (`mm/cma_debug.c:24-32`)
static int cma_debugfs_get(void *data, u64 *val)
{
unsigned long *p = data;
*val = *p;
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(cma_debugfs_fops, cma_debugfs_get, NULL, "%llu\n");
์ค๋ช
: count, order_per_bit, base_pfn ๊ฐ์ ์ฝ๊ธฐ ์ ์ฉ ๊ฐ์ ํ์ํ ๋ ์ฌ์ฉ๋๋ ์ผ๋ฐ ๋๋ฒ๊ทธ ํ์ผ ์ด์ ์ฒด๊ณ์
๋๋ค. DEFINE_DEBUGFS_ATTRIBUTE ๋งคํฌ๋ก๋ก open, read, write ํธ๋ค๋ฌ๊ฐ ์๋ ์์ฑ๋ฉ๋๋ค.
ํต์ฌ ํจ์
1. `cma_debugfs_init()` โ ์ ์ฒด ์ด๊ธฐํ (`mm/cma_debug.c:200-211`)
static int __init cma_debugfs_init(void)
{
struct dentry *cma_debugfs_root;
int i;
cma_debugfs_root = debugfs_create_dir("cma", NULL);
for (i = 0; i < cma_area_count; i++)
cma_debugfs_add_one(&cma_areas[i], cma_debugfs_root);
return 0;
}
late_initcall(cma_debugfs_init);
์ญํ : /sys/kernel/debug/cma/ ๋ฃจํธ ๋๋ ํ ๋ฆฌ๋ฅผ ์์ฑํ๊ณ , ๋ฑ๋ก๋ ๋ชจ๋ CMA ์์ญ์ ๋ํด cma_debugfs_add_one()์ ํธ์ถํฉ๋๋ค.
๋ถ๊ธฐ ๋ก์ง:
1. late_initcall์์ ํธ์ถ โ ๋ชจ๋ CMA ์์ญ์ด ์ด๊ธฐํ๋ ํ ์คํ
2. cma_area_count๋งํผ ๋ฐ๋ณตํ๋ฉฐ ๊ฐ cma_areas[i]์ ๋ํ ๋๋ฒ๊ทธ ํ์ผ ์์ฑ
2. `cma_debugfs_add_one()` โ ์์ญ๋ณ ๋๋ฒ๊ทธ ํ์ผ ์์ฑ (`mm/cma_debug.c:161-198`)
static void cma_debugfs_add_one(struct cma *cma, struct dentry *root_dentry)
{
struct dentry *tmp, *dir, *rangedir;
int r;
char rdirname[12];
struct cma_memrange *cmr;
tmp = debugfs_create_dir(cma->name, root_dentry);
debugfs_create_file("alloc", 0200, tmp, cma, &cma_alloc_fops);
debugfs_create_file("free", 0200, tmp, cma, &cma_free_fops);
debugfs_create_file("count", 0444, tmp, &cma->count, &cma_debugfs_fops);
debugfs_create_file("order_per_bit", 0444, tmp,
&cma->order_per_bit, &cma_debugfs_fops);
debugfs_create_file("used", 0444, tmp, cma, &cma_used_fops);
debugfs_create_file("maxchunk", 0444, tmp, cma, &cma_maxchunk_fops);
rangedir = debugfs_create_dir("ranges", tmp);
for (r = 0; r < cma->nranges; r++) {
cmr = &cma->ranges[r];
snprintf(rdirname, sizeof(rdirname), "%d", r);
dir = debugfs_create_dir(rdirname, rangedir);
debugfs_create_file("base_pfn", 0444, dir,
&cmr->base_pfn, &cma_debugfs_fops);
cmr->dfs_bitmap.array = (u32 *)cmr->bitmap;
cmr->dfs_bitmap.n_elements =
DIV_ROUND_UP(cma_bitmap_maxno(cma, cmr),
BITS_PER_BYTE * sizeof(u32));
debugfs_create_u32_array("bitmap", 0444, dir,
&cmr->dfs_bitmap);
}
debugfs_create_symlink("base_pfn", tmp, "ranges/0/base_pfn");
debugfs_create_symlink("bitmap", tmp, "ranges/0/bitmap");
}
์ญํ : ํ๋์ CMA ์์ญ์ ๋ํด 6๊ฐ์ ๋๋ฒ๊ทธ ํ์ผ๊ณผ ranges/ ํ์ ๋๋ ํ ๋ฆฌ๋ฅผ ์์ฑํฉ๋๋ค. ํ์ ํธํ์ ์ํด base_pfn๊ณผ bitmap์ ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ ๋ง๋ญ๋๋ค.
๋ถ๊ธฐ ๋ก์ง:
1. alloc/free: ์ฐ๊ธฐ ์ ์ฉ (0200) โ ์๋ ํ ๋น/ํด์
2. count/order_per_bit: ์ง์ &cma->count ๋ฑ์ ์ฐ๊ฒฐ (์ฝ๊ธฐ ์ ์ฉ)
3. used: cma_used_get() ์ฌ์ฉ โ count - available_count ๊ณ์ฐ
4. maxchunk: cma_maxchunk_get() ์ฌ์ฉ โ ๋ชจ๋ ๋ ์ธ์ง์ ๋นํธ๋งต์ ์ํํ์ฌ ์ต๋ ์ฐ์ ๋น ๋ธ๋ก ๊ณ์ฐ
5. ranges/N/: ๊ฐ ๋ ์ธ์ง๋ณ base_pfn๊ณผ bitmap u32 ๋ฐฐ์ด ๋
ธ์ถ
3. `cma_used_get()` โ ์ฌ์ฉ๋ ๊ณ์ฐ (`mm/cma_debug.c:34-43`)
static int cma_used_get(void *data, u64 *val)
{
struct cma *cma = data;
spin_lock_irq(&cma->lock);
*val = cma->count - cma->available_count;
spin_unlock_irq(&cma->lock);
return 0;
}
์ญํ : count(์ ์ฒด)์์ available_count(์ฌ์ฉ ๊ฐ๋ฅ)๋ฅผ ๋นผ์ ํ์ฌ ์ฌ์ฉ ์ค์ธ ํ์ด์ง ์๋ฅผ ๋ฐํํฉ๋๋ค.
4. `cma_maxchunk_get()` โ ์ต๋ ์ฐ์ ๋น ๋ธ๋ก ๊ณ์ฐ (`mm/cma_debug.c:46-66`)
static int cma_maxchunk_get(void *data, u64 *val)
{
struct cma *cma = data;
struct cma_memrange *cmr;
unsigned long maxchunk = 0;
unsigned long start, end;
unsigned long bitmap_maxno;
int r;
spin_lock_irq(&cma->lock);
for (r = 0; r < cma->nranges; r++) {
cmr = &cma->ranges[r];
bitmap_maxno = cma_bitmap_maxno(cma, cmr);
for_each_clear_bitrange(start, end, cmr->bitmap, bitmap_maxno)
maxchunk = max(end - start, maxchunk);
}
spin_unlock_irq(&cma->lock);
*val = (u64)maxchunk << cma->order_per_bit;
return 0;
}
์ญํ : ๋ชจ๋ ๋ ์ธ์ง์ ๋นํธ๋งต์ ์ํํ๋ฉฐ ๊ฐ์ฅ ํฐ ์ฐ์ ๋น ์์ญ(0 ๋นํธ ๋ฒ์)์ ํฌ๊ธฐ๋ฅผ ๋ฐํํฉ๋๋ค. CMA ํ ๋น์ด ๊ฐ๋ฅํ ์ต๋ ๋ธ๋ก ํฌ๊ธฐ๋ฅผ ์๋ ค์ค๋๋ค.
๋ถ๊ธฐ ๋ก์ง:
1. cma->nranges๋งํผ ๋ฐ๋ณต
2. for_each_clear_bitrange()๋ก ๊ฐ ๋ ์ธ์ง์ ๋น ๋นํธ ๋ฒ์ ํ์
3. maxchunk = max(end - start, maxchunk)์ผ๋ก ์ต๋๊ฐ ๊ฐฑ์
4. << cma->order_per_bit๋ก ํ์ด์ง ์๋ก ๋ณํ
5. `cma_alloc_mem()` / `cma_free_mem()` โ ์๋ ํ ๋น/ํด์ (`mm/cma_debug.c:90-158`)
static int cma_alloc_mem(struct cma *cma, int count)
{
struct cma_mem *mem;
struct page *p;
mem = kzalloc_obj(*mem);
if (!mem)
return -ENOMEM;
p = cma_alloc(cma, count, 0, false);
if (!p) {
kfree(mem);
return -ENOMEM;
}
mem->p = p;
mem->n = count;
cma_add_to_cma_mem_list(cma, mem);
return 0;
}
์ญํ : alloc ๋๋ฒ๊ทธ ํ์ผ์ ํ์ด์ง ์๋ฅผ ์ฐ๋ฉด cma_alloc()์ผ๋ก ์ค์ ํ ๋น ํ cma_mem ๋ฆฌ์คํธ์ ์ถ๊ฐํฉ๋๋ค.
static int cma_free_mem(struct cma *cma, int count)
{
struct cma_mem *mem = NULL;
while (count) {
mem = cma_get_entry_from_list(cma);
if (mem == NULL)
return 0;
if (mem->n <= count) {
cma_release(cma, mem->p, mem->n);
count -= mem->n;
kfree(mem);
} else if (cma->order_per_bit == 0) {
cma_release(cma, mem->p, count);
mem->p += count;
mem->n -= count;
count = 0;
cma_add_to_cma_mem_list(cma, mem);
} else {
pr_debug("cma: cannot release partial block when order_per_bit != 0\n");
cma_add_to_cma_mem_list(cma, mem);
break;
}
}
return 0;
}
์ญํ : free ๋๋ฒ๊ทธ ํ์ผ์ ํ์ด์ง ์๋ฅผ ์ฐ๋ฉด ํ ๋น ๋ฆฌ์คํธ์์ ์์ฐจ์ ์ผ๋ก ๊บผ๋ด ํด์ ํฉ๋๋ค.
๋ถ๊ธฐ ๋ก์ง:
1. mem->n <= count: ๋ธ๋ก ์ ์ฒด๋ฅผ ํด์ ํ kfree(mem)
2. order_per_bit == 0์ด๊ณ mem->n > count: ๋ถ๋ถ ํด์ ๊ฐ๋ฅ โ mem->p์ mem->n ๊ฐฑ์ ํ ๋ฆฌ์คํธ์ ๋ค์ ์ถ๊ฐ
3. order_per_bit != 0์ด๊ณ ๋ถ๋ถ ํด์ ๋ถ๊ฐ: ๋๋ฒ๊ทธ ๋ฉ์์ง ์ถ๋ ฅ ํ ์ค๋จ
ํธ์ถ ํ๋ฆ
DebugFS ์ด๊ธฐํ ํ๋ฆ
๋ถํ
(late_initcall)
โ
โผ
cma_debugfs_init()
โ
โโโ debugfs_create_dir("cma", NULL) โ /sys/kernel/debug/cma/ ์์ฑ
โ
โโโ for (i = 0; i < cma_area_count; i++)
โ
โโโ cma_debugfs_add_one(&cma_areas[i], root)
โ
โโโ debugfs_create_dir(cma->name) โ cma-0/, cma-1/, ...
โ
โโโ debugfs_create_file("alloc") โ ์ฐ๊ธฐ ์ ์ฉ
โโโ debugfs_create_file("free") โ ์ฐ๊ธฐ ์ ์ฉ
โโโ debugfs_create_file("count") โ ์ฝ๊ธฐ ์ ์ฉ
โโโ debugfs_create_file("order_per_bit")
โโโ debugfs_create_file("used") โ cma_used_get()
โโโ debugfs_create_file("maxchunk") โ cma_maxchunk_get()
โ
โโโ ranges/ ํ์ ๋๋ ํ ๋ฆฌ
โโโ for (r = 0; r < nranges; r++)
โโโ base_pfn ํ์ผ
โโโ bitmap u32 ๋ฐฐ์ด
์๋ ํ ๋น/ํด์ ํ๋ฆ
์ฌ์ฉ์: echo 16 > /sys/kernel/debug/cma/cma-0/alloc
โ
โผ
cma_alloc_write(data=cma, val=16)
โ
โโโ cma_alloc_mem(cma, 16)
โ
โโโ kzalloc_obj(*mem) โ cma_mem ํ ๋น
โโโ cma_alloc(cma, 16, 0, false) โ ์ค์ CMA ํ ๋น
โ โโโ cma_range_alloc()
โ โโโ bitmap_find_next_zero_area_off()
โ โโโ page_range_contiguous()
โ โโโ bitmap_set()
โ โโโ alloc_contig_frozen_range()
โ
โโโ cma_add_to_cma_mem_list() โ mem_head์ ์ถ๊ฐ
์ฌ์ฉ์: echo 16 > /sys/kernel/debug/cma/cma-0/free
โ
โผ
cma_free_write(data=cma, val=16)
โ
โโโ cma_free_mem(cma, 16)
โ
โโโ while (count)
โโโ cma_get_entry_from_list() โ mem_head์์ ๊บผ๋ด๊ธฐ
โ
โโโ mem->n <= count โ cma_release() + kfree()
โโโ order_per_bit == 0 โ ๋ถ๋ถ ํด์ ๊ฐ๋ฅ
โโโ order_per_bit != 0 โ ๋ถ๋ถ ํด์ ๋ถ๊ฐ, ์ค๋จ
์กฐ๊ฑด๋ณ ๋น๊ต
DebugFS ํ์ผ ์ ํ ๋น๊ต
| ํ์ผ | ๊ถํ | ๋์ | ํจ์ |
|---|---|---|---|
| `alloc` | 0200 (์ฐ๊ธฐ) | ํ์ด์ง ์ ํ ๋น | `cma_alloc_write()` โ `cma_alloc_mem()` |
| `free` | 0200 (์ฐ๊ธฐ) | ํ์ด์ง ์ ํด์ | `cma_free_write()` โ `cma_free_mem()` |
| `count` | 0444 (์ฝ๊ธฐ) | ์ ์ฒด ํ์ด์ง ์ | ์ง์ `&cma->count` ์ฝ๊ธฐ |
| `order_per_bit` | 0444 (์ฝ๊ธฐ) | ๋นํธ๋งต ํด์๋ | ์ง์ `&cma->order_per_bit` ์ฝ๊ธฐ |
| `used` | 0444 (์ฝ๊ธฐ) | ์ฌ์ฉ ์ค์ธ ํ์ด์ง ์ | `cma_used_get()` |
| `maxchunk` | 0444 (์ฝ๊ธฐ) | ์ต๋ ์ฐ์ ๋น ๋ธ๋ก | `cma_maxchunk_get()` |
| `ranges/N/base_pfn` | 0444 (์ฝ๊ธฐ) | ๋ฒ์ ์์ PFN | ์ง์ `&cmr->base_pfn` ์ฝ๊ธฐ |
| `ranges/N/bitmap` | 0444 (์ฝ๊ธฐ) | ํ ๋น ๋นํธ๋งต (u32 ๋ฐฐ์ด) | `debugfs_create_u32_array()` |
cma_free_mem() ๋ถ๊ธฐ ๋น๊ต
| ์กฐ๊ฑด | ๋์ | ๊ฒฐ๊ณผ |
|---|---|---|
| `mem->n <= count` | ๋ธ๋ก ์ ์ฒด ํด์ + `kfree(mem)` | ์์ ํด์ |
| `order_per_bit == 0`ไธ `mem->n > count` | ๋ถ๋ถ ํด์ (mem->p ๊ฐฑ์ ) | ๋ถ๋ถ ํด์ ํ ๋ฆฌ์คํธ ๋ณต๊ท |
| `order_per_bit != 0`ไธ `mem->n > count` | ๋๋ฒ๊ทธ ๋ฉ์์ง + ์ค๋จ | ํด์ ๋ถ๊ฐ |
CMA ๋๋ฒ๊น ์ ๊ทผ ๋น๊ต
| ์ ๊ทผ | ๋๊ตฌ | ์ฉ๋ | |
|---|---|---|---|
| **DebugFS** | `/sys/kernel/debug/cma/` | ๋ฐํ์ ์ํ ๊ด์ฐฐ, ์๋ ํ ์คํธ | |
| **sysfs** | `/sys/sys/kernel/mm/cma/` | ํต๊ณ (์ฑ๊ณต/์คํจ/ํด์ ์นด์ดํฐ) | |
| **tracepoint** | `cma:cma_alloc_start/finish`, `cma:cma_release` | ํ ๋น/ํด์ ์ด๋ฒคํธ ์ถ์ | |
| **dmesg** | `dmesg \ | grep cma` | ์ด๊ธฐํ ๋ฉ์์ง, ์๋ฌ ๋ก๊ทธ |
๊ด๋ จ ๋ฌธ์
์ฐธ๊ณ : DebugFS vs sysfs ํต๊ณ ๋น๊ต
CMA๋ ๋ ๊ฐ์ง ์ธํฐํ์ด์ค๋ก ๋ฐํ์ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค:
/sys/kernel/debug/cma/): ๋๋ฒ๊น
์ฉ. ์๋ ํ ๋น/ํด์ , ๋นํธ๋งต ๋คํ, ๋ฉํฐ ๋ ์ธ์ง ์์ธ ์ ๋ณด ์ ๊ณต. CONFIG_CMA_DEBUGFS ํ์./sys/sys/kernel/mm/cma/): ์ด์์ฉ. nr_pages_succeeded, nr_pages_failed, nr_pages_released ์นด์ดํฐ๋ง ์ ๊ณต. CONFIG_CMA_SYSFS ํ์.์ด์ ํ๊ฒฝ์์๋ sysfs๋ฅผ, ๊ฐ๋ฐ/๋๋ฒ๊น ํ๊ฒฝ์์๋ DebugFS๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ ๋๋ค.
# sysfs ํต๊ณ ํ์ธ (CONFIG_CMA_SYSFS)
cat /sys/kernel/mm/cma/cma-0/nr_pages_succeeded
cat /sys/kernel/mm/cma/cma-0/nr_pages_failed
cat /sys/kernel/mm/cma/cma-0/nr_pages_released