Sparse Memory Model

arm64_memory_present                            arch/arm64/mm/init.c +305

static void __init arm64_memory_present(void)
{
        struct memblock_region *reg;

        for_each_memblock(memory, reg) {
                int nid = memblock_get_region_node(reg);

                memory_present(nid, memblock_region_memory_base_pfn(reg),
                                memblock_region_memory_end_pfn(reg));
        }
}

 memory_present                                mm/sparse.c +210

void __init memory_present(int nid, unsigned long start, unsigned long end)
{
        unsigned long pfn;

#ifdef CONFIG_SPARSEMEM_EXTREME
        if (unlikely(!mem_section)) {
                unsigned long size, align;

                size = sizeof(struct mem_section*) * NR_SECTION_ROOTS;
                align = 1 << (INTERNODE_CACHE_SHIFT);
                mem_section = memblock_virt_alloc(size, align);
        }
#endif

        start &= PAGE_SECTION_MASK;
        mminit_validate_memmodel_limits(&start, &end);
        for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) {
                unsigned long section = pfn_to_section_nr(pfn);
                struct mem_section *ms;

                sparse_index_init(section, nid);
                set_section_nid(section, nid);

                ms = __nr_to_section(section);
                if (!ms->section_mem_map) {
                        ms->section_mem_map = sparse_encode_early_nid(nid) |
                                                        SECTION_IS_ONLINE;
                        section_mark_present(ms);
                }
        }
}
sparse_index_init                        mm/sparse.c +77
static int __meminit sparse_index_init(unsigned long section_nr, int nid)
{
        unsigned long root = SECTION_NR_TO_ROOT(section_nr);
        struct mem_section *section;

        if (mem_section[root])
                return -EEXIST;

        section = sparse_index_alloc(nid);
        if (!section)
                return -ENOMEM;

        mem_section[root] = section;

        return 0;
}
sparse_index_alloc                    mm/sparse.c +63
static noinline struct mem_section __ref *sparse_index_alloc(int nid)
{
        struct mem_section *section = NULL;
        unsigned long array_size = SECTIONS_PER_ROOT *
                                   sizeof(struct mem_section);

        if (slab_is_available())
                section = kzalloc_node(array_size, GFP_KERNEL, nid);
        else
                section = memblock_virt_alloc_node(array_size, nid);

        return section;
}
set_section_nid                            mm/sparse.c +52
static void set_section_nid(unsigned long section_nr, int nid)
{
        section_to_node_table[section_nr] = nid;
}
include/linux/mmzone.h +1156
static inline struct mem_section *__nr_to_section(unsigned long nr)
{
        unsigned long root = SECTION_NR_TO_ROOT(nr);

        if (unlikely(root >= NR_SECTION_ROOTS))
                return NULL;

#ifdef CONFIG_SPARSEMEM_EXTREME
        if (!mem_section || !mem_section[root])
                return NULL;
#endif
        return &mem_section[root][nr & SECTION_ROOT_MASK];
}
section_mark_present                    mm/sparse.c +178
int __highest_present_section_nr;
static void section_mark_present(struct mem_section *ms)
{
        int section_nr = __section_nr(ms);

        if (section_nr > __highest_present_section_nr)
                __highest_present_section_nr = section_nr;

        ms->section_mem_map |= SECTION_MARKED_PRESENT;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值