1. 程式人生 > >gfp_mask轉換成對應的zone

gfp_mask轉換成對應的zone

在分配記憶體時,都會帶分配引數比如GPF_KERNEL等等,那麼,一次記憶體分配從哪個zone分配了?

這裡就必需把mask轉換成zone,gfp_mask低4位用於表示分配的zone

static inline enum zone_type gfp_zone(gfp_t flags) {     enum zone_type z;     int bit = (__force int) (flags & GFP_ZONEMASK);

    z = (GFP_ZONE_TABLE >> (bit * ZONES_SHIFT)) &                      ((1 << ZONES_SHIFT) - 1);     VM_BUG_ON((GFP_ZONE_BAD >> bit) & 1);     return z; }

其中ZONES_SHIFT,表示系統中的zone個數不超過2的ZONE_SHIFT次方,比如zone個數為5,那麼zone_SHIFT=3,用

3bit表示zone的index(0-5),如果只有三個zone,那麼ZONES_SHIFT=2,因為2個bit,可以表示4個數.

GFP_ZONEMASK定義的地方如下: #define GFP_ZONEMASK    (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE)

#ifdef CONFIG_HIGHMEM #define OPT_ZONE_HIGHMEM ZONE_HIGHMEM #else #define OPT_ZONE_HIGHMEM ZONE_NORMAL #endif

#ifdef CONFIG_ZONE_DMA #define OPT_ZONE_DMA ZONE_DMA #else #define OPT_ZONE_DMA ZONE_NORMAL #endif

#ifdef CONFIG_ZONE_DMA32 #define OPT_ZONE_DMA32 ZONE_DMA32 #else #define OPT_ZONE_DMA32 ZONE_NORMAL #endif

從其定義可以看出,如果沒有定義HIGHMEM,則ZONE_HIGHMEM自動指向ZONE_NORMAL,其他類似。GFP_ZONE_TABLE的定義,其實是將各個ZONE的值放到對應的BIT位上,ZONE_NORMAL放到[0,ZONE_SHIFT)位,GFP_DMA放到[ZONE_SHIFT, 2*ZONE_SHIFT)位上,依此類推。

bit*ZONE_SHIFT即得到該ZONE所對應的BIT位,然後將GFP_ZONE_TABLE左移所得位數量,這時候得到的是從這個ZONE開始往上的所有BIT位,要將無關的ZONE清零,即只取低ZONE_SHIFT位,所以要&((1<<ZONE_SHITF) -1)