memblock的问题。
在bootloader传递给过去关于内存的tag之后被解析到meminfo结构体中。void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
{
int i;
for (i = 0; i < mi->nr_banks; i++)
memblock_add(mi->bank.start, mi->bank.size); //添加memblock.memory
arm_mm_memblock_reserve();//页表处的内存区域(in use)添加到memblock.reserve
arm_dt_memblock_reserve(); //先不考虑,假设为tags形式传递参数过来
if (mdesc->reserve)
mdesc->reserve(); //head.s中可以确定的mdesc
dma_contiguous_reserve(min(arm_dma_limit, arm_lowmem_limit));
arm_memblock_steal_permitted = false;
memblock_allow_resize();
memblock_dump_all();
}
确定了memblock结构体的各种信息之后,从memblock上memblock_alloc_base函数上进行分配内存。
memblock_alloc_base -> __memblock_alloc_base -> memblock_alloc_base_nid -> memblock_find_in_range_node-> for_each_free_mem_range_reverse
#define for_each_free_mem_range_reverse(i, nid, p_start, p_end, p_nid) \
for (i = (u64)ULLONG_MAX, \
__next_free_mem_range_rev(&i, nid, p_start, p_end, p_nid); \
i != (u64)ULLONG_MAX; \
__next_free_mem_range_rev(&i, nid, p_start, p_end, p_nid))
//分配内存区域
void __init_memblock __next_free_mem_range_rev(u64 *idx, int nid,
phys_addr_t *out_start,
phys_addr_t *out_end, int *out_nid)
{
struct memblock_type *mem = &memblock.memory;
struct memblock_type *rsv = &memblock.reserved;
int mi = *idx & 0xffffffff;
int ri = *idx >> 32;
if (*idx == (u64)ULLONG_MAX) {
mi = mem->cnt - 1; //从最高的regions开始往下分配
ri = rsv->cnt; //
}
for ( ; mi >= 0; mi--) {
struct memblock_region *m = &mem->regions;
phys_addr_t m_start = m->base;
phys_addr_t m_end = m->base + m->size;
/* only memory regions are associated with nodes, check it */
if (nid != MAX_NUMNODES && nid != memblock_get_region_node(m)) //nid 指定从哪个node分配则需要检查
continue;
/* scan areas before each reservation for intersection *///检查交集
for ( ; ri >= 0; ri--) {
struct memblock_region *r = &rsv->regions;
phys_addr_t r_start = ri ? r[-1].base + r[-1].size : 0;
phys_addr_t r_end = ri < rsv->cnt ? r->base : ULLONG_MAX;
/* if ri advanced past mi, break out to advance mi */
if (r_end <= m_start)
break;
/* if the two regions intersect, we're done */
if (m_end > r_start) {
if (out_start)
*out_start = max(m_start, r_start);
if (out_end)
*out_end = min(m_end, r_end);
if (out_nid)
*out_nid = memblock_get_region_node(m);
if (m_start >= r_start)
mi--;
else
ri--;
*idx = (u32)mi | (u64)ri << 32;
return;
}
}
}
*idx = ULLONG_MAX;
}
关于这个函数,哪个大哥可以指点一下么,谢谢了。
我怎么感觉返回的out_startout_end正是memory和reserved之间交集的区域。
页:
[1]