<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    Linux 內(nèi)存管理之vmalloc

    共 2269字,需瀏覽 5分鐘

     ·

    2021-05-15 23:56

    走進(jìn)vmalloc

    根據(jù)前面的系列文章,我們知道了buddy system是基于頁(yè)框分配器,kmalloc是基于slab分配器,而且這些分配的地址都是物理內(nèi)存連續(xù)的。但是隨著碎片化的積累,連續(xù)物理內(nèi)存的分配就會(huì)變得困難,對(duì)于那些非DMA訪問(wèn),不一定非要連續(xù)物理內(nèi)存的話完全可以像malloc那樣,將不連續(xù)的物理內(nèi)存頁(yè)框映射到連續(xù)的虛擬地址空間中,這就是vmap的來(lái)源)(提供把離散的page映射到連續(xù)的虛擬地址空間),vmalloc的分配就是基于這個(gè)機(jī)制來(lái)實(shí)現(xiàn)的。

    vmalloc最小分配一個(gè)page,并且分配到的頁(yè)面不保證是連續(xù)的,因?yàn)関malloc內(nèi)部調(diào)用alloc_page多次分配單個(gè)頁(yè)面。

    vmalloc的區(qū)域就是在上圖中VMALLOC_START - VMALLOC_END之間,可通過(guò)/proc/vmallocinfo查看。

    數(shù)據(jù)結(jié)構(gòu)

    • vmap_area 描述一段虛擬地址的區(qū)域,可以將struct vm_struct構(gòu)成一個(gè)鏈表,維護(hù)多段映射。
    struct vmap_area {
     unsigned long va_start; //vmalloc申請(qǐng)?zhí)摂M地址返回的起始地址
     unsigned long va_end; //vmalloc申請(qǐng)申請(qǐng)?zhí)摂M地址返回的結(jié)束地址
     unsigned long flags;
      //掛接到vmap_area_root紅黑樹(shù)
     struct rb_node rb_node;         /* address sorted rbtree */
      //掛接到vmap_area_list鏈表
     struct list_head list;          /* address sorted list */
     struct llist_node purge_list;    /* "lazy purge" list */
     //如果當(dāng)前VA處于使用狀態(tài)(即在vmap_area_root為根的紅黑樹(shù)中和vmap_area_list鏈表中),vm有效,指向用于管理虛擬地址和物理頁(yè)之間的映射關(guān)系的描述符
     struct vm_struct *vm;
     struct rcu_head rcu_head;
    };
    • vm_struct 管理虛擬地址和物理頁(yè)之間的映射關(guān)系
    struct vm_struct {
     struct vm_struct *next; //指向下一個(gè)vm結(jié)構(gòu)體
     void   *addr; //當(dāng)前vmalloc區(qū)域的虛擬地址的起始地址
     unsigned long  size; //當(dāng)前vmalloc區(qū)域的虛擬地址的大小
     unsigned long  flags;
     //vamlloc分配獲取的各個(gè)物理頁(yè)面并是不連續(xù)的,每個(gè)物理頁(yè)面用struct page描述,一個(gè)vm_struct對(duì)用到的管理所有物理頁(yè)面的struct page構(gòu)成一個(gè)數(shù)組,而pages就是指向這個(gè)數(shù)組的指針。
     struct page  **pages;
     unsigned int  nr_pages; //vmalloc映射的page數(shù)目
     phys_addr_t  phys_addr; //用來(lái)映射硬件設(shè)備的IO共享內(nèi)存,其他情況下為0
     const void  *caller; //調(diào)用vmalloc函數(shù)的函數(shù)的地址
    };

    vmalloc

    主要分以下三步:

    1. 從VMALLOC_START到VMALLOC_END查找空閑的虛擬地址空間(hole)
    2. 根據(jù)分配的size,調(diào)用alloc_page依次分配單個(gè)頁(yè)面.
    3. 把分配的單個(gè)頁(yè)面,映射到第一步中找到的連續(xù)的虛擬地址。把分配的單個(gè)頁(yè)面,映射到第一步中找到的連續(xù)的虛擬地址。




    推薦閱讀:
    專輯|Linux文章匯總
    專輯|程序人生
    專輯|C語(yǔ)言
    我的知識(shí)小密圈

    關(guān)注公眾號(hào),后臺(tái)回復(fù)「1024」獲取學(xué)習(xí)資料網(wǎng)盤(pán)鏈接。

    歡迎點(diǎn)贊,關(guān)注,轉(zhuǎn)發(fā),在看,您的每一次鼓勵(lì),我都將銘記于心~


    瀏覽 36
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評(píng)論
    圖片
    表情
    推薦
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    91 黄网站在线观看 | 伊人天堂网在线 | 影音先锋男人站资源 | 亚洲色区在线 | 日韩国产一级无码 |