aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Travis <travis@sgi.com>2008-12-15 23:26:48 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-12-19 02:17:04 -0500
commite057d7aea9d8f2a46cd440d8bfb72245d4e72d79 (patch)
tree8854a3298c136df54f9b25533bcbbd547b60f971
parentec26b805879c7e77865b39ee91b737985e80006d (diff)
cpumask: add sysfs displays for configured and disabled cpu maps
Impact: add new sysfs files. Add sysfs files "kernel_max" and "offline" to display the max CPU index allowed (NR_CPUS-1), and the map of cpus that are offline. Cpus can be offlined via HOTPLUG, disabled by the BIOS ACPI tables, or if they exceed the number of cpus allowed by the NR_CPUS config option, or the "maxcpus=NUM" kernel start parameter. The "possible_cpus=NUM" parameter can also extend the number of possible cpus allowed, in which case the cpus not present at startup will be in the offline state. (These cpus can be HOTPLUGGED ON after system startup [pending a follow-on patch to provide the capability via the /sys/devices/sys/cpu/cpuN/online mechanism to bring them online.]) By design, the "offlined cpus > possible cpus" display will always use the following formats: * all possible cpus online: "x$" or "x-y$" * some possible cpus offline: ".*,x$" or ".*,x-y$" where: x == number of possible cpus (nr_cpu_ids); and y == number of cpus >= NR_CPUS or maxcpus (if y > x). One use of this feature is for distros to select (or configure) the appropriate kernel to install for the resident system. Notes: * cpus offlined <= possible cpus will be printed for all architectures. * cpus offlined > possible cpus will only be printed for arches that set 'total_cpus' [X86 only in this patch]. Based on tip/cpus4096 + .../rusty/linux-2.6-for-ingo.git/master + x86-only-patches sent 12/15. Signed-off-by: Mike Travis <travis@sgi.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--drivers/base/cpu.c44
-rw-r--r--include/linux/smp.h3
2 files changed, 47 insertions, 0 deletions
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 4259072f5bd0..2aef96f20b30 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -128,10 +128,54 @@ print_cpus_func(online);
128print_cpus_func(possible); 128print_cpus_func(possible);
129print_cpus_func(present); 129print_cpus_func(present);
130 130
131/*
132 * Print values for NR_CPUS and offlined cpus
133 */
134static ssize_t print_cpus_kernel_max(struct sysdev_class *class, char *buf)
135{
136 int n = snprintf(buf, PAGE_SIZE-2, "%d\n", CONFIG_NR_CPUS - 1);
137 return n;
138}
139static SYSDEV_CLASS_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL);
140
141/* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */
142unsigned int total_cpus;
143
144static ssize_t print_cpus_offline(struct sysdev_class *class, char *buf)
145{
146 int n = 0, len = PAGE_SIZE-2;
147 cpumask_var_t offline;
148
149 /* display offline cpus < nr_cpu_ids */
150 if (!alloc_cpumask_var(&offline, GFP_KERNEL))
151 return -ENOMEM;
152 cpumask_complement(offline, cpu_online_mask);
153 n = cpulist_scnprintf(buf, len, offline);
154 free_cpumask_var(offline);
155
156 /* display offline cpus >= nr_cpu_ids */
157 if (total_cpus && nr_cpu_ids < total_cpus) {
158 if (n && n < len)
159 buf[n++] = ',';
160
161 if (nr_cpu_ids == total_cpus-1)
162 n += snprintf(&buf[n], len - n, "%d", nr_cpu_ids);
163 else
164 n += snprintf(&buf[n], len - n, "%d-%d",
165 nr_cpu_ids, total_cpus-1);
166 }
167
168 n += snprintf(&buf[n], len - n, "\n");
169 return n;
170}
171static SYSDEV_CLASS_ATTR(offline, 0444, print_cpus_offline, NULL);
172
131static struct sysdev_class_attribute *cpu_state_attr[] = { 173static struct sysdev_class_attribute *cpu_state_attr[] = {
132 &attr_online_map, 174 &attr_online_map,
133 &attr_possible_map, 175 &attr_possible_map,
134 &attr_present_map, 176 &attr_present_map,
177 &attr_kernel_max,
178 &attr_offline,
135}; 179};
136 180
137static int cpu_states_init(void) 181static int cpu_states_init(void)
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 3f9a60043a97..0d5770c2e43a 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -21,6 +21,9 @@ struct call_single_data {
21 u16 priv; 21 u16 priv;
22}; 22};
23 23
24/* total number of cpus in this system (may exceed NR_CPUS) */
25extern unsigned int total_cpus;
26
24#ifdef CONFIG_SMP 27#ifdef CONFIG_SMP
25 28
26#include <linux/preempt.h> 29#include <linux/preempt.h>