<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
From: Matthew Dobson &lt;colpatch@us.ibm.com&gt;

This patch does the following:
1) Rename ZONE_SHIFT to NODEZONE_SHIFT.  This value is the number
    of bits to shift page-&gt;flags to get the node/zone part of the
    bitfield.
2) Add a macro called NODEZONE which takes a node number and zone number
    and returns a 'nodezone', a bitshifted composition of the two.
3) Create page_zonenum &amp; page_nodenum, inline functions to return the
    node/zone a page belongs to with some simple bit twiddling, no
    pointer dereferences necessary.
4) Modify page_zone() and set_page_zone() to use the new NODEZONE_SHIFT.
5) Modify memmap_init_zone() &amp; free_area_init_core() to use the new
    NODEZONE macros.
6) Fix up some comments to reflect the above changes.



 25-akpm/include/linux/mm.h     |   24 +++++++++++++++++-------
 25-akpm/include/linux/mmzone.h |   15 +++++++++++----
 25-akpm/mm/page_alloc.c        |    6 +++---
 3 files changed, 31 insertions(+), 14 deletions(-)

diff -puN include/linux/mm.h~simplify-node-zone-fields-3 include/linux/mm.h
--- 25/include/linux/mm.h~simplify-node-zone-fields-3	Tue Jan  6 14:44:12 2004
+++ 25-akpm/include/linux/mm.h	Tue Jan  6 14:44:12 2004
@@ -330,23 +330,33 @@ static inline void put_page(struct page 
 /*
  * The zone field is never updated after free_area_init_core()
  * sets it, so none of the operations on it need to be atomic.
- * We'll have up to log2(MAX_NUMNODES * MAX_NR_ZONES) zones
- * total, so we use NODES_SHIFT here to get enough bits.
+ * We'll have up to (MAX_NUMNODES * MAX_NR_ZONES) zones total,
+ * so we use (MAX_NODES_SHIFT + MAX_ZONES_SHIFT) here to get enough bits.
  */
-#define ZONE_SHIFT (BITS_PER_LONG - NODES_SHIFT - MAX_NR_ZONES_SHIFT)
+#define NODEZONE_SHIFT (BITS_PER_LONG - MAX_NODES_SHIFT - MAX_ZONES_SHIFT)
+#define NODEZONE(node, zone)	((node &lt;&lt; ZONES_SHIFT) | zone)
+
+static inline unsigned long page_zonenum(struct page *page)
+{
+	return (page-&gt;flags &gt;&gt; NODEZONE_SHIFT) &amp; (~(~0UL &lt;&lt; ZONES_SHIFT));
+}
+static inline unsigned long page_nodenum(struct page *page)
+{
+	return (page-&gt;flags &gt;&gt; (NODEZONE_SHIFT + ZONES_SHIFT));
+}
 
 struct zone;
 extern struct zone *zone_table[];
 
 static inline struct zone *page_zone(struct page *page)
 {
-	return zone_table[page-&gt;flags &gt;&gt; ZONE_SHIFT];
+	return zone_table[page-&gt;flags &gt;&gt; NODEZONE_SHIFT];
 }
 
-static inline void set_page_zone(struct page *page, unsigned long zone_num)
+static inline void set_page_zone(struct page *page, unsigned long nodezone_num)
 {
-	page-&gt;flags &amp;= ~(~0UL &lt;&lt; ZONE_SHIFT);
-	page-&gt;flags |= zone_num &lt;&lt; ZONE_SHIFT;
+	page-&gt;flags &amp;= ~(~0UL &lt;&lt; NODEZONE_SHIFT);
+	page-&gt;flags |= nodezone_num &lt;&lt; NODEZONE_SHIFT;
 }
 
 #ifndef CONFIG_DISCONTIGMEM
diff -puN include/linux/mmzone.h~simplify-node-zone-fields-3 include/linux/mmzone.h
--- 25/include/linux/mmzone.h~simplify-node-zone-fields-3	Tue Jan  6 14:44:12 2004
+++ 25-akpm/include/linux/mmzone.h	Tue Jan  6 14:44:12 2004
@@ -160,8 +160,8 @@ struct zone {
 #define ZONE_NORMAL		1
 #define ZONE_HIGHMEM		2
 
-#define MAX_NR_ZONES		3	/* Sync this with MAX_NR_ZONES_SHIFT */
-#define MAX_NR_ZONES_SHIFT	2	/* ceil(log2(MAX_NR_ZONES)) */
+#define MAX_NR_ZONES		3	/* Sync this with ZONES_SHIFT */
+#define ZONES_SHIFT		2	/* ceil(log2(MAX_NR_ZONES)) */
 
 #define GFP_ZONEMASK	0x03
 
@@ -303,7 +303,7 @@ int min_free_kbytes_sysctl_handler(struc
 extern struct pglist_data contig_page_data;
 #define NODE_DATA(nid)		(&amp;contig_page_data)
 #define NODE_MEM_MAP(nid)	mem_map
-#define MAX_NODES_SHIFT		0
+#define MAX_NODES_SHIFT		1
 
 #else /* CONFIG_DISCONTIGMEM */
 
@@ -311,7 +311,7 @@ extern struct pglist_data contig_page_da
 
 #if BITS_PER_LONG == 32
 /*
- * with 32 bit flags field, page-&gt;zone is currently 8 bits.
+ * with 32 bit page-&gt;flags field, we reserve 8 bits for node/zone info.
  * there are 3 zones (2 bits) and this leaves 8-2=6 bits for nodes.
  */
 #define MAX_NODES_SHIFT		6
@@ -328,6 +328,13 @@ extern struct pglist_data contig_page_da
 #error NODES_SHIFT &gt; MAX_NODES_SHIFT
 #endif
 
+/* There are currently 3 zones: DMA, Normal &amp; Highmem, thus we need 2 bits */
+#define MAX_ZONES_SHIFT		2
+
+#if ZONES_SHIFT &gt; MAX_ZONES_SHIFT
+#error ZONES_SHIFT &gt; MAX_ZONES_SHIFT
+#endif
+
 extern DECLARE_BITMAP(node_online_map, MAX_NUMNODES);
 extern DECLARE_BITMAP(memblk_online_map, MAX_NR_MEMBLKS);
 
diff -puN mm/page_alloc.c~simplify-node-zone-fields-3 mm/page_alloc.c
--- 25/mm/page_alloc.c~simplify-node-zone-fields-3	Tue Jan  6 14:44:12 2004
+++ 25-akpm/mm/page_alloc.c	Tue Jan  6 14:44:12 2004
@@ -50,7 +50,7 @@ EXPORT_SYMBOL(nr_swap_pages);
  * Used by page_zone() to look up the address of the struct zone whose
  * id is encoded in the upper bits of page-&gt;flags
  */
-struct zone *zone_table[MAX_NR_ZONES*MAX_NUMNODES];
+struct zone *zone_table[1 &lt;&lt; (ZONES_SHIFT + NODES_SHIFT)];
 EXPORT_SYMBOL(zone_table);
 
 static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
@@ -1212,7 +1212,7 @@ void __init memmap_init_zone(struct page
 	struct page *page;
 
 	for (page = start; page &lt; (start + size); page++) {
-		set_page_zone(page, nid * MAX_NR_ZONES + zone);
+		set_page_zone(page, NODEZONE(nid, zone));
 		set_page_count(page, 0);
 		SetPageReserved(page);
 		INIT_LIST_HEAD(&amp;page-&gt;list);
@@ -1253,7 +1253,7 @@ static void __init free_area_init_core(s
 		unsigned long size, realsize;
 		unsigned long batch;
 
-		zone_table[nid * MAX_NR_ZONES + j] = zone;
+		zone_table[NODEZONE(nid, j)] = zone;
 		realsize = size = zones_size[j];
 		if (zholes_size)
 			realsize -= zholes_size[j];

_
</pre></body></html>