亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 10890 | 回復(fù): 3
打印 上一主題 下一主題

[FreeBSD] freebsd9.2-UMA-boot階段的頁框分配(函數(shù)startup_alloc) [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2014-07-26 20:08 |只看該作者 |倒序?yàn)g覽
本帖最后由 71v5 于 2014-07-26 20:10 編輯

UMA相關(guān)的初始化函數(shù)(按調(diào)用順序排列)如下所示:
[1->函數(shù)uma_startup]-該函數(shù)完成了UMA相關(guān)的大部分初始化工作,是函數(shù)vm_page_startup調(diào)用的第一個(gè)主要的初始化函數(shù),
函數(shù)uma_startup的主要工作簡述如下:
  1. SI_SUB_VM                = 0x1000000,        /* virtual memory system init*/
  2. 100: SYSINIT(vm_mem, SI_SUB_VM, SI_ORDER_FIRST, vm_mem_init, NULL);

  3. <1>:初始化變量uma_max_ipers和uma_max_ipers_ref。
  4. <2>:初始化分配struct uma_keg對(duì)象的uma zone。
  5. <3>:將UMA boot階段使用到的物理頁框組織起來。
  6. <4>:創(chuàng)建并初始化分配struct uma_zone對(duì)象的uma zone。
  7. <5>:創(chuàng)建分配struct uma_slab對(duì)象和分配struct uma_slab_refcnt對(duì)象的uma zone。
  8. <6>:創(chuàng)建分配哈希表的uma zone。
  9. <7>:創(chuàng)建分配bucket的uma zone。
  10. <8>:將變量booted設(shè)置為UMA_STARTUP
  11. 我們下面將簡單分析一下工作3.
復(fù)制代碼
[2->函數(shù)uma_startup2]-在函數(shù)kmeminit中被調(diào)用,函數(shù)kmeminit主要做一些初始化工作,為內(nèi)核malloc函數(shù)的正常執(zhí)行做好準(zhǔn)備,
這里先略過函數(shù)kmeminit:
  1. SI_SUB_KMEM                = 0x1800000,        /* kernel memory*/
  2. SYSINIT(kmem, SI_SUB_KMEM, SI_ORDER_FIRST, kmeminit, NULL);

  3. /**************************************************************************************************
  4. * 先來簡單描述一個(gè)數(shù)據(jù)結(jié)構(gòu),struct vm_map,該類型的對(duì)象描述了內(nèi)核中某一子系統(tǒng)或者進(jìn)程
  5.    可以使用的虛擬線性地址的范圍,在分頁啟動(dòng)后,開始使用虛擬地址尋址,所以在獲得一個(gè)
  6.    物理頁框之前,必須先獲取一個(gè)可以使用的虛擬線性地址區(qū)間,然后修改相應(yīng)的頁表項(xiàng),用
  7.    獲取到的物理頁框填充這些頁表項(xiàng),這樣就可以訪問相應(yīng)的物理頁框了。

  8.    在virtual memory system初始化階段,內(nèi)核會(huì)創(chuàng)建幾個(gè)struct vm_map對(duì)象用來給內(nèi)核其它
  9.    子系統(tǒng)分配虛擬地址區(qū)間:
  10.    kmem_map:在UMA中使用。
  11.    exec_map:在execve系統(tǒng)調(diào)用使用。
  12.    pipe_map:在pipe系統(tǒng)調(diào)用使用。
  13.    等等。

  14.    從SYSINIT宏可以看出,當(dāng)調(diào)用函數(shù)kmeminit時(shí),virtual memory system已經(jīng)初始化
  15.    完畢,這就意味著可以使用virtual memory system提供的頁框分配接口vm_page_alloc*
  16.    函數(shù)來分配頁框。

  17.    在函數(shù)kmeminit調(diào)用uma_startup2之前,會(huì)先調(diào)用函數(shù)kmem_suballoc初始化kmem_map變量,
  18.    UMA提供的page_alloc函數(shù)在滿足下面兩個(gè)條件時(shí)才能用來分配頁框,因?yàn)閜age_alloc函數(shù)要
  19.    使用變量kmem_map,同時(shí)其內(nèi)部會(huì)使用virtual memory system提供的頁框分配接口vm_page_alloc*函數(shù)
  20.    來分配頁框:
  21.    條件1:virtual memory system已經(jīng)初始化完成。
  22.    條件2:變量kmem_map被正確初始化。

  23.    1773:更新變量booted,將其設(shè)置為UMA_STARTUP2。
  24.    1774:調(diào)用函數(shù)bucket_enable更新變量bucketdisable。

  25.    所以在函數(shù)uma_startup2執(zhí)行完后,page_alloc函數(shù)才能正常工作。
  26. ********************************************************/  
  27.   1769        /* see uma.h */
  28.   1770        void
  29.   1771        uma_startup2(void)
  30.   1772        {
  31.   1773                booted = UMA_STARTUP2;
  32.   1774                bucket_enable();
  33.   1775        #ifdef UMA_DEBUG
  34.   1776                printf("UMA startup2 complete.\n");
  35.   1777        #endif
  36.   1778        }
復(fù)制代碼
[3->函數(shù)uma_startup3]:
  1. SI_SUB_VM_CONF                = 0x2300000,        /* config VM, set limits */
  2. SYSINIT(uma_startup3, SI_SUB_VM_CONF, SI_ORDER_SECOND, uma_startup3, NULL);
  3. /*********************************************************************************
  4. * uma_startup3函數(shù)將描述等待事件的struct callout對(duì)象添加到相應(yīng)的callout隊(duì)列上,
  5.    每次調(diào)用函數(shù)uma_timeout時(shí),做下面兩工作:
  6.    1: 調(diào)用函數(shù)bucket_enable更新變量bucketdisable。
  7.    2: 如果使用哈希表管理struct slab或者struct uma_slab_refcnt對(duì)象,那么就檢查
  8.       是否extend哈希表的大小。

  9.    callout相關(guān)機(jī)制暫時(shí)先忽略。
  10. **********************************/
  11.   1785        static void
  12.   1786        uma_startup3(void)
  13.   1787        {
  14.   1788        #ifdef UMA_DEBUG
  15.   1789                printf("Starting callout.\n");
  16.   1790        #endif
  17.   1791                callout_init(&uma_callout, CALLOUT_MPSAFE);
  18.   1792                callout_reset(&uma_callout, UMA_TIMEOUT * hz, uma_timeout, NULL);
  19.   1793        #ifdef UMA_DEBUG
  20.   1794                printf("UMA startup3 complete.\n");
  21.   1795        #endif
  22.   1796        }
復(fù)制代碼
結(jié)合前面UMA相關(guān)數(shù)據(jù)結(jié)構(gòu)以及上面的描述,每個(gè)uma zone由struct uma_zone對(duì)象來描述,同時(shí)每個(gè)uma zone關(guān)聯(lián)了
一個(gè)struct uma_keg對(duì)象,當(dāng)從uma zone獲取對(duì)象時(shí),如果slab為空,就要調(diào)用struct uma_keg對(duì)象的成員
uk_allocf指向的函數(shù)來分配頁框。在創(chuàng)建uma zone的過程中,成員uk_allocf被默認(rèn)設(shè)置為函數(shù)page_alloc
的地址,隨后會(huì)根據(jù)變量booted的值確定是否要將成員uk_allocf更新為函數(shù)startup_alloc的地址。
此時(shí)變量booted的值作為一個(gè)分界點(diǎn):
1:當(dāng)變量booted的值小于UMA_STARTUP2時(shí),表示此時(shí)還處于UMA boot階段并且virtual memory system還沒有
初始化完成,就要使用startup_alloc函數(shù)來分配頁框。

2:當(dāng)變量booted的值大于UMA_STARTUP2時(shí),就表示UMA boot階段結(jié)束并且virtual memory system已經(jīng)初始化完畢,
就可以使用函數(shù)page_alloc來分配頁框。

從以前帖子中對(duì)vm_page_startup函數(shù)的描述可知,當(dāng)該函數(shù)執(zhí)行完后,物理內(nèi)存的簡單布局如下下面的圖2所示,其中標(biāo)記為'A'的
物理內(nèi)存就是分配給UMA boot階段使用:
圖1:


下面我們主要對(duì)UMA boot階段如何組織這些頁框以及如何分配這些頁框做一下簡單分析,先來看一個(gè)鏈表:
  1. /******************************************************************
  2. * Linked list of boot time pages.

  3.    struct {
  4.        struct uma_slab *lh_first;
  5.    }uma_boot_pages = { NULL );
  6.    
  7.    uma_boot_pages鏈接了分配給UMA boot階段的頁框。
  8. ******************************/
  9.    129        static LIST_HEAD(,uma_slab) uma_boot_pages = LIST_HEAD_INITIALIZER(uma_boot_pages);
復(fù)制代碼
在函數(shù)vm_page_startup給UMA boot階段分配了物理頁框后,就立即調(diào)用函數(shù)uma_startup:
  1. /**********************************************************************************************
  2. * 函數(shù)uma_startup,參數(shù)描述:

  3.    bootmem:一個(gè)虛擬線性地址,可以訪問分配給UMA boot階段使用的物理頁框,上面圖1中所示。

  4.    boot_pages:UMA boot階段使用的物理頁框的數(shù)目,這里為64個(gè)PAGE。

  5.    其中只保留了組織物理內(nèi)存相關(guān)的代碼。

  6.    從1699-1704之間的for循環(huán)可以看出:
  7.    1:內(nèi)核巧妙地在每個(gè)物理頁框頭部構(gòu)造一個(gè)struct uma_slab對(duì)象,將相應(yīng)的物理頁框鏈接到
  8.       鏈表uma_boot_pages中。

  9.    2:鏈表uma_boot_pages中的物理頁框是連續(xù)的,并且訪問相應(yīng)物理頁框的虛擬線性地址也是連續(xù)的。

  10.    3:鏈表uma_boot_pages中的物理頁框按照相應(yīng)的物理頁框號(hào)以降序排列。

  11.    并且對(duì)于每一個(gè)struct uma_slab對(duì)象:
  12.    成員us_data:保存的是訪問相應(yīng)物理頁框的虛擬線性地址。

  13.    成員us_flags:設(shè)置標(biāo)志UMA_SLAB_BOOT,在后續(xù)的回收操作中,將不會(huì)回收設(shè)置了
  14.                  UMA_SLAB_BOOT標(biāo)志的slab。

  15.    這段for循環(huán)執(zhí)行完后,頁框的簡單組織如下面的圖2所示,為了簡單期間,只包含了
  16.    8個(gè)頁框。

  17.    #define UMA_SLAB_BOOT        0x01                Slab alloced from boot pages
  18. *****************************************/   
  19.   1598        void
  20.   1599        uma_startup(void *bootmem, int boot_pages)
  21.   1600        {
  22. .....................................................................................................
  23. .....................................................................................................
  24.   1699                for (i = 0; i < boot_pages; i++) {
  25.   1700                        slab = (uma_slab_t)((u_int8_t *)bootmem + (i * UMA_SLAB_SIZE));
  26.   1701                        slab->us_data = (u_int8_t *)slab;
  27.   1702                        slab->us_flags = UMA_SLAB_BOOT;
  28.   1703                        LIST_INSERT_HEAD(&uma_boot_pages, slab, us_link);
  29.   1704                }
  30. .....................................................................................................
  31. .....................................................................................................
  32.   1767        }
復(fù)制代碼
圖2:


[函數(shù)startup_alloc]-UMA boot階段分配頁框:
  1. /*********************************************************************************
  2. * 參數(shù)描述:
  3.    zone:指向描述相關(guān)uma zone的struct uma_zone對(duì)象。
  4.    bytes:此次需要分配的內(nèi)存大小。
  5.    pflag:返回給調(diào)用者的標(biāo)志。
  6.    wait:一些標(biāo)志,標(biāo)識(shí)分配頁框過程中是否需要睡眠。

  7.    結(jié)合上面的描述以及圖2,startup_alloc函數(shù)已經(jīng)很容易理解了。
  8. ********************************************************/
  9.    928        static void *
  10.    929        startup_alloc(uma_zone_t zone, int bytes, u_int8_t *pflag, int wait)
  11.    930        {
  12.    931                uma_keg_t keg;
  13.    932                uma_slab_t tmps;
  14.    933                int pages, check_pages;
  15.    934       
  16. /****************************************************************************
  17. * kegs:指向相關(guān)聯(lián)的struct uma_keg對(duì)象。

  18.    pages:此次請(qǐng)求的頁框數(shù)目。

  19.    check_pages:用來檢查鏈表uma_boot_pages中是否有足夠數(shù)目的頁框。

  20.    946-948:如果tmps為NULL,就表示:
  21.             1:鏈表uma_boot_pages為空。
  22.             或者
  23.             2:鏈表uma_boot_pages非空,但是剩余的頁框數(shù)目不滿足此次分配需求。
  24.    
  25.    949-962:鏈表uma_boot_pages中有足夠數(shù)目的頁框滿足此次頁框分配需求。
  26. ****************************************/  
  27.    935                keg = zone_first_keg(zone);
  28.    936                pages = howmany(bytes, PAGE_SIZE);
  29.    937                check_pages = pages - 1;
  30.    938                KASSERT(pages > 0, ("startup_alloc can't reserve 0 pages\n"));
  31.    939       
  32.    940                /*
  33.    941                 * Check our small startup cache to see if it has pages remaining.
  34.    942                 */
  35.    943                mtx_lock(&uma_boot_pages_mtx);
  36.    944       
  37.    945                /* First check if we have enough room. */
  38.    946                tmps = LIST_FIRST(&uma_boot_pages);
  39.    947                while (tmps != NULL && check_pages-- > 0)
  40.    948                        tmps = LIST_NEXT(tmps, us_link);
  41.    949                if (tmps != NULL) {
  42.    950                        /*
  43.    951                         * It's ok to lose tmps references.  The last one will
  44.    952                         * have tmps->us_data pointing to the start address of
  45.    953                         * "pages" contiguous pages of memory.
  46.    954                         */
  47.    955                        while (pages-- > 0) {
  48.    956                                tmps = LIST_FIRST(&uma_boot_pages);
  49.    957                                LIST_REMOVE(tmps, us_link);
  50.    958                        }
  51.    959                        mtx_unlock(&uma_boot_pages_mtx);
  52.    960                        *pflag = tmps->us_flags;
  53.    961                        return (tmps->us_data);
  54.    962                }
  55.    963                mtx_unlock(&uma_boot_pages_mtx);
  56. /*********************************************************************************
  57. * 如果執(zhí)行到這里,即tmps為NULL,就表示鏈表uma_boot_pages中的物理頁框數(shù)目不滿足
  58.    此次分配需求。

  59.    964-965:
  60.    檢查變量booted的值,如果if的條件為真,就表示此時(shí)還處于UMA boot階段并且
  61.    virtual memory system還沒有初始化完成,此時(shí)就要增加分配給UMA boot階段使用的
  62.    物理頁框的數(shù)目。
  63. *********************************/
  64.    964                if (booted < UMA_STARTUP2)
  65.    965                        panic("UMA: Increase vm.boot_pages");
  66. /**********************************************************************
  67. * Now that we've booted reset these users to their real allocator.
  68. *
  69.    執(zhí)行到這里的話,就表示UMA和virtual memory system已經(jīng)初始化完成,
  70.    此時(shí)用正確的函數(shù)地址重新設(shè)置成員uk_allocf:
  71.    
  72.    969-971:和具體底層架構(gòu)相關(guān),uma_small_alloc函數(shù)由相應(yīng)的實(shí)現(xiàn)定義,
  73.             這里忽略。

  74.    971-973:很明顯,此時(shí)函數(shù)page_alloc已經(jīng)可以正常工作。

  75.    974:使用新的頁框分配函數(shù)重新分配頁框。
  76. ********************************/
  77.    968                 
  78.    969        #ifdef UMA_MD_SMALL_ALLOC
  79.    970                keg->uk_allocf = (keg->uk_ppera > 1) ? page_alloc : uma_small_alloc;
  80.    971        #else
  81.    972                keg->uk_allocf = page_alloc;
  82.    973        #endif
  83.    974                return keg->uk_allocf(zone, bytes, pflag, wait);
  84.    975        }
復(fù)制代碼

論壇徽章:
2
亥豬
日期:2014-03-19 16:36:35午馬
日期:2014-11-23 23:48:46
2 [報(bào)告]
發(fā)表于 2014-07-27 11:57 |只看該作者
一定堅(jiān)持下去!

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2014-07-27 21:15 |只看該作者
回復(fù) 2# gvim

在自己能力范圍內(nèi),盡最大努力
   

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2014-08-10 18:50 |只看該作者
本人小白一枚,慢慢學(xué)習(xí)中,多謝樓主分享~
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP