vmalloc_init

/* linux/mm/vmalloc.c*/
struct vmap_area {
    unsigned long va_start;
    unsigned long va_end;
    unsigned long flags;
    struct rb_node rb_node;        /* address sorted rbtree */
    struct list_head list;        /* address sorted list */
    struct list_head purge_list;    /* "lazy purge" list */
    void *private;
    struct rcu_head rcu_head;
};

/*
* 显示通过vmalloc分配的内存区域,个vm_struct通过红黑树管理,
* 红黑树的各节点显示为vmap_area结构体
*/
struct vm_struct {
    struct vm_struct    *next;
    void            *addr;
    unsigned long        size;
    unsigned long        flags;
    struct page        **pages;
    unsigned int        nr_pages;
    unsigned long        phys_addr;
    void            *caller;
};

struct vmap_block_queue {
    spinlock_t lock;
    struct list_head free;
    struct list_head dirty;
    unsigned int nr_dirty;
};
struct vmap_block {
    spinlock_t lock;
    struct vmap_area *va;
    struct vmap_block_queue *vbq;
    unsigned long free, dirty;
    DECLARE_BITMAP(alloc_map, VMAP_BBMAP_BITS);
    DECLARE_BITMAP(dirty_map, VMAP_BBMAP_BITS);
    union {
        struct list_head free_list;
        struct rcu_head rcu_head;
    };
};
/* Queue of free and dirty vmap blocks, for allocation and flushing purposes */
static DEFINE_PER_CPU(struct vmap_block_queue, vmap_block_queue);

void __init vmalloc_init(void)

/*以下代码应该在 中执行*/
int rc;
rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,PERCPU_DYNAMIC_RESERVE,
        PAGE_SIZE,NULL,pcpu_dfl_fc_alloc,pcpu_dfl_fc_free);  
if (rc<0)  
    panic("Failed to initialize percpu areas.");

/* 
* linux/mm/vmalloc.c
* 全局变量vmlist的初始化流程
*/
struct vm_struct *vmlist;
asmlinkage void __init start_kernel(void)
    -->setup_per_cpu_areas();
        -->ssize_t __init pcpu_embed_first_chunk(size_t static_size, size_t reserved_size,
                      ssize_t dyn_size, ssize_t unit_size)
            -->size_t __init pcpu_setup_first_chunk(pcpu_get_page_fn_t get_page_fn,
                     size_t static_size, size_t reserved_size,
                     ssize_t dyn_size, ssize_t unit_size,
                     void *base_addr,
                     pcpu_populate_pte_fn_t populate_pte_fn)
                -->void __init vm_area_register_early(struct vm_struct *vm, size_t align)
                    -->vmlist = vm;

/*建立vm_struct与vmap_area的关联*/
#define RB_ROOT    (struct rb_root) { NULL, }
static struct rb_root vmap_area_root = RB_ROOT;
static LIST_HEAD(vmap_area_list);

static void __insert_vmap_area(struct vmap_area *va)
原文地址:https://www.cnblogs.com/yangjiguang/p/8343945.html