GFP_ZONEMASK vs. MAX_NR_ZONES
Subsystems (4)
PATCH 1/1 GFP_ZONEMASK vs. MAX_NR_ZONES
Ok... hot on the heels of the other GFP_ZONEMASK patch:
struct bootmem_data;
typedef struct pglist_data {
struct zone node_zones[MAX_NR_ZONES];
struct zonelist node_zonelists[GFP_ZONEMASK+1];
int nr_zones;
struct page *node_mem_map;
unsigned long *valid_addr_bitmap;
struct bootmem_data *bdata;
unsigned long node_start_pfn;
unsigned long node_size;
int node_id;
struct pglist_data *pgdat_next;
wait_queue_head_t kswapd_wait;
} pg_data_t;node_zonelists looks like it should really be declared of size MAX_NR_ZONES, not GFP_ZONEMASK. GFP_ZONEMASK is currently 15, making node_zonelists an array of 16 elements. The extra zonelists are all just duplicates of the *real* zonelists, namely the first 3 entries. Again, if anyone can explain to me why I'm wrong in my thinking, I'd love to know. There's certainly no way you could bitwise-and something with any combination of the GFP_DMA and GFP_HIGHMEM flags to refer to the 12th zonelist or some such! Or am I crazy?
Cheers!
-Matt
include/linux/mmzone.h +1 -1
@@ -178,7 +178,7 @@struct bootmem_data ; typedef struct pglist_data { struct zone node_zones[MAX_NR_ZONES]; - struct zonelist node_zonelists[GFP_ZONEMASK+1]; + struct zonelist node_zonelists[MAX_NR_ZONES]; int nr_zones; struct page *node_mem_map; unsigned long *valid_addr_bitmap;
mm/page_alloc.c +1 -1
@@ -1028,7 +1028,7 @@ local_node = pgdat->node_id;printk ("Building zonelist for node : %d\n" , local_node); -for (i =0 ; i <=GFP_ZONEMASK ; i++) { +for (i =0 ; i <MAX_NR_ZONES ; i++) {struct zonelist *zonelist; zonelist = pgdat->node_zonelists + i;
Quoted 8 lines · Matthew Dobson
node_zonelistslooks like it should really be declared of sizeMAX_NR_ZONES, notGFP_ZONEMASK.GFP_ZONEMASKis currently 15, makingnode_zonelistsan array of 16 elements. The extra zonelists are all just duplicates of the *real* zonelists, namely the first 3 entries. Again, if anyone can explain to me why I'm wrong in my thinking, I'd love to know. There's certainly no way you could bitwise-and something with any combination of theGFP_DMAandGFP_HIGHMEMflags to refer to the 12th zonelist or some such! Or am I crazy?
No, you're not crazy, you're right:
#define __GFP_DMA 0x01
#define __GFP_HIGHMEM 0x02
/* Action modifiers - doesn't change the zoning */
#define __GFP_WAIT 0x10 /* Can wait and reschedule? */ #define __GFP_HIGH 0x20 /* Should access emergency pools? */ #define __GFP_IO 0x40 /* Can start physical IO? */ #define __GFP_FS 0x80 /* Can call down to low-level FS? */ #define __GFP_COLD 0x100 /* Cache-cold page required */ #define __GFP_NOWARN 0x200 /* Suppress page allocation failure warning */
bits 3-6 of gfp masks are totally unused.
-- wli