__alloc_pages

2470 /*
2471  * This is the 'heart' of the zoned buddy allocator.
2472  */
/* 参数理解: */
/* GFP = Get Free Pages ? */
/* 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;
/* Convert GFP flags to their corresponding migrate type */ 2480 int migratetype = allocflags_to_migratetype(gfp_mask); 2481 unsigned int cpuset_mems_cookie; 2482
0373 /*
0374  * gfp_allowed_mask is set to GFP_BOOT_MASK during early boot to restrict what
0375  * GFP flags are used before interrupts are enabled. Once interrupts are
0376  * enabled, it is set to __GFP_BITS_MASK while the system is running. During
0377  * hibernation, it is used by PM to avoid I/O during memory allocation while
0378  * devices are suspended.
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 * Check the zones suitable for the gfp_mask contain at least one 2494 * valid zone. It's possible to have an empty zonelist as a result 2495 * of GFP_THISNODE and a memoryless node 2496 */ 2497 if (unlikely(!zonelist->_zonerefs->zone)) 2498 return NULL; 2499 2500 retry_cpuset: 2501 cpuset_mems_cookie = get_mems_allowed(); 2502 2503 /* The preferred zone is used for statistics later */ 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 * get_page_from_freelist goes through the zonelist trying to allocate 1780 * a page. 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 /* First allocation attempt */ 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 * When updating a task's mems_allowed, it is possible to race with 2524 * parallel threads in such a way that an allocation can fail while 2525 * the mask is being updated. If a page allocation is about to fail, 2526 * check if the cpuset changed during allocation and if so, retry. 2527 */ 2528 if (unlikely(!put_mems_allowed(cpuset_mems_cookie) && !page)) 2529 goto retry_cpuset; 2530 2531 return page; 2532 }

posted on 2013-08-23 12:55  kwingmei  阅读(480)  评论(0编辑  收藏  举报

导航