Commit 042ac4ab authored by Matthew Dobson's avatar Matthew Dobson Committed by Linus Torvalds

[PATCH] Replace 'numnodes' with 'node_online_map' - arch-independent

From: William Lee Irwin III <wli@holomorphy.com>

Without passing this parameter by reference, the changes to used_node_mask
are meaningless and do not affect the caller's copy.

This leads to boot-time failure. This proposed fix passes it by reference.
Signed-off-by: default avatarWilliam Irwin <wli@holomorphy.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d61614fa
...@@ -29,7 +29,7 @@ Each node's page allocation data structures have also been encapsulated ...@@ -29,7 +29,7 @@ Each node's page allocation data structures have also been encapsulated
into a pg_data_t. The bootmem_data_t is just one part of this. To into a pg_data_t. The bootmem_data_t is just one part of this. To
make the code look uniform between NUMA and regular UMA platforms, make the code look uniform between NUMA and regular UMA platforms,
UMA platforms have a statically allocated pg_data_t too (contig_page_data). UMA platforms have a statically allocated pg_data_t too (contig_page_data).
For the sake of uniformity, the variable "numnodes" is also defined For the sake of uniformity, the function num_online_nodes() is also defined
for all platforms. As we run benchmarks, we might decide to NUMAize for all platforms. As we run benchmarks, we might decide to NUMAize
more variables like low_on_memory, nr_free_pages etc into the pg_data_t. more variables like low_on_memory, nr_free_pages etc into the pg_data_t.
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/topology.h> #include <linux/topology.h>
#include <linux/nodemask.h>
static struct sysdev_class node_class = { static struct sysdev_class node_class = {
set_kset_name("node"), set_kset_name("node"),
...@@ -120,7 +121,7 @@ static ssize_t node_read_distance(struct sys_device * dev, char * buf) ...@@ -120,7 +121,7 @@ static ssize_t node_read_distance(struct sys_device * dev, char * buf)
/* buf currently PAGE_SIZE, need ~4 chars per node */ /* buf currently PAGE_SIZE, need ~4 chars per node */
BUILD_BUG_ON(MAX_NUMNODES*4 > PAGE_SIZE/2); BUILD_BUG_ON(MAX_NUMNODES*4 > PAGE_SIZE/2);
for (i = 0; i < numnodes; i++) for_each_online_node(i)
len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i)); len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i));
len += sprintf(buf + len, "\n"); len += sprintf(buf + len, "\n");
......
...@@ -272,7 +272,6 @@ typedef struct pglist_data { ...@@ -272,7 +272,6 @@ typedef struct pglist_data {
#define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages) #define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages)
#define node_spanned_pages(nid) (NODE_DATA(nid)->node_spanned_pages) #define node_spanned_pages(nid) (NODE_DATA(nid)->node_spanned_pages)
extern int numnodes;
extern struct pglist_data *pgdat_list; extern struct pglist_data *pgdat_list;
void __get_zone_counts(unsigned long *active, unsigned long *inactive, void __get_zone_counts(unsigned long *active, unsigned long *inactive,
......
...@@ -43,16 +43,9 @@ ...@@ -43,16 +43,9 @@
}) })
#endif #endif
static inline int __next_node_with_cpus(int node) #define for_each_node_with_cpus(node) \
{ for_each_online_node(node) \
do if (nr_cpus_node(node))
++node;
while (node < numnodes && !nr_cpus_node(node));
return node;
}
#define for_each_node_with_cpus(node) \
for (node = 0; node < numnodes; node = __next_node_with_cpus(node))
#ifndef node_distance #ifndef node_distance
/* Conform to ACPI 2.0 SLIT distance definitions */ /* Conform to ACPI 2.0 SLIT distance definitions */
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/nodemask.h>
const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL; const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
static unsigned long nr_huge_pages, free_huge_pages; static unsigned long nr_huge_pages, free_huge_pages;
...@@ -54,10 +55,10 @@ static struct page *alloc_fresh_huge_page(void) ...@@ -54,10 +55,10 @@ static struct page *alloc_fresh_huge_page(void)
struct page *page; struct page *page;
page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN, page = alloc_pages_node(nid, GFP_HIGHUSER|__GFP_COMP|__GFP_NOWARN,
HUGETLB_PAGE_ORDER); HUGETLB_PAGE_ORDER);
nid = (nid + 1) % numnodes; nid = (nid + 1) % num_online_nodes();
if (page) { if (page) {
nr_huge_pages++; nr_huge_pages++;
nr_huge_pages_node[page_zone(page)->zone_pgdat->node_id]++; nr_huge_pages_node[page_to_nid(page)]++;
} }
return page; return page;
} }
......
...@@ -489,7 +489,7 @@ asmlinkage long sys_get_mempolicy(int __user *policy, ...@@ -489,7 +489,7 @@ asmlinkage long sys_get_mempolicy(int __user *policy,
if (flags & ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR)) if (flags & ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR))
return -EINVAL; return -EINVAL;
if (nmask != NULL && maxnode < numnodes) if (nmask != NULL && maxnode < MAX_NUMNODES)
return -EINVAL; return -EINVAL;
if (flags & MPOL_F_ADDR) { if (flags & MPOL_F_ADDR) {
down_read(&mm->mmap_sem); down_read(&mm->mmap_sem);
......
...@@ -37,13 +37,13 @@ ...@@ -37,13 +37,13 @@
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include "internal.h" #include "internal.h"
nodemask_t node_online_map = NODE_MASK_NONE; /* MCD - HACK: Find somewhere to initialize this EARLY, or make this initializer cleaner */
nodemask_t node_online_map = { { [0] = 1UL } };
nodemask_t node_possible_map = NODE_MASK_ALL; nodemask_t node_possible_map = NODE_MASK_ALL;
struct pglist_data *pgdat_list; struct pglist_data *pgdat_list;
unsigned long totalram_pages; unsigned long totalram_pages;
unsigned long totalhigh_pages; unsigned long totalhigh_pages;
long nr_swap_pages; long nr_swap_pages;
int numnodes = 1;
int sysctl_lower_zone_protection = 0; int sysctl_lower_zone_protection = 0;
EXPORT_SYMBOL(totalram_pages); EXPORT_SYMBOL(totalram_pages);
...@@ -1220,13 +1220,13 @@ static int __init build_zonelists_node(pg_data_t *pgdat, struct zonelist *zoneli ...@@ -1220,13 +1220,13 @@ static int __init build_zonelists_node(pg_data_t *pgdat, struct zonelist *zoneli
} }
#ifdef CONFIG_NUMA #ifdef CONFIG_NUMA
#define MAX_NODE_LOAD (numnodes) #define MAX_NODE_LOAD (num_online_nodes())
static int __initdata node_load[MAX_NUMNODES]; static int __initdata node_load[MAX_NUMNODES];
/** /**
* find_next_best_node - find the next node that should appear in a given * find_next_best_node - find the next node that should appear in a given
* node's fallback list * node's fallback list
* @node: node whose fallback list we're appending * @node: node whose fallback list we're appending
* @used_node_mask: pointer to the bitmap of already used nodes * @used_node_mask: nodemask_t of already used nodes
* *
* We use a number of factors to determine which is the next node that should * We use a number of factors to determine which is the next node that should
* appear on a given node's fallback list. The node should not have appeared * appear on a given node's fallback list. The node should not have appeared
...@@ -1237,24 +1237,24 @@ static int __initdata node_load[MAX_NUMNODES]; ...@@ -1237,24 +1237,24 @@ static int __initdata node_load[MAX_NUMNODES];
* on them otherwise. * on them otherwise.
* It returns -1 if no node is found. * It returns -1 if no node is found.
*/ */
static int __init find_next_best_node(int node, void *used_node_mask) static int __init find_next_best_node(int node, nodemask_t *used_node_mask)
{ {
int i, n, val; int i, n, val;
int min_val = INT_MAX; int min_val = INT_MAX;
int best_node = -1; int best_node = -1;
for (i = 0; i < numnodes; i++) { for_each_online_node(i) {
cpumask_t tmp; cpumask_t tmp;
/* Start from local node */ /* Start from local node */
n = (node+i)%numnodes; n = (node+i) % num_online_nodes();
/* Don't want a node to appear more than once */ /* Don't want a node to appear more than once */
if (test_bit(n, used_node_mask)) if (node_isset(n, *used_node_mask))
continue; continue;
/* Use the local node if we haven't already */ /* Use the local node if we haven't already */
if (!test_bit(node, used_node_mask)) { if (!node_isset(node, *used_node_mask)) {
best_node = node; best_node = node;
break; break;
} }
...@@ -1278,7 +1278,7 @@ static int __init find_next_best_node(int node, void *used_node_mask) ...@@ -1278,7 +1278,7 @@ static int __init find_next_best_node(int node, void *used_node_mask)
} }
if (best_node >= 0) if (best_node >= 0)
set_bit(best_node, used_node_mask); node_set(best_node, *used_node_mask);
return best_node; return best_node;
} }
...@@ -1288,7 +1288,7 @@ static void __init build_zonelists(pg_data_t *pgdat) ...@@ -1288,7 +1288,7 @@ static void __init build_zonelists(pg_data_t *pgdat)
int i, j, k, node, local_node; int i, j, k, node, local_node;
int prev_node, load; int prev_node, load;
struct zonelist *zonelist; struct zonelist *zonelist;
DECLARE_BITMAP(used_mask, MAX_NUMNODES); nodemask_t used_mask;
/* initialize zonelists */ /* initialize zonelists */
for (i = 0; i < GFP_ZONETYPES; i++) { for (i = 0; i < GFP_ZONETYPES; i++) {
...@@ -1299,10 +1299,10 @@ static void __init build_zonelists(pg_data_t *pgdat) ...@@ -1299,10 +1299,10 @@ static void __init build_zonelists(pg_data_t *pgdat)
/* NUMA-aware ordering of nodes */ /* NUMA-aware ordering of nodes */
local_node = pgdat->node_id; local_node = pgdat->node_id;
load = numnodes; load = num_online_nodes();
prev_node = local_node; prev_node = local_node;
bitmap_zero(used_mask, MAX_NUMNODES); nodes_clear(used_mask);
while ((node = find_next_best_node(local_node, used_mask)) >= 0) { while ((node = find_next_best_node(local_node, &used_mask)) >= 0) {
/* /*
* We don't want to pressure a particular node. * We don't want to pressure a particular node.
* So adding penalty to the first node in same * So adding penalty to the first node in same
...@@ -1358,11 +1358,17 @@ static void __init build_zonelists(pg_data_t *pgdat) ...@@ -1358,11 +1358,17 @@ static void __init build_zonelists(pg_data_t *pgdat)
* zones coming right after the local ones are those from * zones coming right after the local ones are those from
* node N+1 (modulo N) * node N+1 (modulo N)
*/ */
for (node = local_node + 1; node < numnodes; node++) for (node = local_node + 1; node < MAX_NUMNODES; node++) {
j = build_zonelists_node(NODE_DATA(node), zonelist, j, k); if (!node_online(node))
for (node = 0; node < local_node; node++) continue;
j = build_zonelists_node(NODE_DATA(node), zonelist, j, k); j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
}
for (node = 0; node < local_node; node++) {
if (!node_online(node))
continue;
j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
}
zonelist->zones[j] = NULL; zonelist->zones[j] = NULL;
} }
} }
...@@ -1373,9 +1379,9 @@ void __init build_all_zonelists(void) ...@@ -1373,9 +1379,9 @@ void __init build_all_zonelists(void)
{ {
int i; int i;
for(i = 0 ; i < numnodes ; i++) for_each_online_node(i)
build_zonelists(NODE_DATA(i)); build_zonelists(NODE_DATA(i));
printk("Built %i zonelists\n", numnodes); printk("Built %i zonelists\n", num_online_nodes());
} }
/* /*
......
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