- 论坛徽章:
- 13
|
本帖最后由 _nosay 于 2016-02-18 11:33 编辑
《Linux内核源代码情景分析》第50页:
我最开始看到这句话的时候,产生了一个疑问,就是代表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大小了。
- linux-2.4.0, mm/page_alloc.c, 705~752
- /*
- * Builds allocation fallback zone lists.
- */
- static inline void build_zonelists(pg_data_t *pgdat)
- {
- int i, j, k;
- for (i = 0; i < NR_GFPINDEX; i++) {
- zonelist_t *zonelist;
- zone_t *zone;
- zonelist = pgdat->node_zonelists + i;
- memset(zonelist, 0, sizeof(*zonelist));
- zonelist->gfp_mask = i;
- j = 0;
- k = ZONE_NORMAL;
- if (i & __GFP_HIGHMEM)
- k = ZONE_HIGHMEM;
- if (i & __GFP_DMA)
- k = ZONE_DMA;
- switch (k) {
- default:
- BUG();
- /*
- * fallthrough:
- */
- case ZONE_HIGHMEM:
- zone = pgdat->node_zones + ZONE_HIGHMEM;
- if (zone->size) {
- #ifndef CONFIG_HIGHMEM
- BUG();
- #endif
- zonelist->zones[j++] = zone;
- }
- case ZONE_NORMAL:
- zone = pgdat->node_zones + ZONE_NORMAL;
- if (zone->size)
- zonelist->zones[j++] = zone;
- case ZONE_DMA:
- zone = pgdat->node_zones + ZONE_DMA;
- if (zone->size)
- zonelist->zones[j++] = zone;
- }
- zonelist->zones[j++] = NULL;
- }
- }
复制代码
- build_zonelists()函数模拟
- #include <stdio.h>
- int main()
- {
- int i, k;
- for (i = 0; i < 256; i ++)
- {
- k = 1;
- if (i & 0x10)
- k = 2;
- if (i & 0x08)
- k = 0;
- printf("zonelist[%d]: ", i);
- switch (k)
- {
- case 2:
- printf("highmem ");
- case 1:
- printf("normal ");
- case 0:
- printf("dma ");
- default:
- break;
- }
- printf("\n");
- }
- return 0;
- }
复制代码 |
|