免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 723 | 回复: 3

[内核入门] 分配策略数组大小疑问? [复制链接]

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
发表于 2016-02-18 10:36 |显示全部楼层
本帖最后由 _nosay 于 2016-02-18 11:33 编辑

《Linux内核源代码情景分析》第50页:
分配策略.png

我最开始看到这句话的时候,产生了一个疑问,就是代表1个CPU结点的pglist_data结构,最多只有3个zone,怎么也拼不出来256种组合呀,数组定义这么大不是浪费么?
后来我“想通了”,这256个指针不一定非要指向自己的zone,也可以指向别的pglist_data结构的zone。
但是看了build_zonelists()函数,我又怀疑自己了,这256个指针都是指向pgdat的3个zone,而且有好多重复的(其实就“highmem→normal→dma→null”、“normal→dma→null”、“dma→null” 3种组合),所以又不明白node_zonelists[]数组为什么要定义成256大小了。

  1. linux-2.4.0, mm/page_alloc.c, 705~752
  2. /*
  3. * Builds allocation fallback zone lists.
  4. */
  5. static inline void build_zonelists(pg_data_t *pgdat)
  6. {
  7.         int i, j, k;

  8.         for (i = 0; i < NR_GFPINDEX; i++) {
  9.                 zonelist_t *zonelist;
  10.                 zone_t *zone;

  11.                 zonelist = pgdat->node_zonelists + i;
  12.                 memset(zonelist, 0, sizeof(*zonelist));

  13.                 zonelist->gfp_mask = i;
  14.                 j = 0;
  15.                 k = ZONE_NORMAL;
  16.                 if (i & __GFP_HIGHMEM)
  17.                         k = ZONE_HIGHMEM;
  18.                 if (i & __GFP_DMA)
  19.                         k = ZONE_DMA;

  20.                 switch (k) {
  21.                         default:
  22.                                 BUG();
  23.                         /*
  24.                          * fallthrough:
  25.                          */
  26.                         case ZONE_HIGHMEM:
  27.                                 zone = pgdat->node_zones + ZONE_HIGHMEM;
  28.                                 if (zone->size) {
  29. #ifndef CONFIG_HIGHMEM
  30.                                         BUG();
  31. #endif
  32.                                         zonelist->zones[j++] = zone;
  33.                                 }
  34.                         case ZONE_NORMAL:
  35.                                 zone = pgdat->node_zones + ZONE_NORMAL;
  36.                                 if (zone->size)
  37.                                         zonelist->zones[j++] = zone;
  38.                         case ZONE_DMA:
  39.                                 zone = pgdat->node_zones + ZONE_DMA;
  40.                                 if (zone->size)
  41.                                         zonelist->zones[j++] = zone;
  42.                 }
  43.                 zonelist->zones[j++] = NULL;
  44.         }
  45. }
复制代码

  1. build_zonelists()函数模拟

  2. #include <stdio.h>

  3. int main()
  4. {
  5.         int i, k;

  6.         for (i = 0; i < 256; i ++)
  7.         {
  8.                 k = 1;
  9.                 if (i & 0x10)
  10.                         k = 2;
  11.                 if (i & 0x08)
  12.                         k = 0;

  13.                 printf("zonelist[%d]: ", i);

  14.                 switch (k)
  15.                 {
  16.                 case 2:
  17.                         printf("highmem ");
  18.                 case 1:
  19.                         printf("normal ");
  20.                 case 0:
  21.                         printf("dma ");
  22.                 default:
  23.                         break;
  24.                 }

  25.                 printf("\n");
  26.         }

  27.         return 0;
  28. }
复制代码

  1. 打印结果:
  2. zonelist[0]: normal dma
  3. zonelist[1]: normal dma
  4. zonelist[2]: normal dma
  5. zonelist[3]: normal dma
  6. zonelist[4]: normal dma
  7. zonelist[5]: normal dma
  8. zonelist[6]: normal dma
  9. zonelist[7]: normal dma
  10. zonelist[8]: dma
  11. zonelist[9]: dma
  12. zonelist[10]: dma
  13. zonelist[11]: dma
  14. zonelist[12]: dma
  15. zonelist[13]: dma
  16. zonelist[14]: dma
  17. zonelist[15]: dma
  18. zonelist[16]: highmem normal dma
  19. zonelist[17]: highmem normal dma
  20. zonelist[18]: highmem normal dma
  21. zonelist[19]: highmem normal dma
  22. zonelist[20]: highmem normal dma
  23. zonelist[21]: highmem normal dma
  24. zonelist[22]: highmem normal dma
  25. zonelist[23]: highmem normal dma
  26. zonelist[24]: dma
  27. zonelist[25]: dma
  28. zonelist[26]: dma
  29. zonelist[27]: dma
  30. zonelist[28]: dma
  31. zonelist[29]: dma
  32. zonelist[30]: dma
  33. zonelist[31]: dma
  34. zonelist[32]: normal dma
  35. zonelist[33]: normal dma
  36. zonelist[34]: normal dma
  37. zonelist[35]: normal dma
  38. zonelist[36]: normal dma
  39. zonelist[37]: normal dma
  40. zonelist[38]: normal dma
  41. zonelist[39]: normal dma
  42. zonelist[40]: dma
  43. zonelist[41]: dma
  44. zonelist[42]: dma
  45. zonelist[43]: dma
  46. zonelist[44]: dma
  47. zonelist[45]: dma
  48. zonelist[46]: dma
  49. zonelist[47]: dma
  50. zonelist[48]: highmem normal dma
  51. zonelist[49]: highmem normal dma
  52. zonelist[50]: highmem normal dma
  53. zonelist[51]: highmem normal dma
  54. zonelist[52]: highmem normal dma
  55. zonelist[53]: highmem normal dma
  56. zonelist[54]: highmem normal dma
  57. zonelist[55]: highmem normal dma
  58. zonelist[56]: dma
  59. zonelist[57]: dma
  60. zonelist[58]: dma
  61. zonelist[59]: dma
  62. zonelist[60]: dma
  63. zonelist[61]: dma
  64. zonelist[62]: dma
  65. zonelist[63]: dma
  66. zonelist[64]: normal dma
  67. zonelist[65]: normal dma
  68. zonelist[66]: normal dma
  69. zonelist[67]: normal dma
  70. zonelist[68]: normal dma
  71. zonelist[69]: normal dma
  72. zonelist[70]: normal dma
  73. zonelist[71]: normal dma
  74. zonelist[72]: dma
  75. zonelist[73]: dma
  76. zonelist[74]: dma
  77. zonelist[75]: dma
  78. zonelist[76]: dma
  79. zonelist[77]: dma
  80. zonelist[78]: dma
  81. zonelist[79]: dma
  82. zonelist[80]: highmem normal dma
  83. zonelist[81]: highmem normal dma
  84. zonelist[82]: highmem normal dma
  85. zonelist[83]: highmem normal dma
  86. zonelist[84]: highmem normal dma
  87. zonelist[85]: highmem normal dma
  88. zonelist[86]: highmem normal dma
  89. zonelist[87]: highmem normal dma
  90. zonelist[88]: dma
  91. zonelist[89]: dma
  92. zonelist[90]: dma
  93. zonelist[91]: dma
  94. zonelist[92]: dma
  95. zonelist[93]: dma
  96. zonelist[94]: dma
  97. zonelist[95]: dma
  98. zonelist[96]: normal dma
  99. zonelist[97]: normal dma
  100. zonelist[98]: normal dma
  101. zonelist[99]: normal dma
  102. zonelist[100]: normal dma
  103. zonelist[101]: normal dma
  104. zonelist[102]: normal dma
  105. zonelist[103]: normal dma
  106. zonelist[104]: dma
  107. zonelist[105]: dma
  108. zonelist[106]: dma
  109. zonelist[107]: dma
  110. zonelist[108]: dma
  111. zonelist[109]: dma
  112. zonelist[110]: dma
  113. zonelist[111]: dma
  114. zonelist[112]: highmem normal dma
  115. zonelist[113]: highmem normal dma
  116. zonelist[114]: highmem normal dma
  117. zonelist[115]: highmem normal dma
  118. zonelist[116]: highmem normal dma
  119. zonelist[117]: highmem normal dma
  120. zonelist[118]: highmem normal dma
  121. zonelist[119]: highmem normal dma
  122. zonelist[120]: dma
  123. zonelist[121]: dma
  124. zonelist[122]: dma
  125. zonelist[123]: dma
  126. zonelist[124]: dma
  127. zonelist[125]: dma
  128. zonelist[126]: dma
  129. zonelist[127]: dma
  130. zonelist[128]: normal dma
  131. zonelist[129]: normal dma
  132. zonelist[130]: normal dma
  133. zonelist[131]: normal dma
  134. zonelist[132]: normal dma
  135. zonelist[133]: normal dma
  136. zonelist[134]: normal dma
  137. zonelist[135]: normal dma
  138. zonelist[136]: dma
  139. zonelist[137]: dma
  140. zonelist[138]: dma
  141. zonelist[139]: dma
  142. zonelist[140]: dma
  143. zonelist[141]: dma
  144. zonelist[142]: dma
  145. zonelist[143]: dma
  146. zonelist[144]: highmem normal dma
  147. zonelist[145]: highmem normal dma
  148. zonelist[146]: highmem normal dma
  149. zonelist[147]: highmem normal dma
  150. zonelist[148]: highmem normal dma
  151. zonelist[149]: highmem normal dma
  152. zonelist[150]: highmem normal dma
  153. zonelist[151]: highmem normal dma
  154. zonelist[152]: dma
  155. zonelist[153]: dma
  156. zonelist[154]: dma
  157. zonelist[155]: dma
  158. zonelist[156]: dma
  159. zonelist[157]: dma
  160. zonelist[158]: dma
  161. zonelist[159]: dma
  162. zonelist[160]: normal dma
  163. zonelist[161]: normal dma
  164. zonelist[162]: normal dma
  165. zonelist[163]: normal dma
  166. zonelist[164]: normal dma
  167. zonelist[165]: normal dma
  168. zonelist[166]: normal dma
  169. zonelist[167]: normal dma
  170. zonelist[168]: dma
  171. zonelist[169]: dma
  172. zonelist[170]: dma
  173. zonelist[171]: dma
  174. zonelist[172]: dma
  175. zonelist[173]: dma
  176. zonelist[174]: dma
  177. zonelist[175]: dma
  178. zonelist[176]: highmem normal dma
  179. zonelist[177]: highmem normal dma
  180. zonelist[178]: highmem normal dma
  181. zonelist[179]: highmem normal dma
  182. zonelist[180]: highmem normal dma
  183. zonelist[181]: highmem normal dma
  184. zonelist[182]: highmem normal dma
  185. zonelist[183]: highmem normal dma
  186. zonelist[184]: dma
  187. zonelist[185]: dma
  188. zonelist[186]: dma
  189. zonelist[187]: dma
  190. zonelist[188]: dma
  191. zonelist[189]: dma
  192. zonelist[190]: dma
  193. zonelist[191]: dma
  194. zonelist[192]: normal dma
  195. zonelist[193]: normal dma
  196. zonelist[194]: normal dma
  197. zonelist[195]: normal dma
  198. zonelist[196]: normal dma
  199. zonelist[197]: normal dma
  200. zonelist[198]: normal dma
  201. zonelist[199]: normal dma
  202. zonelist[200]: dma
  203. zonelist[201]: dma
  204. zonelist[202]: dma
  205. zonelist[203]: dma
  206. zonelist[204]: dma
  207. zonelist[205]: dma
  208. zonelist[206]: dma
  209. zonelist[207]: dma
  210. zonelist[208]: highmem normal dma
  211. zonelist[209]: highmem normal dma
  212. zonelist[210]: highmem normal dma
  213. zonelist[211]: highmem normal dma
  214. zonelist[212]: highmem normal dma
  215. zonelist[213]: highmem normal dma
  216. zonelist[214]: highmem normal dma
  217. zonelist[215]: highmem normal dma
  218. zonelist[216]: dma
  219. zonelist[217]: dma
  220. zonelist[218]: dma
  221. zonelist[219]: dma
  222. zonelist[220]: dma
  223. zonelist[221]: dma
  224. zonelist[222]: dma
  225. zonelist[223]: dma
  226. zonelist[224]: normal dma
  227. zonelist[225]: normal dma
  228. zonelist[226]: normal dma
  229. zonelist[227]: normal dma
  230. zonelist[228]: normal dma
  231. zonelist[229]: normal dma
  232. zonelist[230]: normal dma
  233. zonelist[231]: normal dma
  234. zonelist[232]: dma
  235. zonelist[233]: dma
  236. zonelist[234]: dma
  237. zonelist[235]: dma
  238. zonelist[236]: dma
  239. zonelist[237]: dma
  240. zonelist[238]: dma
  241. zonelist[239]: dma
  242. zonelist[240]: highmem normal dma
  243. zonelist[241]: highmem normal dma
  244. zonelist[242]: highmem normal dma
  245. zonelist[243]: highmem normal dma
  246. zonelist[244]: highmem normal dma
  247. zonelist[245]: highmem normal dma
  248. zonelist[246]: highmem normal dma
  249. zonelist[247]: highmem normal dma
  250. zonelist[248]: dma
  251. zonelist[249]: dma
  252. zonelist[250]: dma
  253. zonelist[251]: dma
  254. zonelist[252]: dma
  255. zonelist[253]: dma
  256. zonelist[254]: dma
  257. zonelist[255]: dma
复制代码

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
发表于 2016-02-18 15:19 |显示全部楼层
本帖最后由 _nosay 于 2016-02-18 15:20 编辑

分配页面时,由gfp_mask表示使用哪种分配策略,gfp_mask的意义不仅仅是策略编号(即node_zonelists[]数组的下标),它的意义还在于它的一些二进制位上,策略编号确定的情况下,由于其它二进制位的不同,就会造成这个值整体上发生变化,从而相同的策略要在不同的位置都放一份。
  1. static inline struct page * alloc_pages(int gfp_mask, unsigned long order)
  2. {
  3.         /*
  4.          * Gets optimized away by the compiler.
  5.          */
  6.         if (order >= MAX_ORDER)
  7.                 return NULL;
  8.         return __alloc_pages(contig_page_data.node_zonelists+(gfp_mask), order);
  9. }
复制代码

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
发表于 2016-02-19 09:08 |显示全部楼层
HI:
     楼主,我觉得你想弄懂这个问题,请先更新你的内核版本,新版本中,定义如下:
struct pglist_data {
        struct zone node_zones[MAX_NR_ZONES];
        struct zonelist node_zonelists[MAX_ZONELISTS];
        int nr_zones;
}

#define MAX_NR_ZONES  根据系统中实际使用的区域数,一般为 2,其中包括 Normal 和 Highmem.
#define MAX_ZONELISTS 为系统所使用的节点数,在 UMA 系统中,一般为 1.

内核在使用 build_zonelists() 的时候会根据自身所具有的内存区域采取分配策略,内核会根据 GFP_* 标志从 Normal 或 Highmem 中分配内存.

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
发表于 2016-02-19 10:14 |显示全部楼层
Buddy_Zhang1 发表于 2016-02-19 09:08
HI:
     楼主,我觉得你想弄懂这个问题,请先更新你的内核版本,新版本中,定义如下:
struct pglist_data {
...


其实就是二楼说的那样,分配策略gfp_mask不光指定了zone的使用顺序:
① 通过__GFP_DMA、__GFP_HIGHMEM位,判断使用“highmem→normal→dma→null”、“normal→dma→null”、“dma→null”中的哪个顺序;
  (为什么没有__GFP_NORMAL?因为默认就是它。)
② __GFP_WAIT、__GFP_IO等其它位,对策略的描述。

现在假设对zone的使用顺序要求为__GFP_DMA(0x08),则gfp_mask低8位必须为xxxxx1xx,所以要保证00000100可以选到“dma→null”,也要保证0000101、0000110等,也能选到“dma→null”,所以就出现了模拟程序打印的那样,这样感觉不好,首先是浪费内存,另外是如果将来gfp_mask有意义的位超过了8位,node_zonelists[]数组的大小也要跟着变大才行。

个人理解,如果不对请帮忙纠正。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

DTCC2020中国数据库技术大会

【架构革新 高效可控】2020年12月21日-23日第十一届中国数据库技术大会将在北京隆重召开。

大会设置2大主会场,20+技术专场,将邀请超百位行业专家,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨,为广大数据领域从业人士提供一场年度盛会和交流平台。

http://dtcc.it168.com


大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP