@@ -23,6 +23,7 @@ struct sysdev_class cpu_sysdev_class = {
EXPORT_SYMBOL(cpu_sysdev_class);
static DEFINE_PER_CPU(struct sys_device *, cpu_sys_devices);
+static DEFINE_PER_CPU(bool, is_hotpluggable);
#ifdef CONFIG_HOTPLUG_CPU
static ssize_t show_online(struct sys_device *dev, struct sysdev_attribute *attr,
@@ -76,6 +77,7 @@ void unregister_cpu(struct cpu *cpu)
sysdev_unregister(&cpu->sysdev);
per_cpu(cpu_sys_devices, logical_cpu) = NULL;
+ per_cpu(is_hotpluggable, logical_cpu) = 0;
return;
}
@@ -224,8 +226,10 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
error = sysdev_register(&cpu->sysdev);
- if (!error && cpu->hotpluggable)
+ if (!error && cpu->hotpluggable) {
register_cpu_control(cpu);
+ per_cpu(is_hotpluggable, num) = 1;
+ }
if (!error)
per_cpu(cpu_sys_devices, num) = &cpu->sysdev;
if (!error)
@@ -238,6 +242,12 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
return error;
}
+bool cpu_is_hotpluggable(int num)
+{
+ return per_cpu(is_hotpluggable, num);
+}
+EXPORT_SYMBOL_GPL(cpu_is_hotpluggable);
+
struct sys_device *get_cpu_sysdev(unsigned cpu)
{
if (cpu < nr_cpu_ids && cpu_possible(cpu))
@@ -26,6 +26,7 @@ struct cpu {
};
extern int register_cpu(struct cpu *cpu, int num);
+extern bool cpu_is_hotpluggable(int num);
extern struct sys_device *get_cpu_sysdev(unsigned cpu);
extern int cpu_add_sysdev_attr(struct sysdev_attribute *attr);
@@ -1388,7 +1388,7 @@ rcu_torture_onoff(void *arg)
WARN_ON(maxcpu < 0);
while (!kthread_should_stop()) {
cpu = (rcu_random(&rand) >> 4) % (maxcpu + 1);
- if (cpu_online(cpu)) {
+ if (cpu_online(cpu) && cpu_is_hotpluggable(cpu)) {
if (verbose)
printk(KERN_ALERT "%s" TORTURE_FLAG
"rcu_torture_onoff task: offlining %d\n",
@@ -1402,7 +1402,7 @@ rcu_torture_onoff(void *arg)
torture_type, cpu);
n_offline_successes++;
}
- } else {
+ } else if (cpu_is_hotpluggable(cpu)) {
if (verbose)
printk(KERN_ALERT "%s" TORTURE_FLAG
"rcu_torture_onoff task: onlining %d\n",