2470
2471
2472 /* 098 typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t; */
/* #define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)] */
/* typedef struct { unsigned long bits[ BITS_TO_LONGS( MAX_NUMNODES) ]; } nodemask_t */
/* #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) */
/* #define BITS_PER_BYTE 8 */
/* #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) */
/* d表示一个数据类型有多少bit, n表示要存储多少位, 现在计算要多少个这样的数据类型 */
/* order 表示 2^order 个页 */
/ zonelist 表示zone的链表 */
2473 struct page *
2474 __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
2475 struct zonelist *zonelist, nodemask_t *nodemask)
2476 {
2477 enum zone_type high_zoneidx = gfp_zone(gfp_mask);
/*
0247 static inline enum zone_type gfp_zone(gfp_t flags)
0248 {
0249 enum zone_type z;
0250 int bit = (__force int) (flags & GFP_ZONEMASK); /* 过滤这些标志位吗 ? */
0251
0252 z = (GFP_ZONE_TABLE >> (bit * ZONES_SHIFT)) &
0253 ((1 << ZONES_SHIFT) - 1);
0254 VM_BUG_ON((GFP_ZONE_BAD >> bit) & 1);
0255 return z;
0256 }
*/
/*
0219 #define GFP_ZONE_TABLE ( \
0220 (ZONE_NORMAL << 0 * ZONES_SHIFT) \
0221 | (OPT_ZONE_DMA << ___GFP_DMA * ZONES_SHIFT) \
0222 | (OPT_ZONE_HIGHMEM << ___GFP_HIGHMEM * ZONES_SHIFT) \
0223 | (OPT_ZONE_DMA32 << ___GFP_DMA32 * ZONES_SHIFT) \
0224 | (ZONE_NORMAL << ___GFP_MOVABLE * ZONES_SHIFT) \
0225 | (OPT_ZONE_DMA << (___GFP_MOVABLE | ___GFP_DMA) * ZONES_SHIFT) \
0226 | (ZONE_MOVABLE << (___GFP_MOVABLE | ___GFP_HIGHMEM) * ZONES_SHIFT) \
0227 | (OPT_ZONE_DMA32 << (___GFP_MOVABLE | ___GFP_DMA32) * ZONES_SHIFT) \
0228 )
*/
/* #define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE) */
/*
0319 #if MAX_NR_ZONES < 2
0320 #define ZONES_SHIFT 0
0321 #elif MAX_NR_ZONES <= 2
0322 #define ZONES_SHIFT 1
0323 #elif MAX_NR_ZONES <= 4
0324 #define ZONES_SHIFT 2
*/
/* 这么多就是要获取zone的下标 */
2478 struct zone *preferred_zone;
2479 struct page *page = NULL;
2480 int migratetype = allocflags_to_migratetype(gfp_mask);
2481 unsigned int cpuset_mems_cookie;
2482
0373
0374
0375
0376
0377
0378
0379
2483 gfp_mask &= gfp_allowed_mask;
2484
2485 lockdep_trace_alloc(gfp_mask);
2486
/*
0169 #define might_sleep_if(cond) do { if (cond) might_sleep(); } while (0)
*/
2487 might_sleep_if(gfp_mask & __GFP_WAIT);
2488
2489 if (should_fail_alloc_page(gfp_mask, order))
2490 return NULL;
2491
2492
2493
2494
2495
2496
2497 if (unlikely(!zonelist->_zonerefs->zone))
2498 return NULL;
2499
2500 retry_cpuset:
2501 cpuset_mems_cookie = get_mems_allowed();
2502
2503
2504 first_zones_zonelist(zonelist, high_zoneidx,
2505 nodemask ? : &cpuset_current_mems_allowed,
2506 &preferred_zone);
2507 if (!preferred_zone)
2508 goto out;
2509
/*
1779
1780
1781
1782 static struct page *
1783 get_page_from_freelist(gfp_t gfp_mask, nodemask_t *nodemask, unsigned int order,
1784 struct zonelist *zonelist, int high_zoneidx, int alloc_flags,
1785 struct zone *preferred_zone, int migratetype){ ... }
*/
2510
2511 page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, order,
2512 zonelist, high_zoneidx, ALLOC_WMARK_LOW|ALLOC_CPUSET,
2513 preferred_zone, migratetype);
2514 if (unlikely(!page)) /* 很少失败 */
2515 page = __alloc_pages_slowpath(gfp_mask, order,
2516 zonelist, high_zoneidx, nodemask,
2517 preferred_zone, migratetype);
2518
2519 trace_mm_page_alloc(page, order, gfp_mask, migratetype);
2520
2521 out:
2522
2523
2524
2525
2526
2527
2528 if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page))
2529 goto retry_cpuset;
2530
2531 return page;
2532 }