boot_mem分配器

 

#define alloc_bootmem_low_pages(x) \
    __alloc_bootmem_low(x, PAGE_SIZE, 0)
    

 

void * __init __alloc_bootmem_low(unsigned long size, unsigned long align,
                  unsigned long goal)
{
    return ___alloc_bootmem(size, align, goal, ARCH_LOW_ADDRESS_LIMIT);
}

 

static void * __init ___alloc_bootmem(unsigned long size, unsigned long align,
                    unsigned long goal, unsigned long limit)
{
    void *mem = ___alloc_bootmem_nopanic(size, align, goal, limit);

    if (mem)
        return mem;
    /*
     * Whoops, we cannot satisfy the allocation request.
     */
    printk(KERN_ALERT "bootmem alloc of %lu bytes failed!\n", size);
    panic("Out of memory");
    return NULL;
}

 

static void * __init ___alloc_bootmem_nopanic(unsigned long size,
                    unsigned long align,
                    unsigned long goal,
                    unsigned long limit)
{
    bootmem_data_t *bdata;
    void *region;

restart:
    region = alloc_arch_preferred_bootmem(NULL, size, align, goal, limit);
    if (region)
        return region;

    list_for_each_entry(bdata, &bdata_list, list) {
        if (goal && bdata->node_low_pfn <= PFN_DOWN(goal))
            continue;
        if (limit && bdata->node_min_pfn >= PFN_DOWN(limit))
            break;

        region = alloc_bootmem_core(bdata, size, align, goal, limit);
        if (region)
            return region;
    }

    if (goal) {
        goal = 0;
        goto restart;
    }

    return NULL;
}

 重要的结构体

typedef struct pglist_data {
    struct zone node_zones[MAX_NR_ZONES];
    struct zonelist node_zonelists[MAX_ZONELISTS];
    int nr_zones;
#ifdef CONFIG_FLAT_NODE_MEM_MAP    /* means !SPARSEMEM */
    struct page *node_mem_map;
#ifdef CONFIG_CGROUP_MEM_RES_CTLR
    struct page_cgroup *node_page_cgroup;
#endif
#endif
    struct bootmem_data *bdata;
#ifdef CONFIG_MEMORY_HOTPLUG
    /*
     * Must be held any time you expect node_start_pfn, node_present_pages
     * or node_spanned_pages stay constant.  Holding this will also
     * guarantee that any pfn_valid() stays that way.
     *
     * Nests above zone->lock and zone->size_seqlock.
     */
    spinlock_t node_size_lock;
#endif
    unsigned long node_start_pfn;
    unsigned long node_present_pages; /* total number of physical pages */
    unsigned long node_spanned_pages; /* total size of physical page
                         range, including holes */
    int node_id;
    wait_queue_head_t kswapd_wait;
    struct task_struct *kswapd;
    int kswapd_max_order;
} pg_data_t;

 

/* 
* node_bootmem_map is a map pointer - the bits represent all physical 
 * memory pages (including holes) on the node.
 */
typedef struct bootmem_data {
    unsigned long node_min_pfn;
    unsigned long node_low_pfn;
    void *node_bootmem_map;
    unsigned long last_end_off;
    unsigned long hint_idx;
    struct list_head list;
} bootmem_data_t;

 

posted @ 2018-01-06 09:47  bluebluebluesky  阅读(171)  评论(0编辑  收藏  举报