slub object 内存布局

我在 https://blog.csdn.net/wowricky/article/details/83218126 介绍了一种内存池,它的实现类似于linux 中打开slub_debug (1. make menuconfig: Kenel hacking -> Memory Debugging, 2. comand line中传入slub_debug=PZU) 时slub 对象池。
首先我们先看一下slub_debug没有打开时的 slub obj 所占memory layout,预期如下:
slub obj
为了查看slub obj 内存布局,我写了一个kernle module, code上传至github: https://github.com/greenricky/slub_debug 摘抄主要的代码片段如下:

void print_mem_detail(char *addr, int head_size, int buf_size,int foot_size)
{
    if(NULL==addr || head_size<0 || buf_size<0 || foot_size<0)
        return;

    printk("---Ahead  %d bytes---\n", head_size);
    print_layout(addr-head_size, head_size);
    
    printk("---Buf    %d bytes---\n", buf_size);
    print_layout(addr, buf_size);

    printk("---Footer %d bytes---\n", foot_size);
    print_layout(addr+buf_size, foot_size);
}

static int __init my_test_init(void)
{
    printk("greenricky: init\n");

    buf = kmalloc(mem_size, GFP_KERNEL);
    printk("===============kmalloc=================\n");
    print_mem_detail(buf, head_size, mem_size, foot_size);
    
    memset(buf, 0x57, mem_size);    
    printk("\n===============memset buf to 0x57======\n");
    print_mem_detail(buf, head_size, mem_size, foot_size);

    kfree(buf);
    printk("\n===============free buf====================\n");
    print_mem_detail(buf, head_size, mem_size, foot_size);

    return 0;
}

思路如下:

  1. 申请n个bytes大小的内存,
  2. 打印刚刚分配出的内存布局;(obj 前head_size个 bytes + obj + obj 后foot_size个 bytes);
  3. 打印memset obj 后的内存布局;
  4. 打印free obj 后的内存布局;

在下例中我们实际申请48个bytes的内存,通过查看内核给我们分配是kmalloc-64 obj. 下图是刚刚kmalloc后的内存布局,还没有用memset进行赋值。

# insmod slub.ko head_size=64 mem_size=48  foot_size=64
===============kmalloc=================
---Ahead  64 bytes---
ee598300: 05 47 c2 ee 14 ec c0 ee 14 ec c0 ee c4 1d 03 c0 
ee598310: 00 00 00 00 70 58 7b c0 00 a0 eb ee 0c a0 eb ee 
ee598320: 00 00 00 00 00 00 00 00 00 00 00 00 4c 52 23 c0 
ee598330: 00 a0 eb ee 00 00 00 00 00 00 00 00 00 00 00 00 
---Buf    48 bytes---
ee598340: 80 83 59 ee 65 73 74 5f 69 6e 69 74 20 5b 73 6c 
ee598350: 75 62 5d 00 00 00 00 00 00 00 00 00 00 00 00 00 
ee598360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
---Footer 64 bytes---
ee598370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
ee598380: c0 83 59 ee 00 00 00 00 00 00 00 00 00 00 00 00 
ee598390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
ee5983a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

通过上述打印出来的内存布局来看,我们申请的内存起始地址0xee598340, 结束地址是0xee59837f, 长度为64bytes.
请关注一点,内存区域起始地址的前4个bytes是FP- free pointer, 也就是指向下一个可用object 地址,这里是0xee598380, 而0xee598380正好是我们申请到的内存区域的结束地址的后一个byte。我们继续观察0xee598380 开始这段内存,起始的4个bytes是0xee5983c0, 也就是下一个可用object的地址。
为了更好的理解上述内存布局,截图注释如下:
slub object 内存布局_第1张图片
obj - 48 bytes
本例中object size为48 bytes (前4个bytes存储的是FP), obj align 长度为16bytes。
本章介绍的是slub_debug 关闭情况下的内存布局,下一章我们介绍slub_debug 打开情况下的内存布局,好戏才刚刚开始。

你可能感兴趣的:(kernel)