darling54454 发表于 2015-01-02 22:26

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]
查看完整版本: memblock的问题。