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