diff options
| -rw-r--r-- | arch/s390/kernel/smp.c | 19 | ||||
| -rw-r--r-- | drivers/s390/char/sclp_config.c | 17 | ||||
| -rw-r--r-- | include/asm-s390/smp.h | 6 |
3 files changed, 36 insertions, 6 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 6bb5c050640f..0aeb290060d9 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
| @@ -505,7 +505,7 @@ out: | |||
| 505 | return rc; | 505 | return rc; |
| 506 | } | 506 | } |
| 507 | 507 | ||
| 508 | static int smp_rescan_cpus(void) | 508 | static int __smp_rescan_cpus(void) |
| 509 | { | 509 | { |
| 510 | cpumask_t avail; | 510 | cpumask_t avail; |
| 511 | 511 | ||
| @@ -570,7 +570,7 @@ out: | |||
| 570 | kfree(info); | 570 | kfree(info); |
| 571 | printk(KERN_INFO "CPUs: %d configured, %d standby\n", c_cpus, s_cpus); | 571 | printk(KERN_INFO "CPUs: %d configured, %d standby\n", c_cpus, s_cpus); |
| 572 | get_online_cpus(); | 572 | get_online_cpus(); |
| 573 | smp_rescan_cpus(); | 573 | __smp_rescan_cpus(); |
| 574 | put_online_cpus(); | 574 | put_online_cpus(); |
| 575 | } | 575 | } |
| 576 | 576 | ||
| @@ -1088,8 +1088,8 @@ out: | |||
| 1088 | } | 1088 | } |
| 1089 | 1089 | ||
| 1090 | #ifdef CONFIG_HOTPLUG_CPU | 1090 | #ifdef CONFIG_HOTPLUG_CPU |
| 1091 | static ssize_t __ref rescan_store(struct sys_device *dev, | 1091 | |
| 1092 | const char *buf, size_t count) | 1092 | int smp_rescan_cpus(void) |
| 1093 | { | 1093 | { |
| 1094 | cpumask_t newcpus; | 1094 | cpumask_t newcpus; |
| 1095 | int cpu; | 1095 | int cpu; |
| @@ -1098,7 +1098,7 @@ static ssize_t __ref rescan_store(struct sys_device *dev, | |||
| 1098 | get_online_cpus(); | 1098 | get_online_cpus(); |
| 1099 | mutex_lock(&smp_cpu_state_mutex); | 1099 | mutex_lock(&smp_cpu_state_mutex); |
| 1100 | newcpus = cpu_present_map; | 1100 | newcpus = cpu_present_map; |
| 1101 | rc = smp_rescan_cpus(); | 1101 | rc = __smp_rescan_cpus(); |
| 1102 | if (rc) | 1102 | if (rc) |
| 1103 | goto out; | 1103 | goto out; |
| 1104 | cpus_andnot(newcpus, cpu_present_map, newcpus); | 1104 | cpus_andnot(newcpus, cpu_present_map, newcpus); |
| @@ -1113,6 +1113,15 @@ out: | |||
| 1113 | put_online_cpus(); | 1113 | put_online_cpus(); |
| 1114 | if (!cpus_empty(newcpus)) | 1114 | if (!cpus_empty(newcpus)) |
| 1115 | topology_schedule_update(); | 1115 | topology_schedule_update(); |
| 1116 | return rc; | ||
| 1117 | } | ||
| 1118 | |||
| 1119 | static ssize_t __ref rescan_store(struct sys_device *dev, const char *buf, | ||
| 1120 | size_t count) | ||
| 1121 | { | ||
| 1122 | int rc; | ||
| 1123 | |||
| 1124 | rc = smp_rescan_cpus(); | ||
| 1116 | return rc ? rc : count; | 1125 | return rc ? rc : count; |
| 1117 | } | 1126 | } |
| 1118 | static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store); | 1127 | static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store); |
diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c index b8f35bc52b7b..9e784d5f7f57 100644 --- a/drivers/s390/char/sclp_config.c +++ b/drivers/s390/char/sclp_config.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/cpu.h> | 10 | #include <linux/cpu.h> |
| 11 | #include <linux/sysdev.h> | 11 | #include <linux/sysdev.h> |
| 12 | #include <linux/workqueue.h> | 12 | #include <linux/workqueue.h> |
| 13 | #include <asm/smp.h> | ||
| 13 | #include "sclp.h" | 14 | #include "sclp.h" |
| 14 | 15 | ||
| 15 | #define TAG "sclp_config: " | 16 | #define TAG "sclp_config: " |
| @@ -19,9 +20,11 @@ struct conf_mgm_data { | |||
| 19 | u8 ev_qualifier; | 20 | u8 ev_qualifier; |
| 20 | } __attribute__((packed)); | 21 | } __attribute__((packed)); |
| 21 | 22 | ||
| 23 | #define EV_QUAL_CPU_CHANGE 1 | ||
| 22 | #define EV_QUAL_CAP_CHANGE 3 | 24 | #define EV_QUAL_CAP_CHANGE 3 |
| 23 | 25 | ||
| 24 | static struct work_struct sclp_cpu_capability_work; | 26 | static struct work_struct sclp_cpu_capability_work; |
| 27 | static struct work_struct sclp_cpu_change_work; | ||
| 25 | 28 | ||
| 26 | static void sclp_cpu_capability_notify(struct work_struct *work) | 29 | static void sclp_cpu_capability_notify(struct work_struct *work) |
| 27 | { | 30 | { |
| @@ -37,13 +40,24 @@ static void sclp_cpu_capability_notify(struct work_struct *work) | |||
| 37 | put_online_cpus(); | 40 | put_online_cpus(); |
| 38 | } | 41 | } |
| 39 | 42 | ||
| 43 | static void sclp_cpu_change_notify(struct work_struct *work) | ||
| 44 | { | ||
| 45 | smp_rescan_cpus(); | ||
| 46 | } | ||
| 47 | |||
| 40 | static void sclp_conf_receiver_fn(struct evbuf_header *evbuf) | 48 | static void sclp_conf_receiver_fn(struct evbuf_header *evbuf) |
| 41 | { | 49 | { |
| 42 | struct conf_mgm_data *cdata; | 50 | struct conf_mgm_data *cdata; |
| 43 | 51 | ||
| 44 | cdata = (struct conf_mgm_data *)(evbuf + 1); | 52 | cdata = (struct conf_mgm_data *)(evbuf + 1); |
| 45 | if (cdata->ev_qualifier == EV_QUAL_CAP_CHANGE) | 53 | switch (cdata->ev_qualifier) { |
| 54 | case EV_QUAL_CPU_CHANGE: | ||
| 55 | schedule_work(&sclp_cpu_change_work); | ||
| 56 | break; | ||
| 57 | case EV_QUAL_CAP_CHANGE: | ||
| 46 | schedule_work(&sclp_cpu_capability_work); | 58 | schedule_work(&sclp_cpu_capability_work); |
| 59 | break; | ||
| 60 | } | ||
| 47 | } | 61 | } |
| 48 | 62 | ||
| 49 | static struct sclp_register sclp_conf_register = | 63 | static struct sclp_register sclp_conf_register = |
| @@ -57,6 +71,7 @@ static int __init sclp_conf_init(void) | |||
| 57 | int rc; | 71 | int rc; |
| 58 | 72 | ||
| 59 | INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify); | 73 | INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify); |
| 74 | INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify); | ||
| 60 | 75 | ||
| 61 | rc = sclp_register(&sclp_conf_register); | 76 | rc = sclp_register(&sclp_conf_register); |
| 62 | if (rc) { | 77 | if (rc) { |
diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h index 6f3821a6a902..8376b195a1b6 100644 --- a/include/asm-s390/smp.h +++ b/include/asm-s390/smp.h | |||
| @@ -108,5 +108,11 @@ static inline void smp_send_stop(void) | |||
| 108 | #define smp_cpu_not_running(cpu) 1 | 108 | #define smp_cpu_not_running(cpu) 1 |
| 109 | #endif | 109 | #endif |
| 110 | 110 | ||
| 111 | #ifdef CONFIG_HOTPLUG_CPU | ||
| 112 | extern int smp_rescan_cpus(void); | ||
| 113 | #else | ||
| 114 | static inline int smp_rescan_cpus(void) { return 0; } | ||
| 115 | #endif | ||
| 116 | |||
| 111 | extern union save_area *zfcpdump_save_areas[NR_CPUS + 1]; | 117 | extern union save_area *zfcpdump_save_areas[NR_CPUS + 1]; |
| 112 | #endif | 118 | #endif |
