1. 程式人生 > >2.7 Linux儲存管理-物理頁面分配

2.7 Linux儲存管理-物理頁面分配

程序需要的連續的頁面,通過alloc_pages來完成 該函式在mm/numa.c和mm/page_alloc.h中都有定義 NUMA和UMA分配記憶體的函式是不併存的,根據CONFIG_DISCONTIGMEM的勾選與否選擇其中一個
1. NUMA的分配記憶體函式: 選擇CONFIG_DISCONTIGMEM選項 被編譯的條件是“不連續的儲存空間”,而不是CONFIG_NUMA,但是CONFIG_NUMA會對程式造成影響 alloc_pages(int gfp_mask,unsigned long order)
gfp_mask:表示採用哪一種分配策略 order:申請2^order個頁面
numa的alloc_pages的程式碼:
如果定義了NUMA,就需要獲取 pgdat_list,並且需要遍歷所有的pg_data_t節點 分配時輪流從各個節點開始,並希望各節點負載均衡 在每個節點上使用 alloc_pages_pgdat函式
1
==================== mm/numa.c 43 43 ====================
2
43
 #ifdef CONFIG_DISCONTIGMEM
3
==================== mm/numa.c 91 128 ====================
4
91  /*
5
92  * This can be refined. Currently, tries to do round robin, instead
6
93  * should do concentratic circle search, starting from current node.
7
94  */
8
95  struct page * alloc_pages(int gfp_mask, unsigned long order)
9
96  {
10
97     struct page *ret = 0;
11
98     pg_data_t *start, *temp;
12
99  #ifndef CONFIG_NUMA
13
100     unsigned long flags;
14
101     static pg_data_t *next = 0;
15
102 #endif
16
103
17
104 if (order >= MAX_ORDER)
18
105     return NULL;
19
106 #ifdef CONFIG_NUMA
20
107     temp = NODE_DATA(numa_node_id());
21
108 #else
22
109     spin_lock_irqsave(&node_lock, flags);
23
110     if (!next) next = pgdat_list;
24
111     temp = next;
25
112     next = next->node_next;
26
113     spin_unlock_irqrestore(&node_lock, flags);
27
114 #endif
28
115     start = temp;
29
116 while (temp) {
30
117     if ((ret = alloc_pages_pgdat(temp, gfp_mask, order)))
31
118         return(ret);
32
119     temp = temp->node_next;
33
120 }
34
121 temp = pgdat_list;
35
122 while (temp != start) {
36
123    if ((ret = alloc_pages_pgdat(temp, gfp_mask, order)))
37
124        return(ret);
38
125     temp = temp->node_next;
39
126 }
40
127     return(0);
41
128 }
1.2 alloc_pages_pgdat函式: NUMA和UMA機制下都使用了相同的函式,在UMA處在做詳細介紹 gfp_mask相當於node_zonelists陣列的下標
 
            
             
            
            
             
            
           
           
           
           
           
            
             
             
               1
              
             
            
85  static struct page * alloc_pages_pgdat(pg_data_t *pgdat, int gfp_mask,
2
86 unsigned long order)
3
87  {
4
88     return <