/* 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)