目錄1.vmalloc概覽...
21.1 vmalloc資料結構說明...
21.2 vmalloc資料結構關係...
22.vmalloc記憶體分配...
32.1 vmalloc開機初始化...
32.2vmalloc.
32.2.1 vmalloc記憶體分配流程...
32.2.2 vmalloc虛擬位址空間分配...
42.2.3 vmalloc物理頁分配和對映...
63.vfree.
7附:位址空間布局...
//將開機過程中分配的vmalloc區域插入紅黑樹中
vmalloc虛擬位址區間分配
分配乙個vmap_area 結構,並且在紅黑樹中查詢乙個size大小的空閒區域,空閒位址空間必須位於vstart 到vend 之間,這裡傳入的是vmalloc_start和 vmalloc_end
tatic struct vmap_area *alloc_vmap_area(unsigned long size,
unsigned long align,
unsigned long vstart, unsigned long vend,
int node, gfp_t gfp_mask)
cached_vstart = vstart;
cached_align = align;
/*free_vmap_cache用於快取上一次查詢的vmap_area,下次查詢空閒區域可以從這個位置開始,避免從vmalloc_star開始浪費時間*/
if (free_vmap_cache) else else
n = n->rb_right;
}if (!first)
goto found;
}/*從first開始查詢乙個可以容納size大小的空閒區域,找到的條件是
addr + size 小於first->va_start
addr + size 大於 vend
查詢到鍊錶vmap_area_list末尾*/
while (addr + size > first->va_start && addr + size <= vend)
found:
if (addr + size > vend)
goto overflow;
//程式走到這裡說明找打了可用的空閒區域
va->va_start = addr;
va->va_end = addr + size;
va->flags = 0;
__insert_vmap_area(va); //將初始化後的vmap_area插入紅黑樹
free_vmap_cache = &va->rb_node;
spin_unlock(&vmap_area_lock);
return va;
overflow:
spin_unlock(&vmap_area_lock);
if (!purged)
if (gfpflags_allow_blocking(gfp_mask))
}kfree(va);
return err_ptr(-ebusy);
}
vmap_area_root是紅黑樹的根節點;全域性變數vmap_area_list用於將vmap_area安位址從小到大排序。下面函式是將vmap_area同時插入紅黑樹和鍊錶vmap_area_list中、
static void __insert_vmap_area(struct vmap_area *va)
rb_link_node(&va->rb_node, parent, p);
rb_insert_color(&va->rb_node, &vmap_area_root);
tmp = rb_prev(&va->rb_node);
if (tmp) else //如果沒有prev節點就新增到vmap_area_list的末尾
list_add_rcu(&va->list, &vmap_area_list);
}
初始化vm_struct並關聯vm_struct與vmap_area
static void setup_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va,
unsigned long flags, const void *caller)
vmalloc物理頁分配和對映
static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
pgprot_t prot, int node)
else
area->pages = pages; //用於存放page結構位址的陣列
…… for (i = 0; i < area->nr_pages; i++)
if (node == numa_no_node)
page = alloc_page(alloc_mask); //分配一頁
else
page = alloc_pages_node(node, alloc_mask, 0);
area->pages[i] = page; //將頁的位址放到陣列中
if (gfpflags_allow_blocking(gfp_mask))
cond_resched();
}//對映前面分配到的物理頁到連續虛擬位址空間中去
if (map_vm_area(area, prot, pages))
goto fail;
return area->addr; //返回虛擬位址區間的起始位址
fail:
......
fail_no_warn:
vfree(area->addr);
return null;
}
vfree
void vfree(const void *addr)
schedule free_work去釋放vfree_deferred中等待釋放的記憶體
static inline void __vfree_deferred(const void *addr)
釋放掉虛擬位址空間和對應的物理頁
static void __vunmap(const void *addr, int deallocate_pages)
if (deallocate_pages)
kvfree(area->pages); //釋放到page指標陣列
}kfree(area); //釋放掉vm_struct
kernel閱讀手記之vmalloc
vmalloc 和kmalloc 的在邏輯位址上時連續的,他們的區別在於 vmalloc 在實體地址上並不時連續的,但是 kmalloc 在實體地址上頁時連續的。vmalloc 分配分為兩種模式,一種是沒有 mmu memory management unit,記憶體管理模組 的 vmalloc 比...
Kmalloc和Vmalloc的區別
kmalloc 和vmalloc 介紹 kmalloc 用於申請較小的 連續的物理記憶體 1.以位元組為單位進行分配,在中 2.void kmalloc size t size,int flags 分配的記憶體實體地址上連續,虛擬位址上自然連續 3.gfp mask標誌 什麼時候使用哪種標誌?如下 ...
Kmalloc和Vmalloc的區別
kmalloc 和vmalloc 介紹 kmalloc 用於申請較小的 連續的物理記憶體 1.以位元組為單位進行分配,在中 2.void kmalloc size t size,int flags 分配的記憶體實體地址上連續,虛擬位址上自然連續 3.gfp mask標誌 什麼時候使用哪種標誌?如下 ...