aboutsummaryrefslogtreecommitdiff
path: root/arch/s390/kernel
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2007-04-27 16:01:56 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2007-04-27 16:01:46 +0200
commit2fc2d1e9ffcde78af7ab63ed640d9a4901797de2 (patch)
tree9fd8fcbf4b6882200480da1f04e30b406d1f8a57 /arch/s390/kernel
parentdb77aa5f3d01fe6a6cc629dbd37936b1fdd129ba (diff)
[S390] Processor degradation notification.
Generate uevents for all cpus if cpu capability changes. This can happen e.g. because the cpus are overheating. The cpu capability can be read via /sys/devices/system/cpu/cpuN/capability. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/smp.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 7c0143fdf71..2c5de92958d 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -821,19 +821,57 @@ int setup_profiling_timer(unsigned int multiplier)
static DEFINE_PER_CPU(struct cpu, cpu_devices);
+static ssize_t show_capability(struct sys_device *dev, char *buf)
+{
+ unsigned int capability;
+ int rc;
+
+ rc = get_cpu_capability(&capability);
+ if (rc)
+ return rc;
+ return sprintf(buf, "%u\n", capability);
+}
+static SYSDEV_ATTR(capability, 0444, show_capability, NULL);
+
+static int __cpuinit smp_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned int)(long)hcpu;
+ struct cpu *c = &per_cpu(cpu_devices, cpu);
+ struct sys_device *s = &c->sysdev;
+
+ switch (action) {
+ case CPU_ONLINE:
+ if (sysdev_create_file(s, &attr_capability))
+ return NOTIFY_BAD;
+ break;
+ case CPU_DEAD:
+ sysdev_remove_file(s, &attr_capability);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata smp_cpu_nb = {
+ .notifier_call = smp_cpu_notify,
+};
+
static int __init topology_init(void)
{
int cpu;
- int ret;
+
+ register_cpu_notifier(&smp_cpu_nb);
for_each_possible_cpu(cpu) {
struct cpu *c = &per_cpu(cpu_devices, cpu);
+ struct sys_device *s = &c->sysdev;
c->hotpluggable = 1;
- ret = register_cpu(c, cpu);
- if (ret)
- printk(KERN_WARNING "topology_init: register_cpu %d "
- "failed (%d)\n", cpu, ret);
+ register_cpu(c, cpu);
+ if (!cpu_online(cpu))
+ continue;
+ s = &c->sysdev;
+ sysdev_create_file(s, &attr_capability);
}
return 0;
}