Commit 0fc44159 authored by Yasunori Goto's avatar Yasunori Goto Committed by Linus Torvalds

[PATCH] Register sysfs file for hotplugged new node

When new node becomes enable by hot-add, new sysfs file must be created for
new node.  So, if new node is enabled by add_memory(), register_one_node() is
called to create it.  In addition, I386's arch_register_node() and a part of
register_nodes() of powerpc are consolidated to register_one_node() as a
generic_code().

This is tested by Tiger4(IPF) with node hot-plug emulation.
Signed-off-by: default avatarKeiichiro Tokunaga <tokuanga.keiich@jp.fujitsu.com>
Signed-off-by: default avatarYasunori Goto <y-goto@jp.fujitsu.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1f04bbd2
......@@ -38,7 +38,7 @@ int arch_register_cpu(int num){
#ifdef CONFIG_NUMA
int node = cpu_to_node(num);
if (node_online(node))
parent = &node_devices[node].node;
parent = &node_devices[parent_node(node)];
#endif /* CONFIG_NUMA */
/*
......@@ -61,7 +61,7 @@ void arch_unregister_cpu(int num) {
#ifdef CONFIG_NUMA
int node = cpu_to_node(num);
if (node_online(node))
parent = &node_devices[node].node;
parent = &node_devices[parent_node(node)];
#endif /* CONFIG_NUMA */
return unregister_cpu(&cpu_devices[num].cpu, parent);
......@@ -74,16 +74,13 @@ EXPORT_SYMBOL(arch_unregister_cpu);
#ifdef CONFIG_NUMA
#include <linux/mmzone.h>
#include <asm/node.h>
struct i386_node node_devices[MAX_NUMNODES];
static int __init topology_init(void)
{
int i;
for_each_online_node(i)
arch_register_node(i);
register_one_node(i);
for_each_present_cpu(i)
arch_register_cpu(i);
......
......@@ -26,9 +26,6 @@
#include <asm/numa.h>
#include <asm/cpu.h>
#ifdef CONFIG_NUMA
static struct node *sysfs_nodes;
#endif
static struct ia64_cpu *sysfs_cpus;
int arch_register_cpu(int num)
......@@ -36,7 +33,7 @@ int arch_register_cpu(int num)
struct node *parent = NULL;
#ifdef CONFIG_NUMA
parent = &sysfs_nodes[cpu_to_node(num)];
parent = &node_devices[cpu_to_node(num)];
#endif /* CONFIG_NUMA */
#if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU)
......@@ -59,7 +56,7 @@ void arch_unregister_cpu(int num)
#ifdef CONFIG_NUMA
int node = cpu_to_node(num);
parent = &sysfs_nodes[node];
parent = &node_devices[node];
#endif /* CONFIG_NUMA */
return unregister_cpu(&sysfs_cpus[num].cpu, parent);
......@@ -74,17 +71,11 @@ static int __init topology_init(void)
int i, err = 0;
#ifdef CONFIG_NUMA
sysfs_nodes = kzalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL);
if (!sysfs_nodes) {
err = -ENOMEM;
goto out;
}
/*
* MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes?
*/
for_each_online_node(i) {
if ((err = register_node(&sysfs_nodes[i], i, 0)))
if ((err = register_one_node(i)))
goto out;
}
#endif
......
......@@ -304,23 +304,12 @@ static struct notifier_block sysfs_cpu_nb = {
/* NUMA stuff */
#ifdef CONFIG_NUMA
static struct node node_devices[MAX_NUMNODES];
static void register_nodes(void)
{
int i;
for (i = 0; i < MAX_NUMNODES; i++) {
if (node_online(i)) {
int p_node = parent_node(i);
struct node *parent = NULL;
if (p_node != i)
parent = &node_devices[p_node];
register_node(&node_devices[i], i, parent);
}
}
for (i = 0; i < MAX_NUMNODES; i++)
register_one_node(i);
}
int sysfs_add_device_to_node(struct sys_device *dev, int nid)
......
......@@ -190,6 +190,31 @@ void unregister_node(struct node *node)
sysdev_unregister(&node->sysdev);
}
struct node node_devices[MAX_NUMNODES];
int register_one_node(int nid)
{
int error = 0;
if (node_online(nid)) {
int p_node = parent_node(nid);
struct node *parent = NULL;
if (p_node != nid)
parent = &node_devices[p_node];
error = register_node(&node_devices[nid], nid, parent);
}
return error;
}
void unregister_one_node(int nid)
{
unregister_node(&node_devices[nid]);
}
static int __init register_node_type(void)
{
return sysdev_class_register(&node_class);
......
......@@ -7,8 +7,6 @@
#include <linux/nodemask.h>
#include <linux/percpu.h>
#include <asm/node.h>
struct i386_cpu {
struct cpu cpu;
};
......
#ifndef _ASM_I386_NODE_H_
#define _ASM_I386_NODE_H_
#include <linux/device.h>
#include <linux/mmzone.h>
#include <linux/node.h>
#include <linux/topology.h>
#include <linux/nodemask.h>
struct i386_node {
struct node node;
};
extern struct i386_node node_devices[MAX_NUMNODES];
static inline int arch_register_node(int num){
int p_node;
struct node *parent = NULL;
if (!node_online(num))
return 0;
p_node = parent_node(num);
if (p_node != num)
parent = &node_devices[p_node].node;
return register_node(&node_devices[num].node, num, parent);
}
#endif /* _ASM_I386_NODE_H_ */
......@@ -26,8 +26,12 @@ struct node {
struct sys_device sysdev;
};
extern struct node node_devices[];
extern int register_node(struct node *, int, struct node *);
extern void unregister_node(struct node *node);
extern int register_one_node(int nid);
extern void unregister_one_node(int nid);
#define to_node(sys_device) container_of(sys_device, struct node, sysdev)
......
......@@ -256,9 +256,19 @@ int add_memory(int nid, u64 start, u64 size)
if (ret < 0)
goto error;
/* we online node here. we have no error path from here. */
/* we online node here. we can't roll back from here. */
node_set_online(nid);
if (new_pgdat) {
ret = register_one_node(nid);
/*
* If sysfs file of new node can't create, cpu on the node
* can't be hot-added. There is no rollback way now.
* So, check by BUG_ON() to catch it reluctantly..
*/
BUG_ON(ret);
}
/* register this memory as resource */
register_memory_resource(start, size);
......
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