diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2007-04-27 10:01:56 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2007-04-27 10:01:46 -0400 |
commit | 2fc2d1e9ffcde78af7ab63ed640d9a4901797de2 (patch) | |
tree | 9fd8fcbf4b6882200480da1f04e30b406d1f8a57 /arch/s390 | |
parent | db77aa5f3d01fe6a6cc629dbd37936b1fdd129ba (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')
-rw-r--r-- | arch/s390/kernel/smp.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 7c0143fdf710..2c5de92958dd 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -821,19 +821,57 @@ int setup_profiling_timer(unsigned int multiplier) | |||
821 | 821 | ||
822 | static DEFINE_PER_CPU(struct cpu, cpu_devices); | 822 | static DEFINE_PER_CPU(struct cpu, cpu_devices); |
823 | 823 | ||
824 | static ssize_t show_capability(struct sys_device *dev, char *buf) | ||
825 | { | ||
826 | unsigned int capability; | ||
827 | int rc; | ||
828 | |||
829 | rc = get_cpu_capability(&capability); | ||
830 | if (rc) | ||
831 | return rc; | ||
832 | return sprintf(buf, "%u\n", capability); | ||
833 | } | ||
834 | static SYSDEV_ATTR(capability, 0444, show_capability, NULL); | ||
835 | |||
836 | static int __cpuinit smp_cpu_notify(struct notifier_block *self, | ||
837 | unsigned long action, void *hcpu) | ||
838 | { | ||
839 | unsigned int cpu = (unsigned int)(long)hcpu; | ||
840 | struct cpu *c = &per_cpu(cpu_devices, cpu); | ||
841 | struct sys_device *s = &c->sysdev; | ||
842 | |||
843 | switch (action) { | ||
844 | case CPU_ONLINE: | ||
845 | if (sysdev_create_file(s, &attr_capability)) | ||
846 | return NOTIFY_BAD; | ||
847 | break; | ||
848 | case CPU_DEAD: | ||
849 | sysdev_remove_file(s, &attr_capability); | ||
850 | break; | ||
851 | } | ||
852 | return NOTIFY_OK; | ||
853 | } | ||
854 | |||
855 | static struct notifier_block __cpuinitdata smp_cpu_nb = { | ||
856 | .notifier_call = smp_cpu_notify, | ||
857 | }; | ||
858 | |||
824 | static int __init topology_init(void) | 859 | static int __init topology_init(void) |
825 | { | 860 | { |
826 | int cpu; | 861 | int cpu; |
827 | int ret; | 862 | |
863 | register_cpu_notifier(&smp_cpu_nb); | ||
828 | 864 | ||
829 | for_each_possible_cpu(cpu) { | 865 | for_each_possible_cpu(cpu) { |
830 | struct cpu *c = &per_cpu(cpu_devices, cpu); | 866 | struct cpu *c = &per_cpu(cpu_devices, cpu); |
867 | struct sys_device *s = &c->sysdev; | ||
831 | 868 | ||
832 | c->hotpluggable = 1; | 869 | c->hotpluggable = 1; |
833 | ret = register_cpu(c, cpu); | 870 | register_cpu(c, cpu); |
834 | if (ret) | 871 | if (!cpu_online(cpu)) |
835 | printk(KERN_WARNING "topology_init: register_cpu %d " | 872 | continue; |
836 | "failed (%d)\n", cpu, ret); | 873 | s = &c->sysdev; |
874 | sysdev_create_file(s, &attr_capability); | ||
837 | } | 875 | } |
838 | return 0; | 876 | return 0; |
839 | } | 877 | } |