2.7 Linux儲存管理-物理頁面分配
阿新 • • 發佈:2018-11-23
程序需要的連續的頁面,通過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
1
1. NUMA的分配記憶體函式: 選擇CONFIG_DISCONTIGMEM選項 被編譯的條件是“不連續的儲存空間”,而不是CONFIG_NUMA,但是CONFIG_NUMA會對程式造成影響 alloc_pages(int gfp_mask,unsigned long order)
numa的alloc_pages的程式碼:
如果定義了NUMA,就需要獲取 pgdat_list,並且需要遍歷所有的pg_data_t節點 分配時輪流從各個節點開始,並希望各節點負載均衡 在每個節點上使用 alloc_pages_pgdat函式
==================== 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陣列的下標
85 static struct page * alloc_pages_pgdat(pg_data_t *pgdat, int gfp_mask,
2
86 unsigned long order)
3
87 {
4
88 return <