[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: Keiichiro Tokunaga <tokuanga.keiich@jp.fujitsu.com> Signed-off-by: Yasunori Goto <y-goto@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Родитель
1f04bbd2d3
Коммит
0fc44159bf
|
@ -38,7 +38,7 @@ int arch_register_cpu(int num){
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
int node = cpu_to_node(num);
|
int node = cpu_to_node(num);
|
||||||
if (node_online(node))
|
if (node_online(node))
|
||||||
parent = &node_devices[node].node;
|
parent = &node_devices[parent_node(node)];
|
||||||
#endif /* CONFIG_NUMA */
|
#endif /* CONFIG_NUMA */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -61,7 +61,7 @@ void arch_unregister_cpu(int num) {
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
int node = cpu_to_node(num);
|
int node = cpu_to_node(num);
|
||||||
if (node_online(node))
|
if (node_online(node))
|
||||||
parent = &node_devices[node].node;
|
parent = &node_devices[parent_node(node)];
|
||||||
#endif /* CONFIG_NUMA */
|
#endif /* CONFIG_NUMA */
|
||||||
|
|
||||||
return unregister_cpu(&cpu_devices[num].cpu, parent);
|
return unregister_cpu(&cpu_devices[num].cpu, parent);
|
||||||
|
@ -74,16 +74,13 @@ EXPORT_SYMBOL(arch_unregister_cpu);
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
#include <linux/mmzone.h>
|
#include <linux/mmzone.h>
|
||||||
#include <asm/node.h>
|
|
||||||
|
|
||||||
struct i386_node node_devices[MAX_NUMNODES];
|
|
||||||
|
|
||||||
static int __init topology_init(void)
|
static int __init topology_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for_each_online_node(i)
|
for_each_online_node(i)
|
||||||
arch_register_node(i);
|
register_one_node(i);
|
||||||
|
|
||||||
for_each_present_cpu(i)
|
for_each_present_cpu(i)
|
||||||
arch_register_cpu(i);
|
arch_register_cpu(i);
|
||||||
|
|
|
@ -26,9 +26,6 @@
|
||||||
#include <asm/numa.h>
|
#include <asm/numa.h>
|
||||||
#include <asm/cpu.h>
|
#include <asm/cpu.h>
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA
|
|
||||||
static struct node *sysfs_nodes;
|
|
||||||
#endif
|
|
||||||
static struct ia64_cpu *sysfs_cpus;
|
static struct ia64_cpu *sysfs_cpus;
|
||||||
|
|
||||||
int arch_register_cpu(int num)
|
int arch_register_cpu(int num)
|
||||||
|
@ -36,7 +33,7 @@ int arch_register_cpu(int num)
|
||||||
struct node *parent = NULL;
|
struct node *parent = NULL;
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
parent = &sysfs_nodes[cpu_to_node(num)];
|
parent = &node_devices[cpu_to_node(num)];
|
||||||
#endif /* CONFIG_NUMA */
|
#endif /* CONFIG_NUMA */
|
||||||
|
|
||||||
#if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU)
|
#if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU)
|
||||||
|
@ -59,7 +56,7 @@ void arch_unregister_cpu(int num)
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
int node = cpu_to_node(num);
|
int node = cpu_to_node(num);
|
||||||
parent = &sysfs_nodes[node];
|
parent = &node_devices[node];
|
||||||
#endif /* CONFIG_NUMA */
|
#endif /* CONFIG_NUMA */
|
||||||
|
|
||||||
return unregister_cpu(&sysfs_cpus[num].cpu, parent);
|
return unregister_cpu(&sysfs_cpus[num].cpu, parent);
|
||||||
|
@ -74,17 +71,11 @@ static int __init topology_init(void)
|
||||||
int i, err = 0;
|
int i, err = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA
|
#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?
|
* MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes?
|
||||||
*/
|
*/
|
||||||
for_each_online_node(i) {
|
for_each_online_node(i) {
|
||||||
if ((err = register_node(&sysfs_nodes[i], i, 0)))
|
if ((err = register_one_node(i)))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -304,23 +304,12 @@ static struct notifier_block sysfs_cpu_nb = {
|
||||||
/* NUMA stuff */
|
/* NUMA stuff */
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
static struct node node_devices[MAX_NUMNODES];
|
|
||||||
|
|
||||||
static void register_nodes(void)
|
static void register_nodes(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_NUMNODES; i++) {
|
for (i = 0; i < MAX_NUMNODES; i++)
|
||||||
if (node_online(i)) {
|
register_one_node(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sysfs_add_device_to_node(struct sys_device *dev, int nid)
|
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);
|
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)
|
static int __init register_node_type(void)
|
||||||
{
|
{
|
||||||
return sysdev_class_register(&node_class);
|
return sysdev_class_register(&node_class);
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
#include <linux/nodemask.h>
|
#include <linux/nodemask.h>
|
||||||
#include <linux/percpu.h>
|
#include <linux/percpu.h>
|
||||||
|
|
||||||
#include <asm/node.h>
|
|
||||||
|
|
||||||
struct i386_cpu {
|
struct i386_cpu {
|
||||||
struct cpu cpu;
|
struct cpu cpu;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
#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;
|
struct sys_device sysdev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern struct node node_devices[];
|
||||||
|
|
||||||
extern int register_node(struct node *, int, struct node *);
|
extern int register_node(struct node *, int, struct node *);
|
||||||
extern void unregister_node(struct node *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)
|
#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)
|
if (ret < 0)
|
||||||
goto error;
|
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);
|
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 this memory as resource */
|
||||||
register_memory_resource(start, size);
|
register_memory_resource(start, size);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче