Commit 19655d34 authored by Christoph Lameter's avatar Christoph Lameter Committed by Linus Torvalds

[PATCH] linearly index zone->node_zonelists[]

I wonder why we need this bitmask indexing into zone->node_zonelists[]?

We always start with the highest zone and then include all lower zones
if we build zonelists.

Are there really cases where we need allocation from ZONE_DMA or
ZONE_HIGHMEM but not ZONE_NORMAL? It seems that the current implementation
of highest_zone() makes that already impossible.

If we go linear on the index then gfp_zone() == highest_zone() and a lot
of definitions fall by the wayside.

We can now revert back to the use of gfp_zone() in mempolicy.c ;-)
Signed-off-by: default avatarChristoph Lameter <clameter@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 2f6726e5
...@@ -12,9 +12,6 @@ struct vm_area_struct; ...@@ -12,9 +12,6 @@ struct vm_area_struct;
* *
* Zone modifiers (see linux/mmzone.h - low three bits) * Zone modifiers (see linux/mmzone.h - low three bits)
* *
* These may be masked by GFP_ZONEMASK to make allocations with this bit
* set fall back to ZONE_NORMAL.
*
* Do not put any conditional on these. If necessary modify the definitions * Do not put any conditional on these. If necessary modify the definitions
* without the underscores and use the consistently. The definitions here may * without the underscores and use the consistently. The definitions here may
* be used in bit comparisons. * be used in bit comparisons.
...@@ -78,14 +75,7 @@ struct vm_area_struct; ...@@ -78,14 +75,7 @@ struct vm_area_struct;
#define GFP_DMA32 __GFP_DMA32 #define GFP_DMA32 __GFP_DMA32
static inline int gfp_zone(gfp_t gfp) static inline enum zone_type gfp_zone(gfp_t flags)
{
int zone = GFP_ZONEMASK & (__force int) gfp;
BUG_ON(zone >= GFP_ZONETYPES);
return zone;
}
static inline enum zone_type highest_zone(gfp_t flags)
{ {
if (flags & __GFP_DMA) if (flags & __GFP_DMA)
return ZONE_DMA; return ZONE_DMA;
......
...@@ -137,60 +137,18 @@ enum zone_type { ...@@ -137,60 +137,18 @@ enum zone_type {
MAX_NR_ZONES MAX_NR_ZONES
}; };
/* /*
* When a memory allocation must conform to specific limitations (such * When a memory allocation must conform to specific limitations (such
* as being suitable for DMA) the caller will pass in hints to the * as being suitable for DMA) the caller will pass in hints to the
* allocator in the gfp_mask, in the zone modifier bits. These bits * allocator in the gfp_mask, in the zone modifier bits. These bits
* are used to select a priority ordered list of memory zones which * are used to select a priority ordered list of memory zones which
* match the requested limits. GFP_ZONEMASK defines which bits within * match the requested limits. See gfp_zone() in include/linux/gfp.h
* the gfp_mask should be considered as zone modifiers. Each valid
* combination of the zone modifier bits has a corresponding list
* of zones (in node_zonelists). Thus for two zone modifiers there
* will be a maximum of 4 (2 ** 2) zonelists, for 3 modifiers there will
* be 8 (2 ** 3) zonelists. GFP_ZONETYPES defines the number of possible
* combinations of zone modifiers in "zone modifier space".
*
* As an optimisation any zone modifier bits which are only valid when
* no other zone modifier bits are set (loners) should be placed in
* the highest order bits of this field. This allows us to reduce the
* extent of the zonelists thus saving space. For example in the case
* of three zone modifier bits, we could require up to eight zonelists.
* If the left most zone modifier is a "loner" then the highest valid
* zonelist would be four allowing us to allocate only five zonelists.
* Use the first form for GFP_ZONETYPES when the left most bit is not
* a "loner", otherwise use the second.
*
* NOTE! Make sure this matches the zones in <linux/gfp.h>
*/ */
#ifdef CONFIG_ZONE_DMA32 #if !defined(CONFIG_ZONE_DMA32) && !defined(CONFIG_HIGHMEM)
#define ZONES_SHIFT 1
#ifdef CONFIG_HIGHMEM
#define GFP_ZONETYPES ((GFP_ZONEMASK + 1) / 2 + 1) /* Loner */
#define GFP_ZONEMASK 0x07
#define ZONES_SHIFT 2 /* ceil(log2(MAX_NR_ZONES)) */
#else
#define GFP_ZONETYPES ((0x07 + 1) / 2 + 1) /* Loner */
/* Mask __GFP_HIGHMEM */
#define GFP_ZONEMASK 0x05
#define ZONES_SHIFT 2
#endif
#else #else
#ifdef CONFIG_HIGHMEM
#define GFP_ZONEMASK 0x03
#define ZONES_SHIFT 2 #define ZONES_SHIFT 2
#define GFP_ZONETYPES 3
#else
#define GFP_ZONEMASK 0x01
#define ZONES_SHIFT 1
#define GFP_ZONETYPES 2
#endif
#endif #endif
struct zone { struct zone {
...@@ -360,7 +318,7 @@ struct zonelist { ...@@ -360,7 +318,7 @@ struct zonelist {
struct bootmem_data; struct bootmem_data;
typedef struct pglist_data { typedef struct pglist_data {
struct zone node_zones[MAX_NR_ZONES]; struct zone node_zones[MAX_NR_ZONES];
struct zonelist node_zonelists[GFP_ZONETYPES]; struct zonelist node_zonelists[MAX_NR_ZONES];
int nr_zones; int nr_zones;
#ifdef CONFIG_FLAT_NODE_MEM_MAP #ifdef CONFIG_FLAT_NODE_MEM_MAP
struct page *node_mem_map; struct page *node_mem_map;
......
...@@ -1101,7 +1101,7 @@ static struct zonelist *zonelist_policy(gfp_t gfp, struct mempolicy *policy) ...@@ -1101,7 +1101,7 @@ static struct zonelist *zonelist_policy(gfp_t gfp, struct mempolicy *policy)
case MPOL_BIND: case MPOL_BIND:
/* Lower zones don't get a policy applied */ /* Lower zones don't get a policy applied */
/* Careful: current->mems_allowed might have moved */ /* Careful: current->mems_allowed might have moved */
if (highest_zone(gfp) >= policy_zone) if (gfp_zone(gfp) >= policy_zone)
if (cpuset_zonelist_valid_mems_allowed(policy->v.zonelist)) if (cpuset_zonelist_valid_mems_allowed(policy->v.zonelist))
return policy->v.zonelist; return policy->v.zonelist;
/*FALL THROUGH*/ /*FALL THROUGH*/
......
...@@ -1444,14 +1444,14 @@ static int __meminit find_next_best_node(int node, nodemask_t *used_node_mask) ...@@ -1444,14 +1444,14 @@ static int __meminit find_next_best_node(int node, nodemask_t *used_node_mask)
static void __meminit build_zonelists(pg_data_t *pgdat) static void __meminit build_zonelists(pg_data_t *pgdat)
{ {
int i, j, node, local_node; int j, node, local_node;
enum zone_type i;
int prev_node, load; int prev_node, load;
struct zonelist *zonelist; struct zonelist *zonelist;
nodemask_t used_mask; nodemask_t used_mask;
enum zone_type k;
/* initialize zonelists */ /* initialize zonelists */
for (i = 0; i < GFP_ZONETYPES; i++) { for (i = 0; i < MAX_NR_ZONES; i++) {
zonelist = pgdat->node_zonelists + i; zonelist = pgdat->node_zonelists + i;
zonelist->zones[0] = NULL; zonelist->zones[0] = NULL;
} }
...@@ -1481,13 +1481,11 @@ static void __meminit build_zonelists(pg_data_t *pgdat) ...@@ -1481,13 +1481,11 @@ static void __meminit build_zonelists(pg_data_t *pgdat)
node_load[node] += load; node_load[node] += load;
prev_node = node; prev_node = node;
load--; load--;
for (i = 0; i < GFP_ZONETYPES; i++) { for (i = 0; i < MAX_NR_ZONES; i++) {
zonelist = pgdat->node_zonelists + i; zonelist = pgdat->node_zonelists + i;
for (j = 0; zonelist->zones[j] != NULL; j++); for (j = 0; zonelist->zones[j] != NULL; j++);
k = highest_zone(i); j = build_zonelists_node(NODE_DATA(node), zonelist, j, i);
j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
zonelist->zones[j] = NULL; zonelist->zones[j] = NULL;
} }
} }
...@@ -1497,19 +1495,16 @@ static void __meminit build_zonelists(pg_data_t *pgdat) ...@@ -1497,19 +1495,16 @@ static void __meminit build_zonelists(pg_data_t *pgdat)
static void __meminit build_zonelists(pg_data_t *pgdat) static void __meminit build_zonelists(pg_data_t *pgdat)
{ {
int i, node, local_node; int node, local_node;
enum zone_type k; enum zone_type i,j;
enum zone_type j;
local_node = pgdat->node_id; local_node = pgdat->node_id;
for (i = 0; i < GFP_ZONETYPES; i++) { for (i = 0; i < MAX_NR_ZONES; i++) {
struct zonelist *zonelist; struct zonelist *zonelist;
zonelist = pgdat->node_zonelists + i; zonelist = pgdat->node_zonelists + i;
j = 0; j = build_zonelists_node(pgdat, zonelist, 0, i);
k = highest_zone(i);
j = build_zonelists_node(pgdat, zonelist, j, k);
/* /*
* Now we build the zonelist so that it contains the zones * Now we build the zonelist so that it contains the zones
* of all the other nodes. * of all the other nodes.
...@@ -1521,12 +1516,12 @@ static void __meminit build_zonelists(pg_data_t *pgdat) ...@@ -1521,12 +1516,12 @@ static void __meminit build_zonelists(pg_data_t *pgdat)
for (node = local_node + 1; node < MAX_NUMNODES; node++) { for (node = local_node + 1; node < MAX_NUMNODES; node++) {
if (!node_online(node)) if (!node_online(node))
continue; continue;
j = build_zonelists_node(NODE_DATA(node), zonelist, j, k); j = build_zonelists_node(NODE_DATA(node), zonelist, j, i);
} }
for (node = 0; node < local_node; node++) { for (node = 0; node < local_node; node++) {
if (!node_online(node)) if (!node_online(node))
continue; continue;
j = build_zonelists_node(NODE_DATA(node), zonelist, j, k); j = build_zonelists_node(NODE_DATA(node), zonelist, j, i);
} }
zonelist->zones[j] = NULL; zonelist->zones[j] = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment