1. buddy system 取出 0x200 大小的块
    1. slab 向 buddy system 请求分配 page
    2. slab 分配 new object
    3. page 结构体字段
  2. 这么打印结构体

buddy system 取出 0x200 大小的块

3.2.5 SLAB/SLUB/SLOB - Linux核心概念详解

/*
 * Go through the free lists for the given migratetype and remove
 * the smallest available page from the freelists
 */
static __always_inline
struct page *__rmqueue_smallest(struct zone *zone, unsigned int order,
                        int migratetype)
{
    unsigned int current_order;
    struct free_area *area;
    struct page *page;

    /* Find a page of the appropriate size in the preferred list */
    for (current_order = order; current_order <= MAX_ORDER; ++current_order) {
        area = &(zone->free_area[current_order]);
        page = get_page_from_free_area(area, migratetype);
        if (!page)
            continue;
        del_page_from_free_list(page, zone, current_order);
        expand(zone, page, order, current_order, migratetype);
        set_pcppage_migratetype(page, migratetype);
        trace_mm_page_alloc_zone_locked(page, order, migratetype,
                pcp_allowed_order(order) &&
                migratetype < MIGRATE_PCPTYPES);
        return page;
    }

    return NULL;
}

slab 向 buddy system 请求分配 page

struct page *__alloc_pages(gfp_t gfp, unsigned int order, int preferred_nid,
                            nodemask_t *nodemask)

slab 分配 new object

static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
              unsigned long addr, struct kmem_cache_cpu *c, unsigned int orig_size)
              
new_objects:


.... 

    freelist = slab->freelist;
    slab->freelist = NULL;
    slab->inuse = slab->objects;
    slab->frozen = 1;

页面是如何分配结构体的

    shuffle = shuffle_freelist(s, slab);

    if (!shuffle) {
        //在 page 的开始设置 red zone 防止越界
        start = fixup_red_left(s, start);
        start = setup_object(s, start);
        slab->freelist = start;
        for (idx = 0, p = start; idx < slab->objects - 1; idx++) {
            next = p + s->size;
            next = setup_object(s, next);
            set_freepointer(s, p, next);
            p = next;
        }
        set_freepointer(s, p, NULL);
    }

    return slab;

https://blog.csdn.net/qq_44629819/article/details/133043499

page 结构体字段

pwndbg> x/10gx 0xffffea00001be200
0xffffea00001be200:     0x000fffffc0000200      0xffff888004dfb500
0xffffea00001be210:     0xdead000000000122      0x0000000000000000
0xffffea00001be220:     0xffff888006f88450      0x0000000000aa0000
0xffffea00001be230:     0x00000001ffffffff      0x0000000000000000

flags       slab_cache
?           ?
freelist    

struct slab {
    unsigned long __page_flags;
    struct kmem_cache *slab_cache;
    struct {
        union {
            struct list_head slab_list;
#ifdef CONFIG_SLUB_CPU_PARTIAL
            struct {
                struct slab *next;
                int slabs;	/* Nr of slabs left */
            };
#endif
        };
        /* Double-word boundary */
        void *freelist;		/* first free object */
        struct {
            unsigned inuse:16;
            unsigned objects:15;
            unsigned frozen:1;
        };
    };
    unsigned int __unused;
    atomic_t __page_refcount;
#ifdef CONFIG_MEMCG
    unsigned long memcg_data;
#endif
};

这么打印结构体

p * (struct kmem_cache *) 0xffff888004c44100