[PATCH 3/6] Use two zonelist that are filtered by GFP mask

2007-11-09 Thread Mel Gorman

Currently a node has a number of zonelists, one for each zone type in the
system and a second set for GFP_THISNODE allocations. Based on the zones allowed
by a gfp mask, one of these zonelists is selected. All of these zonelists
consume memory and occupy cache lines.

This patch replaces the multiple zonelists per-node with two zonelists. The
first contains all populated zones in the system and the second contains all
populated zones in node suitable for GFP_THISNODE allocations. An iterator
macro is introduced called for_each_zone_zonelist() interates through each
zone in the zonelist that is allowed by the GFP flags.

Signed-off-by: Mel Gorman <[EMAIL PROTECTED]>
Acked-by: Christoph Lameter <[EMAIL PROTECTED]>
---

 arch/parisc/mm/init.c  |   11 +-
 fs/buffer.c|6 +
 include/linux/gfp.h|   17 +---
 include/linux/mmzone.h |   65 +++-
 mm/hugetlb.c   |8 +-
 mm/oom_kill.c  |8 +-
 mm/page_alloc.c|  169 +++-
 mm/slab.c  |8 +-
 mm/slub.c  |8 +-
 mm/vmscan.c|   20 ++---
 10 files changed, 159 insertions(+), 161 deletions(-)

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.24-rc1-mm-007_node_zonelist/arch/parisc/mm/init.c 
linux-2.6.24-rc1-mm-010_use_two_zonelists/arch/parisc/mm/init.c
--- linux-2.6.24-rc1-mm-007_node_zonelist/arch/parisc/mm/init.c 2007-11-08 
19:04:11.0 +
+++ linux-2.6.24-rc1-mm-010_use_two_zonelists/arch/parisc/mm/init.c 
2007-11-08 19:11:18.0 +
@@ -603,15 +603,18 @@ void show_mem(void)
 #ifdef CONFIG_DISCONTIGMEM
{
struct zonelist *zl;
-   int i, j, k;
+   int i, j;
 
for (i = 0; i < npmem_ranges; i++) {
+   zl = node_zonelist(i);
for (j = 0; j < MAX_NR_ZONES; j++) {
-   zl = NODE_DATA(i)->node_zonelists + j;
+   struct zone **z;
+   struct zone *zone;
 
printk("Zone list for zone %d on node %d: ", j, 
i);
-   for (k = 0; zl->zones[k] != NULL; k++) 
-   printk("[%d/%s] ", 
zone_to_nid(zl->zones[k]), zl->zones[k]->name);
+   for_each_zone_zonelist(zone, z, zl, j)
+   printk("[%d/%s] ", zone_to_nid(zone),
+   zone->name);
printk("\n");
}
}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.24-rc1-mm-007_node_zonelist/fs/buffer.c 
linux-2.6.24-rc1-mm-010_use_two_zonelists/fs/buffer.c
--- linux-2.6.24-rc1-mm-007_node_zonelist/fs/buffer.c   2007-11-08 
19:08:12.0 +
+++ linux-2.6.24-rc1-mm-010_use_two_zonelists/fs/buffer.c   2007-11-08 
19:11:18.0 +
@@ -375,9 +375,11 @@ static void free_more_memory(void)
yield();
 
for_each_online_node(nid) {
-   zones = node_zonelist(nid, GFP_NOFS);
+   zones = first_zones_zonelist(node_zonelist(nid, GFP_NOFS),
+   gfp_zone(GFP_NOFS));
if (*zones)
-   try_to_free_pages(zones, 0, GFP_NOFS);
+   try_to_free_pages(node_zonelist(nid, GFP_NOFS), 0,
+   GFP_NOFS);
}
 }
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.24-rc1-mm-007_node_zonelist/include/linux/gfp.h 
linux-2.6.24-rc1-mm-010_use_two_zonelists/include/linux/gfp.h
--- linux-2.6.24-rc1-mm-007_node_zonelist/include/linux/gfp.h   2007-11-08 
19:08:12.0 +
+++ linux-2.6.24-rc1-mm-010_use_two_zonelists/include/linux/gfp.h   
2007-11-08 19:11:18.0 +
@@ -119,29 +119,22 @@ static inline int allocflags_to_migratet
 
 static inline enum zone_type gfp_zone(gfp_t flags)
 {
-   int base = 0;
-
-#ifdef CONFIG_NUMA
-   if (flags & __GFP_THISNODE)
-   base = MAX_NR_ZONES;
-#endif
-
 #ifdef CONFIG_ZONE_DMA
if (flags & __GFP_DMA)
-   return base + ZONE_DMA;
+   return ZONE_DMA;
 #endif
 #ifdef CONFIG_ZONE_DMA32
if (flags & __GFP_DMA32)
-   return base + ZONE_DMA32;
+   return ZONE_DMA32;
 #endif
if ((flags & (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
-   return base + ZONE_MOVABLE;
+   return ZONE_MOVABLE;
 #ifdef CONFIG_HIGHMEM
if (flags & __GFP_HIGHMEM)
-   return base + ZONE_HIGHMEM;
+   return ZONE_HIGHMEM;
 #endif
-   return base + ZONE_NORMAL;
+   return ZONE_NORMAL;
 }
 
 static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 

[PATCH 3/6] Use two zonelist that are filtered by GFP mask

2007-11-09 Thread Mel Gorman

Currently a node has a number of zonelists, one for each zone type in the
system and a second set for GFP_THISNODE allocations. Based on the zones allowed
by a gfp mask, one of these zonelists is selected. All of these zonelists
consume memory and occupy cache lines.

This patch replaces the multiple zonelists per-node with two zonelists. The
first contains all populated zones in the system and the second contains all
populated zones in node suitable for GFP_THISNODE allocations. An iterator
macro is introduced called for_each_zone_zonelist() interates through each
zone in the zonelist that is allowed by the GFP flags.

Signed-off-by: Mel Gorman [EMAIL PROTECTED]
Acked-by: Christoph Lameter [EMAIL PROTECTED]
---

 arch/parisc/mm/init.c  |   11 +-
 fs/buffer.c|6 +
 include/linux/gfp.h|   17 +---
 include/linux/mmzone.h |   65 +++-
 mm/hugetlb.c   |8 +-
 mm/oom_kill.c  |8 +-
 mm/page_alloc.c|  169 +++-
 mm/slab.c  |8 +-
 mm/slub.c  |8 +-
 mm/vmscan.c|   20 ++---
 10 files changed, 159 insertions(+), 161 deletions(-)

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.24-rc1-mm-007_node_zonelist/arch/parisc/mm/init.c 
linux-2.6.24-rc1-mm-010_use_two_zonelists/arch/parisc/mm/init.c
--- linux-2.6.24-rc1-mm-007_node_zonelist/arch/parisc/mm/init.c 2007-11-08 
19:04:11.0 +
+++ linux-2.6.24-rc1-mm-010_use_two_zonelists/arch/parisc/mm/init.c 
2007-11-08 19:11:18.0 +
@@ -603,15 +603,18 @@ void show_mem(void)
 #ifdef CONFIG_DISCONTIGMEM
{
struct zonelist *zl;
-   int i, j, k;
+   int i, j;
 
for (i = 0; i  npmem_ranges; i++) {
+   zl = node_zonelist(i);
for (j = 0; j  MAX_NR_ZONES; j++) {
-   zl = NODE_DATA(i)-node_zonelists + j;
+   struct zone **z;
+   struct zone *zone;
 
printk(Zone list for zone %d on node %d: , j, 
i);
-   for (k = 0; zl-zones[k] != NULL; k++) 
-   printk([%d/%s] , 
zone_to_nid(zl-zones[k]), zl-zones[k]-name);
+   for_each_zone_zonelist(zone, z, zl, j)
+   printk([%d/%s] , zone_to_nid(zone),
+   zone-name);
printk(\n);
}
}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.24-rc1-mm-007_node_zonelist/fs/buffer.c 
linux-2.6.24-rc1-mm-010_use_two_zonelists/fs/buffer.c
--- linux-2.6.24-rc1-mm-007_node_zonelist/fs/buffer.c   2007-11-08 
19:08:12.0 +
+++ linux-2.6.24-rc1-mm-010_use_two_zonelists/fs/buffer.c   2007-11-08 
19:11:18.0 +
@@ -375,9 +375,11 @@ static void free_more_memory(void)
yield();
 
for_each_online_node(nid) {
-   zones = node_zonelist(nid, GFP_NOFS);
+   zones = first_zones_zonelist(node_zonelist(nid, GFP_NOFS),
+   gfp_zone(GFP_NOFS));
if (*zones)
-   try_to_free_pages(zones, 0, GFP_NOFS);
+   try_to_free_pages(node_zonelist(nid, GFP_NOFS), 0,
+   GFP_NOFS);
}
 }
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.24-rc1-mm-007_node_zonelist/include/linux/gfp.h 
linux-2.6.24-rc1-mm-010_use_two_zonelists/include/linux/gfp.h
--- linux-2.6.24-rc1-mm-007_node_zonelist/include/linux/gfp.h   2007-11-08 
19:08:12.0 +
+++ linux-2.6.24-rc1-mm-010_use_two_zonelists/include/linux/gfp.h   
2007-11-08 19:11:18.0 +
@@ -119,29 +119,22 @@ static inline int allocflags_to_migratet
 
 static inline enum zone_type gfp_zone(gfp_t flags)
 {
-   int base = 0;
-
-#ifdef CONFIG_NUMA
-   if (flags  __GFP_THISNODE)
-   base = MAX_NR_ZONES;
-#endif
-
 #ifdef CONFIG_ZONE_DMA
if (flags  __GFP_DMA)
-   return base + ZONE_DMA;
+   return ZONE_DMA;
 #endif
 #ifdef CONFIG_ZONE_DMA32
if (flags  __GFP_DMA32)
-   return base + ZONE_DMA32;
+   return ZONE_DMA32;
 #endif
if ((flags  (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
-   return base + ZONE_MOVABLE;
+   return ZONE_MOVABLE;
 #ifdef CONFIG_HIGHMEM
if (flags  __GFP_HIGHMEM)
-   return base + ZONE_HIGHMEM;
+   return ZONE_HIGHMEM;
 #endif
-   return base + ZONE_NORMAL;
+   return ZONE_NORMAL;
 }
 
 static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 

[PATCH 3/6] Use two zonelist that are filtered by GFP mask

2007-09-28 Thread Mel Gorman

Currently a node has a number of zonelists, one for each zone type in the
system and a second set for GFP_THISNODE allocations. Based on the zones allowed
by a gfp mask, one of these zonelists is selected. All of these zonelists
consume memory and occupy cache lines.

This patch replaces the multiple zonelists per-node with two zonelists. The
first contains all populated zones in the system and the second contains all
populated zones in node suitable for GFP_THISNODE allocations. An iterator
macro is introduced called for_each_zone_zonelist() interates through each
zone in the zonelist that is allowed by the GFP flags.

Signed-off-by: Mel Gorman <[EMAIL PROTECTED]>
Acked-by: Christoph Lameter <[EMAIL PROTECTED]>
---

 arch/parisc/mm/init.c  |   11 +-
 fs/buffer.c|6 +
 include/linux/gfp.h|   17 +---
 include/linux/mmzone.h |   65 +++-
 mm/hugetlb.c   |8 +-
 mm/oom_kill.c  |8 +-
 mm/page_alloc.c|  169 +++-
 mm/slab.c  |8 +-
 mm/slub.c  |8 +-
 mm/vmscan.c|   21 ++---
 10 files changed, 159 insertions(+), 162 deletions(-)

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc8-mm2-007_node_zonelist/arch/parisc/mm/init.c 
linux-2.6.23-rc8-mm2-010_use_two_zonelists/arch/parisc/mm/init.c
--- linux-2.6.23-rc8-mm2-007_node_zonelist/arch/parisc/mm/init.c
2007-09-25 01:33:10.0 +0100
+++ linux-2.6.23-rc8-mm2-010_use_two_zonelists/arch/parisc/mm/init.c
2007-09-28 15:49:16.0 +0100
@@ -599,15 +599,18 @@ void show_mem(void)
 #ifdef CONFIG_DISCONTIGMEM
{
struct zonelist *zl;
-   int i, j, k;
+   int i, j;
 
for (i = 0; i < npmem_ranges; i++) {
+   zl = node_zonelist(i);
for (j = 0; j < MAX_NR_ZONES; j++) {
-   zl = NODE_DATA(i)->node_zonelists + j;
+   struct zone **z;
+   struct zone *zone;
 
printk("Zone list for zone %d on node %d: ", j, 
i);
-   for (k = 0; zl->zones[k] != NULL; k++) 
-   printk("[%ld/%s] ", 
zone_to_nid(zl->zones[k]), zl->zones[k]->name);
+   for_each_zone_zonelist(zone, z, zl, j)
+   printk("[%d/%s] ", zone_to_nid(zone),
+   zone->name);
printk("\n");
}
}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc8-mm2-007_node_zonelist/fs/buffer.c 
linux-2.6.23-rc8-mm2-010_use_two_zonelists/fs/buffer.c
--- linux-2.6.23-rc8-mm2-007_node_zonelist/fs/buffer.c  2007-09-28 
15:48:55.0 +0100
+++ linux-2.6.23-rc8-mm2-010_use_two_zonelists/fs/buffer.c  2007-09-28 
15:49:16.0 +0100
@@ -375,9 +375,11 @@ static void free_more_memory(void)
yield();
 
for_each_online_node(nid) {
-   zones = node_zonelist(nid, GFP_NOFS);
+   zones = first_zones_zonelist(node_zonelist(nid, GFP_NOFS),
+   gfp_zone(GFP_NOFS));
if (*zones)
-   try_to_free_pages(zones, 0, GFP_NOFS);
+   try_to_free_pages(node_zonelist(nid, GFP_NOFS), 0,
+   GFP_NOFS);
}
 }
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc8-mm2-007_node_zonelist/include/linux/gfp.h 
linux-2.6.23-rc8-mm2-010_use_two_zonelists/include/linux/gfp.h
--- linux-2.6.23-rc8-mm2-007_node_zonelist/include/linux/gfp.h  2007-09-28 
15:48:55.0 +0100
+++ linux-2.6.23-rc8-mm2-010_use_two_zonelists/include/linux/gfp.h  
2007-09-28 15:49:16.0 +0100
@@ -119,29 +119,22 @@ static inline int allocflags_to_migratet
 
 static inline enum zone_type gfp_zone(gfp_t flags)
 {
-   int base = 0;
-
-#ifdef CONFIG_NUMA
-   if (flags & __GFP_THISNODE)
-   base = MAX_NR_ZONES;
-#endif
-
 #ifdef CONFIG_ZONE_DMA
if (flags & __GFP_DMA)
-   return base + ZONE_DMA;
+   return ZONE_DMA;
 #endif
 #ifdef CONFIG_ZONE_DMA32
if (flags & __GFP_DMA32)
-   return base + ZONE_DMA32;
+   return ZONE_DMA32;
 #endif
if ((flags & (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
-   return base + ZONE_MOVABLE;
+   return ZONE_MOVABLE;
 #ifdef CONFIG_HIGHMEM
if (flags & __GFP_HIGHMEM)
-   return base + ZONE_HIGHMEM;
+   return ZONE_HIGHMEM;
 #endif
-   return base + ZONE_NORMAL;
+   return ZONE_NORMAL;
 }
 
 static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
diff -rup -X 

[PATCH 3/6] Use two zonelist that are filtered by GFP mask

2007-09-28 Thread Mel Gorman

Currently a node has a number of zonelists, one for each zone type in the
system and a second set for GFP_THISNODE allocations. Based on the zones allowed
by a gfp mask, one of these zonelists is selected. All of these zonelists
consume memory and occupy cache lines.

This patch replaces the multiple zonelists per-node with two zonelists. The
first contains all populated zones in the system and the second contains all
populated zones in node suitable for GFP_THISNODE allocations. An iterator
macro is introduced called for_each_zone_zonelist() interates through each
zone in the zonelist that is allowed by the GFP flags.

Signed-off-by: Mel Gorman [EMAIL PROTECTED]
Acked-by: Christoph Lameter [EMAIL PROTECTED]
---

 arch/parisc/mm/init.c  |   11 +-
 fs/buffer.c|6 +
 include/linux/gfp.h|   17 +---
 include/linux/mmzone.h |   65 +++-
 mm/hugetlb.c   |8 +-
 mm/oom_kill.c  |8 +-
 mm/page_alloc.c|  169 +++-
 mm/slab.c  |8 +-
 mm/slub.c  |8 +-
 mm/vmscan.c|   21 ++---
 10 files changed, 159 insertions(+), 162 deletions(-)

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc8-mm2-007_node_zonelist/arch/parisc/mm/init.c 
linux-2.6.23-rc8-mm2-010_use_two_zonelists/arch/parisc/mm/init.c
--- linux-2.6.23-rc8-mm2-007_node_zonelist/arch/parisc/mm/init.c
2007-09-25 01:33:10.0 +0100
+++ linux-2.6.23-rc8-mm2-010_use_two_zonelists/arch/parisc/mm/init.c
2007-09-28 15:49:16.0 +0100
@@ -599,15 +599,18 @@ void show_mem(void)
 #ifdef CONFIG_DISCONTIGMEM
{
struct zonelist *zl;
-   int i, j, k;
+   int i, j;
 
for (i = 0; i  npmem_ranges; i++) {
+   zl = node_zonelist(i);
for (j = 0; j  MAX_NR_ZONES; j++) {
-   zl = NODE_DATA(i)-node_zonelists + j;
+   struct zone **z;
+   struct zone *zone;
 
printk(Zone list for zone %d on node %d: , j, 
i);
-   for (k = 0; zl-zones[k] != NULL; k++) 
-   printk([%ld/%s] , 
zone_to_nid(zl-zones[k]), zl-zones[k]-name);
+   for_each_zone_zonelist(zone, z, zl, j)
+   printk([%d/%s] , zone_to_nid(zone),
+   zone-name);
printk(\n);
}
}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc8-mm2-007_node_zonelist/fs/buffer.c 
linux-2.6.23-rc8-mm2-010_use_two_zonelists/fs/buffer.c
--- linux-2.6.23-rc8-mm2-007_node_zonelist/fs/buffer.c  2007-09-28 
15:48:55.0 +0100
+++ linux-2.6.23-rc8-mm2-010_use_two_zonelists/fs/buffer.c  2007-09-28 
15:49:16.0 +0100
@@ -375,9 +375,11 @@ static void free_more_memory(void)
yield();
 
for_each_online_node(nid) {
-   zones = node_zonelist(nid, GFP_NOFS);
+   zones = first_zones_zonelist(node_zonelist(nid, GFP_NOFS),
+   gfp_zone(GFP_NOFS));
if (*zones)
-   try_to_free_pages(zones, 0, GFP_NOFS);
+   try_to_free_pages(node_zonelist(nid, GFP_NOFS), 0,
+   GFP_NOFS);
}
 }
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc8-mm2-007_node_zonelist/include/linux/gfp.h 
linux-2.6.23-rc8-mm2-010_use_two_zonelists/include/linux/gfp.h
--- linux-2.6.23-rc8-mm2-007_node_zonelist/include/linux/gfp.h  2007-09-28 
15:48:55.0 +0100
+++ linux-2.6.23-rc8-mm2-010_use_two_zonelists/include/linux/gfp.h  
2007-09-28 15:49:16.0 +0100
@@ -119,29 +119,22 @@ static inline int allocflags_to_migratet
 
 static inline enum zone_type gfp_zone(gfp_t flags)
 {
-   int base = 0;
-
-#ifdef CONFIG_NUMA
-   if (flags  __GFP_THISNODE)
-   base = MAX_NR_ZONES;
-#endif
-
 #ifdef CONFIG_ZONE_DMA
if (flags  __GFP_DMA)
-   return base + ZONE_DMA;
+   return ZONE_DMA;
 #endif
 #ifdef CONFIG_ZONE_DMA32
if (flags  __GFP_DMA32)
-   return base + ZONE_DMA32;
+   return ZONE_DMA32;
 #endif
if ((flags  (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
-   return base + ZONE_MOVABLE;
+   return ZONE_MOVABLE;
 #ifdef CONFIG_HIGHMEM
if (flags  __GFP_HIGHMEM)
-   return base + ZONE_HIGHMEM;
+   return ZONE_HIGHMEM;
 #endif
-   return base + ZONE_NORMAL;
+   return ZONE_NORMAL;
 }
 
 static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 

[PATCH 3/6] Use two zonelist that are filtered by GFP mask

2007-09-13 Thread Mel Gorman

Currently a node has a number of zonelists, one for each zone type in the
system and a second set for THISNODE allocations. Based on the zones allowed
by a gfp mask, one of these zonelists is selected. All of these zonelists
occupy memory and consume cache lines.

This patch replaces the multiple zonelists per-node with two zonelists. The
first contains all populated zones in the system and the second contains all
populated zones in node suitable for GFP_THISNODE allocations. An iterator
macro is introduced called for_each_zone_zonelist() interates through each
zone in the zonelist that is allowed by the GFP flags.

Signed-off-by: Mel Gorman <[EMAIL PROTECTED]>
Acked-by: Christoph Lameter <[EMAIL PROTECTED]>
---

 arch/parisc/mm/init.c  |   11 +-
 fs/buffer.c|6 +
 include/linux/gfp.h|   17 +---
 include/linux/mmzone.h |   65 +++-
 mm/hugetlb.c   |8 +-
 mm/oom_kill.c  |8 +-
 mm/page_alloc.c|  169 +++-
 mm/slab.c  |8 +-
 mm/slub.c  |8 +-
 mm/vmscan.c|   22 ++---
 10 files changed, 160 insertions(+), 162 deletions(-)

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c
2007-08-28 02:32:35.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
2007-09-13 11:57:36.0 +0100
@@ -599,15 +599,18 @@ void show_mem(void)
 #ifdef CONFIG_DISCONTIGMEM
{
struct zonelist *zl;
-   int i, j, k;
+   int i, j;
 
for (i = 0; i < npmem_ranges; i++) {
+   zl = node_zonelist(i);
for (j = 0; j < MAX_NR_ZONES; j++) {
-   zl = NODE_DATA(i)->node_zonelists + j;
+   struct zone **z;
+   struct zone *zone;
 
printk("Zone list for zone %d on node %d: ", j, 
i);
-   for (k = 0; zl->zones[k] != NULL; k++) 
-   printk("[%ld/%s] ", 
zone_to_nid(zl->zones[k]), zl->zones[k]->name);
+   for_each_zone_zonelist(zone, z, zl, j)
+   printk("[%d/%s] ", zone_to_nid(zone),
+   zone->name);
printk("\n");
}
}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c  2007-09-13 
11:57:27.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c  2007-09-13 
11:57:36.0 +0100
@@ -375,9 +375,11 @@ static void free_more_memory(void)
yield();
 
for_each_online_node(nid) {
-   zones = node_zonelist(nid, GFP_NOFS);
+   zones = first_zones_zonelist(node_zonelist(nid, GFP_NOFS),
+   gfp_zone(GFP_NOFS));
if (*zones)
-   try_to_free_pages(zones, 0, GFP_NOFS);
+   try_to_free_pages(node_zonelist(nid, GFP_NOFS), 0,
+   GFP_NOFS);
}
 }
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h
--- linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h  2007-09-13 
11:57:27.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h  
2007-09-13 11:57:36.0 +0100
@@ -119,29 +119,22 @@ static inline int allocflags_to_migratet
 
 static inline enum zone_type gfp_zone(gfp_t flags)
 {
-   int base = 0;
-
-#ifdef CONFIG_NUMA
-   if (flags & __GFP_THISNODE)
-   base = MAX_NR_ZONES;
-#endif
-
 #ifdef CONFIG_ZONE_DMA
if (flags & __GFP_DMA)
-   return base + ZONE_DMA;
+   return ZONE_DMA;
 #endif
 #ifdef CONFIG_ZONE_DMA32
if (flags & __GFP_DMA32)
-   return base + ZONE_DMA32;
+   return ZONE_DMA32;
 #endif
if ((flags & (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
-   return base + ZONE_MOVABLE;
+   return ZONE_MOVABLE;
 #ifdef CONFIG_HIGHMEM
if (flags & __GFP_HIGHMEM)
-   return base + ZONE_HIGHMEM;
+   return ZONE_HIGHMEM;
 #endif
-   return base + ZONE_NORMAL;
+   return ZONE_NORMAL;
 }
 
 static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
diff -rup -X 

[PATCH 3/6] Use two zonelist that are filtered by GFP mask

2007-09-13 Thread Mel Gorman

Currently a node has a number of zonelists, one for each zone type in the
system and a second set for THISNODE allocations. Based on the zones allowed
by a gfp mask, one of these zonelists is selected. All of these zonelists
occupy memory and consume cache lines.

This patch replaces the multiple zonelists per-node with two zonelists. The
first contains all populated zones in the system and the second contains all
populated zones in node suitable for GFP_THISNODE allocations. An iterator
macro is introduced called for_each_zone_zonelist() interates through each
zone in the zonelist that is allowed by the GFP flags.

Signed-off-by: Mel Gorman [EMAIL PROTECTED]
Acked-by: Christoph Lameter [EMAIL PROTECTED]
---

 arch/parisc/mm/init.c  |   11 +-
 fs/buffer.c|6 +
 include/linux/gfp.h|   17 +---
 include/linux/mmzone.h |   65 +++-
 mm/hugetlb.c   |8 +-
 mm/oom_kill.c  |8 +-
 mm/page_alloc.c|  169 +++-
 mm/slab.c  |8 +-
 mm/slub.c  |8 +-
 mm/vmscan.c|   22 ++---
 10 files changed, 160 insertions(+), 162 deletions(-)

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c
2007-08-28 02:32:35.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
2007-09-13 11:57:36.0 +0100
@@ -599,15 +599,18 @@ void show_mem(void)
 #ifdef CONFIG_DISCONTIGMEM
{
struct zonelist *zl;
-   int i, j, k;
+   int i, j;
 
for (i = 0; i  npmem_ranges; i++) {
+   zl = node_zonelist(i);
for (j = 0; j  MAX_NR_ZONES; j++) {
-   zl = NODE_DATA(i)-node_zonelists + j;
+   struct zone **z;
+   struct zone *zone;
 
printk(Zone list for zone %d on node %d: , j, 
i);
-   for (k = 0; zl-zones[k] != NULL; k++) 
-   printk([%ld/%s] , 
zone_to_nid(zl-zones[k]), zl-zones[k]-name);
+   for_each_zone_zonelist(zone, z, zl, j)
+   printk([%d/%s] , zone_to_nid(zone),
+   zone-name);
printk(\n);
}
}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c  2007-09-13 
11:57:27.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c  2007-09-13 
11:57:36.0 +0100
@@ -375,9 +375,11 @@ static void free_more_memory(void)
yield();
 
for_each_online_node(nid) {
-   zones = node_zonelist(nid, GFP_NOFS);
+   zones = first_zones_zonelist(node_zonelist(nid, GFP_NOFS),
+   gfp_zone(GFP_NOFS));
if (*zones)
-   try_to_free_pages(zones, 0, GFP_NOFS);
+   try_to_free_pages(node_zonelist(nid, GFP_NOFS), 0,
+   GFP_NOFS);
}
 }
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h
--- linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h  2007-09-13 
11:57:27.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h  
2007-09-13 11:57:36.0 +0100
@@ -119,29 +119,22 @@ static inline int allocflags_to_migratet
 
 static inline enum zone_type gfp_zone(gfp_t flags)
 {
-   int base = 0;
-
-#ifdef CONFIG_NUMA
-   if (flags  __GFP_THISNODE)
-   base = MAX_NR_ZONES;
-#endif
-
 #ifdef CONFIG_ZONE_DMA
if (flags  __GFP_DMA)
-   return base + ZONE_DMA;
+   return ZONE_DMA;
 #endif
 #ifdef CONFIG_ZONE_DMA32
if (flags  __GFP_DMA32)
-   return base + ZONE_DMA32;
+   return ZONE_DMA32;
 #endif
if ((flags  (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
-   return base + ZONE_MOVABLE;
+   return ZONE_MOVABLE;
 #ifdef CONFIG_HIGHMEM
if (flags  __GFP_HIGHMEM)
-   return base + ZONE_HIGHMEM;
+   return ZONE_HIGHMEM;
 #endif
-   return base + ZONE_NORMAL;
+   return ZONE_NORMAL;
 }
 
 static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 

[PATCH 3/6] Use two zonelist that are filtered by GFP mask

2007-09-12 Thread Mel Gorman

Currently a node has a number of zonelists, one for each zone type in the
system and a second set for THISNODE allocations. Based on the zones allowed
by a gfp mask, one of these zonelists is selected. All of these zonelists
occupy memory and consume cache lines.

This patch replaces the multiple zonelists per-node with two zonelists. The
first contains all populated zones in the system and the second contains all
populated zones in node suitable for GFP_THISNODE allocations. An iterator
macro is introduced called for_each_zone_zonelist() interates through each
zone in the zonelist that is allowed by the GFP flags.

Signed-off-by: Mel Gorman <[EMAIL PROTECTED]>
Acked-by: Christoph Lameter <[EMAIL PROTECTED]>
---

 arch/parisc/mm/init.c  |   11 +-
 fs/buffer.c|6 +
 include/linux/gfp.h|   29 ---
 include/linux/mmzone.h |   65 +++-
 mm/hugetlb.c   |8 +-
 mm/oom_kill.c  |8 +-
 mm/page_alloc.c|  169 +++-
 mm/slab.c  |8 +-
 mm/slub.c  |8 +-
 mm/vmscan.c|   20 ++---
 10 files changed, 171 insertions(+), 161 deletions(-)

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c
2007-08-28 02:32:35.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
2007-09-12 16:05:27.0 +0100
@@ -599,15 +599,18 @@ void show_mem(void)
 #ifdef CONFIG_DISCONTIGMEM
{
struct zonelist *zl;
-   int i, j, k;
+   int i, j;
 
for (i = 0; i < npmem_ranges; i++) {
+   zl = node_zonelist(i);
for (j = 0; j < MAX_NR_ZONES; j++) {
-   zl = NODE_DATA(i)->node_zonelists + j;
+   struct zone **z;
+   struct zone *zone;
 
printk("Zone list for zone %d on node %d: ", j, 
i);
-   for (k = 0; zl->zones[k] != NULL; k++) 
-   printk("[%ld/%s] ", 
zone_to_nid(zl->zones[k]), zl->zones[k]->name);
+   for_each_zone_zonelist(zone, z, zl, j)
+   printk("[%d/%s] ", zone_to_nid(zone),
+   zone->name);
printk("\n");
}
}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c  2007-09-12 
16:05:18.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c  2007-09-12 
16:05:27.0 +0100
@@ -375,9 +375,11 @@ static void free_more_memory(void)
yield();
 
for_each_online_node(nid) {
-   zones = node_zonelist(nid, GFP_NOFS);
+   zones = first_zones_zonelist(node_zonelist(nid, GFP_NOFS),
+   gfp_zone(GFP_NOFS));
if (*zones)
-   try_to_free_pages(zones, 0, GFP_NOFS);
+   try_to_free_pages(node_zonelist(nid, GFP_NOFS), 0,
+   GFP_NOFS);
}
 }
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h
--- linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h  2007-09-12 
16:05:18.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h  
2007-09-12 16:05:27.0 +0100
@@ -119,29 +119,22 @@ static inline int allocflags_to_migratet
 
 static inline enum zone_type gfp_zone(gfp_t flags)
 {
-   int base = 0;
-
-#ifdef CONFIG_NUMA
-   if (flags & __GFP_THISNODE)
-   base = MAX_NR_ZONES;
-#endif
-
 #ifdef CONFIG_ZONE_DMA
if (flags & __GFP_DMA)
-   return base + ZONE_DMA;
+   return ZONE_DMA;
 #endif
 #ifdef CONFIG_ZONE_DMA32
if (flags & __GFP_DMA32)
-   return base + ZONE_DMA32;
+   return ZONE_DMA32;
 #endif
if ((flags & (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
-   return base + ZONE_MOVABLE;
+   return ZONE_MOVABLE;
 #ifdef CONFIG_HIGHMEM
if (flags & __GFP_HIGHMEM)
-   return base + ZONE_HIGHMEM;
+   return ZONE_HIGHMEM;
 #endif
-   return base + ZONE_NORMAL;
+   return ZONE_NORMAL;
 }
 
 static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
@@ -157,6 +150,18 @@ static inline gfp_t 

[PATCH 3/6] Use two zonelist that are filtered by GFP mask

2007-09-12 Thread Mel Gorman

Currently a node has a number of zonelists, one for each zone type in the
system and a second set for THISNODE allocations. Based on the zones allowed
by a gfp mask, one of these zonelists is selected. All of these zonelists
occupy memory and consume cache lines.

This patch replaces the multiple zonelists per-node with two zonelists. The
first contains all populated zones in the system and the second contains all
populated zones in node suitable for GFP_THISNODE allocations. An iterator
macro is introduced called for_each_zone_zonelist() interates through each
zone in the zonelist that is allowed by the GFP flags.

Signed-off-by: Mel Gorman [EMAIL PROTECTED]
Acked-by: Christoph Lameter [EMAIL PROTECTED]
---

 arch/parisc/mm/init.c  |   11 +-
 fs/buffer.c|6 +
 include/linux/gfp.h|   29 ---
 include/linux/mmzone.h |   65 +++-
 mm/hugetlb.c   |8 +-
 mm/oom_kill.c  |8 +-
 mm/page_alloc.c|  169 +++-
 mm/slab.c  |8 +-
 mm/slub.c  |8 +-
 mm/vmscan.c|   20 ++---
 10 files changed, 171 insertions(+), 161 deletions(-)

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c
2007-08-28 02:32:35.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
2007-09-12 16:05:27.0 +0100
@@ -599,15 +599,18 @@ void show_mem(void)
 #ifdef CONFIG_DISCONTIGMEM
{
struct zonelist *zl;
-   int i, j, k;
+   int i, j;
 
for (i = 0; i  npmem_ranges; i++) {
+   zl = node_zonelist(i);
for (j = 0; j  MAX_NR_ZONES; j++) {
-   zl = NODE_DATA(i)-node_zonelists + j;
+   struct zone **z;
+   struct zone *zone;
 
printk(Zone list for zone %d on node %d: , j, 
i);
-   for (k = 0; zl-zones[k] != NULL; k++) 
-   printk([%ld/%s] , 
zone_to_nid(zl-zones[k]), zl-zones[k]-name);
+   for_each_zone_zonelist(zone, z, zl, j)
+   printk([%d/%s] , zone_to_nid(zone),
+   zone-name);
printk(\n);
}
}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c  2007-09-12 
16:05:18.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c  2007-09-12 
16:05:27.0 +0100
@@ -375,9 +375,11 @@ static void free_more_memory(void)
yield();
 
for_each_online_node(nid) {
-   zones = node_zonelist(nid, GFP_NOFS);
+   zones = first_zones_zonelist(node_zonelist(nid, GFP_NOFS),
+   gfp_zone(GFP_NOFS));
if (*zones)
-   try_to_free_pages(zones, 0, GFP_NOFS);
+   try_to_free_pages(node_zonelist(nid, GFP_NOFS), 0,
+   GFP_NOFS);
}
 }
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h
--- linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h  2007-09-12 
16:05:18.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h  
2007-09-12 16:05:27.0 +0100
@@ -119,29 +119,22 @@ static inline int allocflags_to_migratet
 
 static inline enum zone_type gfp_zone(gfp_t flags)
 {
-   int base = 0;
-
-#ifdef CONFIG_NUMA
-   if (flags  __GFP_THISNODE)
-   base = MAX_NR_ZONES;
-#endif
-
 #ifdef CONFIG_ZONE_DMA
if (flags  __GFP_DMA)
-   return base + ZONE_DMA;
+   return ZONE_DMA;
 #endif
 #ifdef CONFIG_ZONE_DMA32
if (flags  __GFP_DMA32)
-   return base + ZONE_DMA32;
+   return ZONE_DMA32;
 #endif
if ((flags  (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
-   return base + ZONE_MOVABLE;
+   return ZONE_MOVABLE;
 #ifdef CONFIG_HIGHMEM
if (flags  __GFP_HIGHMEM)
-   return base + ZONE_HIGHMEM;
+   return ZONE_HIGHMEM;
 #endif
-   return base + ZONE_NORMAL;
+   return ZONE_NORMAL;
 }
 
 static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
@@ -157,6 +150,18 @@ static inline gfp_t set_migrateflags(gfp
  * 

[PATCH 3/6] Use two zonelist that are filtered by GFP mask

2007-09-11 Thread Mel Gorman

Currently a node has a number of zonelists, one for each zone type in the
system and a second set for THISNODE allocations. Based on the zones allowed
by a gfp mask, one of these zonelists is selected. All of these zonelists
occupy memory and consume cache lines.

This patch replaces the multiple zonelists per-node with two zonelists. The
first contains all populated zones in the system and the second contains all
populated zones in node suitable for GFP_THISNODE allocations. An iterator
macro is introduced called for_each_zone_zonelist() interates through each
zone in the zonelist that is allowed by the GFP flags.

Signed-off-by: Mel Gorman <[EMAIL PROTECTED]>
Acked-by: Christoph Lameter <[EMAIL PROTECTED]>
---

 arch/parisc/mm/init.c  |   11 +-
 fs/buffer.c|6 +
 include/linux/gfp.h|   29 ---
 include/linux/mmzone.h |   65 +++-
 mm/hugetlb.c   |8 +-
 mm/oom_kill.c  |8 +-
 mm/page_alloc.c|  169 +++-
 mm/slab.c  |8 +-
 mm/slub.c  |8 +-
 mm/vmscan.c|   20 ++---
 10 files changed, 171 insertions(+), 161 deletions(-)

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c
2007-08-28 02:32:35.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
2007-09-10 16:06:22.0 +0100
@@ -599,15 +599,18 @@ void show_mem(void)
 #ifdef CONFIG_DISCONTIGMEM
{
struct zonelist *zl;
-   int i, j, k;
+   int i, j;
 
for (i = 0; i < npmem_ranges; i++) {
+   zl = node_zonelist(i);
for (j = 0; j < MAX_NR_ZONES; j++) {
-   zl = NODE_DATA(i)->node_zonelists + j;
+   struct zone **z;
+   struct zone *zone;
 
printk("Zone list for zone %d on node %d: ", j, 
i);
-   for (k = 0; zl->zones[k] != NULL; k++) 
-   printk("[%ld/%s] ", 
zone_to_nid(zl->zones[k]), zl->zones[k]->name);
+   for_each_zone_zonelist(zone, z, zl, j)
+   printk("[%d/%s] ", zone_to_nid(zone),
+   zone->name);
printk("\n");
}
}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c  2007-09-10 
16:06:13.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c  2007-09-10 
16:06:22.0 +0100
@@ -375,9 +375,11 @@ static void free_more_memory(void)
yield();
 
for_each_online_node(nid) {
-   zones = node_zonelist(nid, GFP_NOFS);
+   zones = first_zones_zonelist(node_zonelist(nid, GFP_NOFS),
+   gfp_zone(GFP_NOFS));
if (*zones)
-   try_to_free_pages(zones, 0, GFP_NOFS);
+   try_to_free_pages(node_zonelist(nid, GFP_NOFS), 0,
+   GFP_NOFS);
}
 }
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h
--- linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h  2007-09-10 
16:06:13.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h  
2007-09-10 16:06:22.0 +0100
@@ -119,29 +119,22 @@ static inline int allocflags_to_migratet
 
 static inline enum zone_type gfp_zone(gfp_t flags)
 {
-   int base = 0;
-
-#ifdef CONFIG_NUMA
-   if (flags & __GFP_THISNODE)
-   base = MAX_NR_ZONES;
-#endif
-
 #ifdef CONFIG_ZONE_DMA
if (flags & __GFP_DMA)
-   return base + ZONE_DMA;
+   return ZONE_DMA;
 #endif
 #ifdef CONFIG_ZONE_DMA32
if (flags & __GFP_DMA32)
-   return base + ZONE_DMA32;
+   return ZONE_DMA32;
 #endif
if ((flags & (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
-   return base + ZONE_MOVABLE;
+   return ZONE_MOVABLE;
 #ifdef CONFIG_HIGHMEM
if (flags & __GFP_HIGHMEM)
-   return base + ZONE_HIGHMEM;
+   return ZONE_HIGHMEM;
 #endif
-   return base + ZONE_NORMAL;
+   return ZONE_NORMAL;
 }
 
 static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
@@ -157,6 +150,18 @@ static inline gfp_t 

[PATCH 3/6] Use two zonelist that are filtered by GFP mask

2007-09-11 Thread Mel Gorman

Currently a node has a number of zonelists, one for each zone type in the
system and a second set for THISNODE allocations. Based on the zones allowed
by a gfp mask, one of these zonelists is selected. All of these zonelists
occupy memory and consume cache lines.

This patch replaces the multiple zonelists per-node with two zonelists. The
first contains all populated zones in the system and the second contains all
populated zones in node suitable for GFP_THISNODE allocations. An iterator
macro is introduced called for_each_zone_zonelist() interates through each
zone in the zonelist that is allowed by the GFP flags.

Signed-off-by: Mel Gorman <[EMAIL PROTECTED]>
Acked-by: Christoph Lameter <[EMAIL PROTECTED]>
---

 arch/parisc/mm/init.c  |   11 +-
 fs/buffer.c|6 +
 include/linux/gfp.h|   29 ---
 include/linux/mmzone.h |   65 +++-
 mm/hugetlb.c   |8 +-
 mm/oom_kill.c  |8 +-
 mm/page_alloc.c|  169 +++-
 mm/slab.c  |8 +-
 mm/slub.c  |8 +-
 mm/vmscan.c|   20 ++---
 10 files changed, 171 insertions(+), 161 deletions(-)

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c
2007-08-28 02:32:35.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
2007-09-10 16:06:22.0 +0100
@@ -599,15 +599,18 @@ void show_mem(void)
 #ifdef CONFIG_DISCONTIGMEM
{
struct zonelist *zl;
-   int i, j, k;
+   int i, j;
 
for (i = 0; i < npmem_ranges; i++) {
+   zl = node_zonelist(i);
for (j = 0; j < MAX_NR_ZONES; j++) {
-   zl = NODE_DATA(i)->node_zonelists + j;
+   struct zone **z;
+   struct zone *zone;
 
printk("Zone list for zone %d on node %d: ", j, 
i);
-   for (k = 0; zl->zones[k] != NULL; k++) 
-   printk("[%ld/%s] ", 
zone_to_nid(zl->zones[k]), zl->zones[k]->name);
+   for_each_zone_zonelist(zone, z, zl, j)
+   printk("[%d/%s] ", zone_to_nid(zone),
+   zone->name);
printk("\n");
}
}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c  2007-09-10 
16:06:13.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c  2007-09-10 
16:06:22.0 +0100
@@ -375,9 +375,11 @@ static void free_more_memory(void)
yield();
 
for_each_online_node(nid) {
-   zones = node_zonelist(nid, GFP_NOFS);
+   zones = first_zones_zonelist(node_zonelist(nid, GFP_NOFS),
+   gfp_zone(GFP_NOFS));
if (*zones)
-   try_to_free_pages(zones, 0, GFP_NOFS);
+   try_to_free_pages(node_zonelist(nid, GFP_NOFS), 0,
+   GFP_NOFS);
}
 }
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h
--- linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h  2007-09-10 
16:06:13.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h  
2007-09-10 16:06:22.0 +0100
@@ -119,29 +119,22 @@ static inline int allocflags_to_migratet
 
 static inline enum zone_type gfp_zone(gfp_t flags)
 {
-   int base = 0;
-
-#ifdef CONFIG_NUMA
-   if (flags & __GFP_THISNODE)
-   base = MAX_NR_ZONES;
-#endif
-
 #ifdef CONFIG_ZONE_DMA
if (flags & __GFP_DMA)
-   return base + ZONE_DMA;
+   return ZONE_DMA;
 #endif
 #ifdef CONFIG_ZONE_DMA32
if (flags & __GFP_DMA32)
-   return base + ZONE_DMA32;
+   return ZONE_DMA32;
 #endif
if ((flags & (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
-   return base + ZONE_MOVABLE;
+   return ZONE_MOVABLE;
 #ifdef CONFIG_HIGHMEM
if (flags & __GFP_HIGHMEM)
-   return base + ZONE_HIGHMEM;
+   return ZONE_HIGHMEM;
 #endif
-   return base + ZONE_NORMAL;
+   return ZONE_NORMAL;
 }
 
 static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
@@ -157,6 +150,18 @@ static inline gfp_t 

[PATCH 3/6] Use two zonelist that are filtered by GFP mask

2007-09-11 Thread Mel Gorman

Currently a node has a number of zonelists, one for each zone type in the
system and a second set for THISNODE allocations. Based on the zones allowed
by a gfp mask, one of these zonelists is selected. All of these zonelists
occupy memory and consume cache lines.

This patch replaces the multiple zonelists per-node with two zonelists. The
first contains all populated zones in the system and the second contains all
populated zones in node suitable for GFP_THISNODE allocations. An iterator
macro is introduced called for_each_zone_zonelist() interates through each
zone in the zonelist that is allowed by the GFP flags.

Signed-off-by: Mel Gorman [EMAIL PROTECTED]
Acked-by: Christoph Lameter [EMAIL PROTECTED]
---

 arch/parisc/mm/init.c  |   11 +-
 fs/buffer.c|6 +
 include/linux/gfp.h|   29 ---
 include/linux/mmzone.h |   65 +++-
 mm/hugetlb.c   |8 +-
 mm/oom_kill.c  |8 +-
 mm/page_alloc.c|  169 +++-
 mm/slab.c  |8 +-
 mm/slub.c  |8 +-
 mm/vmscan.c|   20 ++---
 10 files changed, 171 insertions(+), 161 deletions(-)

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c
2007-08-28 02:32:35.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
2007-09-10 16:06:22.0 +0100
@@ -599,15 +599,18 @@ void show_mem(void)
 #ifdef CONFIG_DISCONTIGMEM
{
struct zonelist *zl;
-   int i, j, k;
+   int i, j;
 
for (i = 0; i  npmem_ranges; i++) {
+   zl = node_zonelist(i);
for (j = 0; j  MAX_NR_ZONES; j++) {
-   zl = NODE_DATA(i)-node_zonelists + j;
+   struct zone **z;
+   struct zone *zone;
 
printk(Zone list for zone %d on node %d: , j, 
i);
-   for (k = 0; zl-zones[k] != NULL; k++) 
-   printk([%ld/%s] , 
zone_to_nid(zl-zones[k]), zl-zones[k]-name);
+   for_each_zone_zonelist(zone, z, zl, j)
+   printk([%d/%s] , zone_to_nid(zone),
+   zone-name);
printk(\n);
}
}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c  2007-09-10 
16:06:13.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c  2007-09-10 
16:06:22.0 +0100
@@ -375,9 +375,11 @@ static void free_more_memory(void)
yield();
 
for_each_online_node(nid) {
-   zones = node_zonelist(nid, GFP_NOFS);
+   zones = first_zones_zonelist(node_zonelist(nid, GFP_NOFS),
+   gfp_zone(GFP_NOFS));
if (*zones)
-   try_to_free_pages(zones, 0, GFP_NOFS);
+   try_to_free_pages(node_zonelist(nid, GFP_NOFS), 0,
+   GFP_NOFS);
}
 }
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h
--- linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h  2007-09-10 
16:06:13.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h  
2007-09-10 16:06:22.0 +0100
@@ -119,29 +119,22 @@ static inline int allocflags_to_migratet
 
 static inline enum zone_type gfp_zone(gfp_t flags)
 {
-   int base = 0;
-
-#ifdef CONFIG_NUMA
-   if (flags  __GFP_THISNODE)
-   base = MAX_NR_ZONES;
-#endif
-
 #ifdef CONFIG_ZONE_DMA
if (flags  __GFP_DMA)
-   return base + ZONE_DMA;
+   return ZONE_DMA;
 #endif
 #ifdef CONFIG_ZONE_DMA32
if (flags  __GFP_DMA32)
-   return base + ZONE_DMA32;
+   return ZONE_DMA32;
 #endif
if ((flags  (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
-   return base + ZONE_MOVABLE;
+   return ZONE_MOVABLE;
 #ifdef CONFIG_HIGHMEM
if (flags  __GFP_HIGHMEM)
-   return base + ZONE_HIGHMEM;
+   return ZONE_HIGHMEM;
 #endif
-   return base + ZONE_NORMAL;
+   return ZONE_NORMAL;
 }
 
 static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
@@ -157,6 +150,18 @@ static inline gfp_t set_migrateflags(gfp
  * 

[PATCH 3/6] Use two zonelist that are filtered by GFP mask

2007-09-11 Thread Mel Gorman

Currently a node has a number of zonelists, one for each zone type in the
system and a second set for THISNODE allocations. Based on the zones allowed
by a gfp mask, one of these zonelists is selected. All of these zonelists
occupy memory and consume cache lines.

This patch replaces the multiple zonelists per-node with two zonelists. The
first contains all populated zones in the system and the second contains all
populated zones in node suitable for GFP_THISNODE allocations. An iterator
macro is introduced called for_each_zone_zonelist() interates through each
zone in the zonelist that is allowed by the GFP flags.

Signed-off-by: Mel Gorman [EMAIL PROTECTED]
Acked-by: Christoph Lameter [EMAIL PROTECTED]
---

 arch/parisc/mm/init.c  |   11 +-
 fs/buffer.c|6 +
 include/linux/gfp.h|   29 ---
 include/linux/mmzone.h |   65 +++-
 mm/hugetlb.c   |8 +-
 mm/oom_kill.c  |8 +-
 mm/page_alloc.c|  169 +++-
 mm/slab.c  |8 +-
 mm/slub.c  |8 +-
 mm/vmscan.c|   20 ++---
 10 files changed, 171 insertions(+), 161 deletions(-)

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/arch/parisc/mm/init.c
2007-08-28 02:32:35.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/arch/parisc/mm/init.c
2007-09-10 16:06:22.0 +0100
@@ -599,15 +599,18 @@ void show_mem(void)
 #ifdef CONFIG_DISCONTIGMEM
{
struct zonelist *zl;
-   int i, j, k;
+   int i, j;
 
for (i = 0; i  npmem_ranges; i++) {
+   zl = node_zonelist(i);
for (j = 0; j  MAX_NR_ZONES; j++) {
-   zl = NODE_DATA(i)-node_zonelists + j;
+   struct zone **z;
+   struct zone *zone;
 
printk(Zone list for zone %d on node %d: , j, 
i);
-   for (k = 0; zl-zones[k] != NULL; k++) 
-   printk([%ld/%s] , 
zone_to_nid(zl-zones[k]), zl-zones[k]-name);
+   for_each_zone_zonelist(zone, z, zl, j)
+   printk([%d/%s] , zone_to_nid(zone),
+   zone-name);
printk(\n);
}
}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c
--- linux-2.6.23-rc4-mm1-007_node_zonelist/fs/buffer.c  2007-09-10 
16:06:13.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/fs/buffer.c  2007-09-10 
16:06:22.0 +0100
@@ -375,9 +375,11 @@ static void free_more_memory(void)
yield();
 
for_each_online_node(nid) {
-   zones = node_zonelist(nid, GFP_NOFS);
+   zones = first_zones_zonelist(node_zonelist(nid, GFP_NOFS),
+   gfp_zone(GFP_NOFS));
if (*zones)
-   try_to_free_pages(zones, 0, GFP_NOFS);
+   try_to_free_pages(node_zonelist(nid, GFP_NOFS), 0,
+   GFP_NOFS);
}
 }
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff 
linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h 
linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h
--- linux-2.6.23-rc4-mm1-007_node_zonelist/include/linux/gfp.h  2007-09-10 
16:06:13.0 +0100
+++ linux-2.6.23-rc4-mm1-010_use_two_zonelists/include/linux/gfp.h  
2007-09-10 16:06:22.0 +0100
@@ -119,29 +119,22 @@ static inline int allocflags_to_migratet
 
 static inline enum zone_type gfp_zone(gfp_t flags)
 {
-   int base = 0;
-
-#ifdef CONFIG_NUMA
-   if (flags  __GFP_THISNODE)
-   base = MAX_NR_ZONES;
-#endif
-
 #ifdef CONFIG_ZONE_DMA
if (flags  __GFP_DMA)
-   return base + ZONE_DMA;
+   return ZONE_DMA;
 #endif
 #ifdef CONFIG_ZONE_DMA32
if (flags  __GFP_DMA32)
-   return base + ZONE_DMA32;
+   return ZONE_DMA32;
 #endif
if ((flags  (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
(__GFP_HIGHMEM | __GFP_MOVABLE))
-   return base + ZONE_MOVABLE;
+   return ZONE_MOVABLE;
 #ifdef CONFIG_HIGHMEM
if (flags  __GFP_HIGHMEM)
-   return base + ZONE_HIGHMEM;
+   return ZONE_HIGHMEM;
 #endif
-   return base + ZONE_NORMAL;
+   return ZONE_NORMAL;
 }
 
 static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
@@ -157,6 +150,18 @@ static inline gfp_t set_migrateflags(gfp
  *