Commit 1e489518 authored by Heiko Carstens's avatar Heiko Carstens Committed by Martin Schwidefsky

[S390] Automatically detect added cpus.

Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 0b18d318
...@@ -505,7 +505,7 @@ static int smp_rescan_cpus_sclp(cpumask_t avail) ...@@ -505,7 +505,7 @@ static int smp_rescan_cpus_sclp(cpumask_t avail)
return rc; return rc;
} }
static int smp_rescan_cpus(void) static int __smp_rescan_cpus(void)
{ {
cpumask_t avail; cpumask_t avail;
...@@ -570,7 +570,7 @@ static void __init smp_detect_cpus(void) ...@@ -570,7 +570,7 @@ static void __init smp_detect_cpus(void)
kfree(info); kfree(info);
printk(KERN_INFO "CPUs: %d configured, %d standby\n", c_cpus, s_cpus); printk(KERN_INFO "CPUs: %d configured, %d standby\n", c_cpus, s_cpus);
get_online_cpus(); get_online_cpus();
smp_rescan_cpus(); __smp_rescan_cpus();
put_online_cpus(); put_online_cpus();
} }
...@@ -1088,8 +1088,8 @@ static int __devinit smp_add_present_cpu(int cpu) ...@@ -1088,8 +1088,8 @@ static int __devinit smp_add_present_cpu(int cpu)
} }
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
static ssize_t __ref rescan_store(struct sys_device *dev,
const char *buf, size_t count) int smp_rescan_cpus(void)
{ {
cpumask_t newcpus; cpumask_t newcpus;
int cpu; int cpu;
...@@ -1098,7 +1098,7 @@ static ssize_t __ref rescan_store(struct sys_device *dev, ...@@ -1098,7 +1098,7 @@ static ssize_t __ref rescan_store(struct sys_device *dev,
get_online_cpus(); get_online_cpus();
mutex_lock(&smp_cpu_state_mutex); mutex_lock(&smp_cpu_state_mutex);
newcpus = cpu_present_map; newcpus = cpu_present_map;
rc = smp_rescan_cpus(); rc = __smp_rescan_cpus();
if (rc) if (rc)
goto out; goto out;
cpus_andnot(newcpus, cpu_present_map, newcpus); cpus_andnot(newcpus, cpu_present_map, newcpus);
...@@ -1113,6 +1113,15 @@ static ssize_t __ref rescan_store(struct sys_device *dev, ...@@ -1113,6 +1113,15 @@ static ssize_t __ref rescan_store(struct sys_device *dev,
put_online_cpus(); put_online_cpus();
if (!cpus_empty(newcpus)) if (!cpus_empty(newcpus))
topology_schedule_update(); topology_schedule_update();
return rc;
}
static ssize_t __ref rescan_store(struct sys_device *dev, const char *buf,
size_t count)
{
int rc;
rc = smp_rescan_cpus();
return rc ? rc : count; return rc ? rc : count;
} }
static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store); static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/sysdev.h> #include <linux/sysdev.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <asm/smp.h>
#include "sclp.h" #include "sclp.h"
#define TAG "sclp_config: " #define TAG "sclp_config: "
...@@ -19,9 +20,11 @@ struct conf_mgm_data { ...@@ -19,9 +20,11 @@ struct conf_mgm_data {
u8 ev_qualifier; u8 ev_qualifier;
} __attribute__((packed)); } __attribute__((packed));
#define EV_QUAL_CPU_CHANGE 1
#define EV_QUAL_CAP_CHANGE 3 #define EV_QUAL_CAP_CHANGE 3
static struct work_struct sclp_cpu_capability_work; static struct work_struct sclp_cpu_capability_work;
static struct work_struct sclp_cpu_change_work;
static void sclp_cpu_capability_notify(struct work_struct *work) static void sclp_cpu_capability_notify(struct work_struct *work)
{ {
...@@ -37,13 +40,24 @@ static void sclp_cpu_capability_notify(struct work_struct *work) ...@@ -37,13 +40,24 @@ static void sclp_cpu_capability_notify(struct work_struct *work)
put_online_cpus(); put_online_cpus();
} }
static void sclp_cpu_change_notify(struct work_struct *work)
{
smp_rescan_cpus();
}
static void sclp_conf_receiver_fn(struct evbuf_header *evbuf) static void sclp_conf_receiver_fn(struct evbuf_header *evbuf)
{ {
struct conf_mgm_data *cdata; struct conf_mgm_data *cdata;
cdata = (struct conf_mgm_data *)(evbuf + 1); cdata = (struct conf_mgm_data *)(evbuf + 1);
if (cdata->ev_qualifier == EV_QUAL_CAP_CHANGE) switch (cdata->ev_qualifier) {
case EV_QUAL_CPU_CHANGE:
schedule_work(&sclp_cpu_change_work);
break;
case EV_QUAL_CAP_CHANGE:
schedule_work(&sclp_cpu_capability_work); schedule_work(&sclp_cpu_capability_work);
break;
}
} }
static struct sclp_register sclp_conf_register = static struct sclp_register sclp_conf_register =
...@@ -57,6 +71,7 @@ static int __init sclp_conf_init(void) ...@@ -57,6 +71,7 @@ static int __init sclp_conf_init(void)
int rc; int rc;
INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify); INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify);
INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify);
rc = sclp_register(&sclp_conf_register); rc = sclp_register(&sclp_conf_register);
if (rc) { if (rc) {
......
...@@ -108,5 +108,11 @@ static inline void smp_send_stop(void) ...@@ -108,5 +108,11 @@ static inline void smp_send_stop(void)
#define smp_cpu_not_running(cpu) 1 #define smp_cpu_not_running(cpu) 1
#endif #endif
#ifdef CONFIG_HOTPLUG_CPU
extern int smp_rescan_cpus(void);
#else
static inline int smp_rescan_cpus(void) { return 0; }
#endif
extern union save_area *zfcpdump_save_areas[NR_CPUS + 1]; extern union save_area *zfcpdump_save_areas[NR_CPUS + 1];
#endif #endif
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