From: Shaohui Zheng <shaohui.zheng@intel.com>
To: akpm@linux-foundation.org, linux-mm@kvack.org
Cc: Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
x86@kernel.org, Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>,
Greg Kroah-Hartman <gregkh@suse.de>,
David Rientjes <rientjes@google.com>,
Alex Chiang <achiang@hp.com>,
linux-kernel@vger.kernel.org, ak@linux.intel.co,
fengguang.wu@intel.com, haicheng.li@linux.intel.com,
shaohui.zheng@linux.intel.com
Subject: [RFC, 3/7] NUMA hotplug emulator
Date: Thu, 13 May 2010 19:48:35 +0800 [thread overview]
Message-ID: <20100513114835.GD2169@shaohui> (raw)
[-- Attachment #1: Type: text/plain, Size: 3593 bytes --]
Userland interface to hotplug-add fake offlined nodes.
Add a sysfs entry "probe" under /sys/devices/system/node/:
- to show all fake offlined nodes:
$ cat /sys/devices/system/node/probe
- to hotadd a fake offlined node, e.g. nodeid is N:
$ echo N > /sys/devices/system/node/probe
Signed-off-by: Haicheng Li <haicheng.li@linux.intel.com>
Signed-off-by: Shaohui Zheng <shaohui.zheng@intel.com>
---
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 9458685..2c078c8 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1214,6 +1214,20 @@ config NUMA_EMU
into virtual nodes when booted with "numa=fake=N", where N is the
number of nodes. This is only useful for debugging.
+config NUMA_HOTPLUG_EMU
+ bool "NUMA hotplug emulator"
+ depends on X86_64 && NUMA && HOTPLUG
+ ---help---
+
+config NODE_HOTPLUG_EMU
+ bool "Node hotplug emulation"
+ depends on NUMA_HOTPLUG_EMU && MEMORY_HOTPLUG
+ ---help---
+ Enable Node hotplug emulation. The machine will be setup with
+ hidden virtual nodes when booted with "numa=hide=N*size", where
+ N is the number of hidden nodes, size is the memory size per
+ hidden node. This is only useful for debugging.
+
config NODES_SHIFT
int "Maximum NUMA Nodes (as a power of 2)" if !MAXSMP
range 1 10
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 057979a..a0be257 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -535,6 +535,26 @@ void unregister_one_node(int nid)
unregister_node(&node_devices[nid]);
}
+#ifdef CONFIG_NODE_HOTPLUG_EMU
+static ssize_t store_nodes_probe(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ const char *buf, size_t count)
+{
+ long nid;
+ int ret;
+
+ strict_strtol(buf, 0, &nid);
+ if (nid < 0 || nid > nr_node_ids - 1) {
+ printk(KERN_ERR "Invalid NUMA node id: %d (0 <= nid < %d).\n",
+ nid, nr_node_ids);
+ return -EPERM;
+ }
+ hotadd_hidden_nodes(nid);
+
+ return count;
+}
+#endif
+
/*
* node states attributes
*/
@@ -563,26 +583,35 @@ static ssize_t show_node_state(struct sysdev_class *class,
return print_nodes_state(na->state, buf);
}
-#define _NODE_ATTR(name, state) \
+#define _NODE_ATTR_RO(name, state) \
{ _SYSDEV_CLASS_ATTR(name, 0444, show_node_state, NULL), state }
+#define _NODE_ATTR_RW(name, store_func, state) \
+ { _SYSDEV_CLASS_ATTR(name, 0644, show_node_state, store_func), state }
+
static struct node_attr node_state_attr[] = {
- _NODE_ATTR(possible, N_POSSIBLE),
- _NODE_ATTR(online, N_ONLINE),
- _NODE_ATTR(has_normal_memory, N_NORMAL_MEMORY),
- _NODE_ATTR(has_cpu, N_CPU),
+ [N_POSSIBLE] = _NODE_ATTR_RO(possible, N_POSSIBLE),
+#ifdef CONFIG_NODE_HOTPLUG_EMU
+ [N_HIDDEN] = _NODE_ATTR_RW(probe, store_nodes_probe, N_HIDDEN),
+#endif
+ [N_ONLINE] = _NODE_ATTR_RO(online, N_ONLINE),
+ [N_NORMAL_MEMORY] = _NODE_ATTR_RO(has_normal_memory, N_NORMAL_MEMORY),
#ifdef CONFIG_HIGHMEM
- _NODE_ATTR(has_high_memory, N_HIGH_MEMORY),
+ [N_HIGH_MEMORY] = _NODE_ATTR_RO(has_high_memory, N_HIGH_MEMORY),
#endif
+ [N_CPU] = _NODE_ATTR_RO(has_cpu, N_CPU),
};
static struct sysdev_class_attribute *node_state_attrs[] = {
- &node_state_attr[0].attr,
- &node_state_attr[1].attr,
- &node_state_attr[2].attr,
- &node_state_attr[3].attr,
+ &node_state_attr[N_POSSIBLE].attr,
+#ifdef CONFIG_NODE_HOTPLUG_EMU
+ &node_state_attr[N_HIDDEN].attr,
+#endif
+ &node_state_attr[N_ONLINE].attr,
+ &node_state_attr[N_NORMAL_MEMORY].attr,
+ &node_state_attr[N_CPU].attr,
#ifdef CONFIG_HIGHMEM
- &node_state_attr[4].attr,
+ &node_state_attr[N_HIGH_MEMORY].attr,
#endif
NULL
};
--
Thanks & Regards,
Shaohui
[-- Attachment #2: 003-hotplug-emulator-userland-interface-to-add-fake-node.patch --]
[-- Type: text/x-diff, Size: 3562 bytes --]
Userland interface to hotplug-add fake offlined nodes.
Add a sysfs entry "probe" under /sys/devices/system/node/:
- to show all fake offlined nodes:
$ cat /sys/devices/system/node/probe
- to hotadd a fake offlined node, e.g. nodeid is N:
$ echo N > /sys/devices/system/node/probe
Signed-off-by: Haicheng Li <haicheng.li@linux.intel.com>
Signed-off-by: Shaohui Zheng <shaohui.zheng@intel.com>
---
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 9458685..2c078c8 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1214,6 +1214,20 @@ config NUMA_EMU
into virtual nodes when booted with "numa=fake=N", where N is the
number of nodes. This is only useful for debugging.
+config NUMA_HOTPLUG_EMU
+ bool "NUMA hotplug emulator"
+ depends on X86_64 && NUMA && HOTPLUG
+ ---help---
+
+config NODE_HOTPLUG_EMU
+ bool "Node hotplug emulation"
+ depends on NUMA_HOTPLUG_EMU && MEMORY_HOTPLUG
+ ---help---
+ Enable Node hotplug emulation. The machine will be setup with
+ hidden virtual nodes when booted with "numa=hide=N*size", where
+ N is the number of hidden nodes, size is the memory size per
+ hidden node. This is only useful for debugging.
+
config NODES_SHIFT
int "Maximum NUMA Nodes (as a power of 2)" if !MAXSMP
range 1 10
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 057979a..a0be257 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -535,6 +535,26 @@ void unregister_one_node(int nid)
unregister_node(&node_devices[nid]);
}
+#ifdef CONFIG_NODE_HOTPLUG_EMU
+static ssize_t store_nodes_probe(struct sysdev_class *class,
+ struct sysdev_class_attribute *attr,
+ const char *buf, size_t count)
+{
+ long nid;
+ int ret;
+
+ strict_strtol(buf, 0, &nid);
+ if (nid < 0 || nid > nr_node_ids - 1) {
+ printk(KERN_ERR "Invalid NUMA node id: %d (0 <= nid < %d).\n",
+ nid, nr_node_ids);
+ return -EPERM;
+ }
+ hotadd_hidden_nodes(nid);
+
+ return count;
+}
+#endif
+
/*
* node states attributes
*/
@@ -563,26 +583,35 @@ static ssize_t show_node_state(struct sysdev_class *class,
return print_nodes_state(na->state, buf);
}
-#define _NODE_ATTR(name, state) \
+#define _NODE_ATTR_RO(name, state) \
{ _SYSDEV_CLASS_ATTR(name, 0444, show_node_state, NULL), state }
+#define _NODE_ATTR_RW(name, store_func, state) \
+ { _SYSDEV_CLASS_ATTR(name, 0644, show_node_state, store_func), state }
+
static struct node_attr node_state_attr[] = {
- _NODE_ATTR(possible, N_POSSIBLE),
- _NODE_ATTR(online, N_ONLINE),
- _NODE_ATTR(has_normal_memory, N_NORMAL_MEMORY),
- _NODE_ATTR(has_cpu, N_CPU),
+ [N_POSSIBLE] = _NODE_ATTR_RO(possible, N_POSSIBLE),
+#ifdef CONFIG_NODE_HOTPLUG_EMU
+ [N_HIDDEN] = _NODE_ATTR_RW(probe, store_nodes_probe, N_HIDDEN),
+#endif
+ [N_ONLINE] = _NODE_ATTR_RO(online, N_ONLINE),
+ [N_NORMAL_MEMORY] = _NODE_ATTR_RO(has_normal_memory, N_NORMAL_MEMORY),
#ifdef CONFIG_HIGHMEM
- _NODE_ATTR(has_high_memory, N_HIGH_MEMORY),
+ [N_HIGH_MEMORY] = _NODE_ATTR_RO(has_high_memory, N_HIGH_MEMORY),
#endif
+ [N_CPU] = _NODE_ATTR_RO(has_cpu, N_CPU),
};
static struct sysdev_class_attribute *node_state_attrs[] = {
- &node_state_attr[0].attr,
- &node_state_attr[1].attr,
- &node_state_attr[2].attr,
- &node_state_attr[3].attr,
+ &node_state_attr[N_POSSIBLE].attr,
+#ifdef CONFIG_NODE_HOTPLUG_EMU
+ &node_state_attr[N_HIDDEN].attr,
+#endif
+ &node_state_attr[N_ONLINE].attr,
+ &node_state_attr[N_NORMAL_MEMORY].attr,
+ &node_state_attr[N_CPU].attr,
#ifdef CONFIG_HIGHMEM
- &node_state_attr[4].attr,
+ &node_state_attr[N_HIGH_MEMORY].attr,
#endif
NULL
};
next reply other threads:[~2010-05-13 11:52 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-13 11:48 Shaohui Zheng [this message]
2010-05-13 16:55 ` [RFC, 3/7] NUMA hotplug emulator Greg KH
2010-05-13 16:55 ` Greg KH
2010-05-13 17:54 ` Dave Hansen
2010-05-13 17:54 ` Dave Hansen
2010-05-13 18:05 ` Greg KH
2010-05-13 18:05 ` Greg KH
2010-05-14 2:13 ` Haicheng Li
2010-05-14 2:13 ` Haicheng Li
2010-05-14 1:45 ` Shaohui Zheng
2010-05-14 1:45 ` Shaohui Zheng
2010-05-14 2:01 ` Wu Fengguang
2010-05-14 2:01 ` Wu Fengguang
2010-05-14 2:11 ` Shaohui Zheng
2010-05-14 2:11 ` Shaohui Zheng
2010-05-14 2:01 ` Haicheng Li
2010-05-14 2:01 ` Haicheng Li
2010-05-14 3:31 ` Haicheng Li
2010-05-14 3:31 ` Haicheng Li
2010-05-14 4:11 ` Wu Fengguang
2010-05-14 4:11 ` Wu Fengguang
2010-05-14 5:19 ` Shaohui Zheng
2010-05-14 5:19 ` Shaohui Zheng
2010-05-14 5:32 ` Haicheng Li
2010-05-14 5:32 ` Haicheng Li
2010-05-14 5:52 ` Wu Fengguang
2010-05-14 5:52 ` Wu Fengguang
2010-05-21 10:08 ` Ankita Garg
2010-05-21 10:08 ` Ankita Garg
2010-05-24 1:31 ` Shaohui Zheng
2010-05-24 1:31 ` Shaohui Zheng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100513114835.GD2169@shaohui \
--to=shaohui.zheng@intel.com \
--cc=achiang@hp.com \
--cc=ak@linux.intel.co \
--cc=akpm@linux-foundation.org \
--cc=fengguang.wu@intel.com \
--cc=gregkh@suse.de \
--cc=haicheng.li@linux.intel.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mingo@redhat.com \
--cc=rientjes@google.com \
--cc=seto.hidetoshi@jp.fujitsu.com \
--cc=shaohui.zheng@linux.intel.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.