diff options
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r-- | arch/s390/kernel/smp.c | 113 |
1 files changed, 22 insertions, 91 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 14d5211a185..9cf01e455e5 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -69,9 +69,7 @@ enum s390_cpu_state { | |||
69 | }; | 69 | }; |
70 | 70 | ||
71 | DEFINE_MUTEX(smp_cpu_state_mutex); | 71 | DEFINE_MUTEX(smp_cpu_state_mutex); |
72 | int smp_cpu_polarization[NR_CPUS]; | ||
73 | static int smp_cpu_state[NR_CPUS]; | 72 | static int smp_cpu_state[NR_CPUS]; |
74 | static int cpu_management; | ||
75 | 73 | ||
76 | static DEFINE_PER_CPU(struct cpu, cpu_devices); | 74 | static DEFINE_PER_CPU(struct cpu, cpu_devices); |
77 | 75 | ||
@@ -369,7 +367,7 @@ static int smp_rescan_cpus_sigp(cpumask_t avail) | |||
369 | if (cpu_known(cpu_id)) | 367 | if (cpu_known(cpu_id)) |
370 | continue; | 368 | continue; |
371 | __cpu_logical_map[logical_cpu] = cpu_id; | 369 | __cpu_logical_map[logical_cpu] = cpu_id; |
372 | smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN; | 370 | cpu_set_polarization(logical_cpu, POLARIZATION_UNKNOWN); |
373 | if (!cpu_stopped(logical_cpu)) | 371 | if (!cpu_stopped(logical_cpu)) |
374 | continue; | 372 | continue; |
375 | set_cpu_present(logical_cpu, true); | 373 | set_cpu_present(logical_cpu, true); |
@@ -403,7 +401,7 @@ static int smp_rescan_cpus_sclp(cpumask_t avail) | |||
403 | if (cpu_known(cpu_id)) | 401 | if (cpu_known(cpu_id)) |
404 | continue; | 402 | continue; |
405 | __cpu_logical_map[logical_cpu] = cpu_id; | 403 | __cpu_logical_map[logical_cpu] = cpu_id; |
406 | smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN; | 404 | cpu_set_polarization(logical_cpu, POLARIZATION_UNKNOWN); |
407 | set_cpu_present(logical_cpu, true); | 405 | set_cpu_present(logical_cpu, true); |
408 | if (cpu >= info->configured) | 406 | if (cpu >= info->configured) |
409 | smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY; | 407 | smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY; |
@@ -806,7 +804,7 @@ void __init smp_prepare_boot_cpu(void) | |||
806 | S390_lowcore.percpu_offset = __per_cpu_offset[0]; | 804 | S390_lowcore.percpu_offset = __per_cpu_offset[0]; |
807 | current_set[0] = current; | 805 | current_set[0] = current; |
808 | smp_cpu_state[0] = CPU_STATE_CONFIGURED; | 806 | smp_cpu_state[0] = CPU_STATE_CONFIGURED; |
809 | smp_cpu_polarization[0] = POLARIZATION_UNKNWN; | 807 | cpu_set_polarization(0, POLARIZATION_UNKNOWN); |
810 | } | 808 | } |
811 | 809 | ||
812 | void __init smp_cpus_done(unsigned int max_cpus) | 810 | void __init smp_cpus_done(unsigned int max_cpus) |
@@ -868,7 +866,7 @@ static ssize_t cpu_configure_store(struct sys_device *dev, | |||
868 | rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]); | 866 | rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]); |
869 | if (!rc) { | 867 | if (!rc) { |
870 | smp_cpu_state[cpu] = CPU_STATE_STANDBY; | 868 | smp_cpu_state[cpu] = CPU_STATE_STANDBY; |
871 | smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; | 869 | cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); |
872 | } | 870 | } |
873 | } | 871 | } |
874 | break; | 872 | break; |
@@ -877,7 +875,7 @@ static ssize_t cpu_configure_store(struct sys_device *dev, | |||
877 | rc = sclp_cpu_configure(__cpu_logical_map[cpu]); | 875 | rc = sclp_cpu_configure(__cpu_logical_map[cpu]); |
878 | if (!rc) { | 876 | if (!rc) { |
879 | smp_cpu_state[cpu] = CPU_STATE_CONFIGURED; | 877 | smp_cpu_state[cpu] = CPU_STATE_CONFIGURED; |
880 | smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; | 878 | cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); |
881 | } | 879 | } |
882 | } | 880 | } |
883 | break; | 881 | break; |
@@ -892,35 +890,6 @@ out: | |||
892 | static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store); | 890 | static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store); |
893 | #endif /* CONFIG_HOTPLUG_CPU */ | 891 | #endif /* CONFIG_HOTPLUG_CPU */ |
894 | 892 | ||
895 | static ssize_t cpu_polarization_show(struct sys_device *dev, | ||
896 | struct sysdev_attribute *attr, char *buf) | ||
897 | { | ||
898 | int cpu = dev->id; | ||
899 | ssize_t count; | ||
900 | |||
901 | mutex_lock(&smp_cpu_state_mutex); | ||
902 | switch (smp_cpu_polarization[cpu]) { | ||
903 | case POLARIZATION_HRZ: | ||
904 | count = sprintf(buf, "horizontal\n"); | ||
905 | break; | ||
906 | case POLARIZATION_VL: | ||
907 | count = sprintf(buf, "vertical:low\n"); | ||
908 | break; | ||
909 | case POLARIZATION_VM: | ||
910 | count = sprintf(buf, "vertical:medium\n"); | ||
911 | break; | ||
912 | case POLARIZATION_VH: | ||
913 | count = sprintf(buf, "vertical:high\n"); | ||
914 | break; | ||
915 | default: | ||
916 | count = sprintf(buf, "unknown\n"); | ||
917 | break; | ||
918 | } | ||
919 | mutex_unlock(&smp_cpu_state_mutex); | ||
920 | return count; | ||
921 | } | ||
922 | static SYSDEV_ATTR(polarization, 0444, cpu_polarization_show, NULL); | ||
923 | |||
924 | static ssize_t show_cpu_address(struct sys_device *dev, | 893 | static ssize_t show_cpu_address(struct sys_device *dev, |
925 | struct sysdev_attribute *attr, char *buf) | 894 | struct sysdev_attribute *attr, char *buf) |
926 | { | 895 | { |
@@ -928,13 +897,11 @@ static ssize_t show_cpu_address(struct sys_device *dev, | |||
928 | } | 897 | } |
929 | static SYSDEV_ATTR(address, 0444, show_cpu_address, NULL); | 898 | static SYSDEV_ATTR(address, 0444, show_cpu_address, NULL); |
930 | 899 | ||
931 | |||
932 | static struct attribute *cpu_common_attrs[] = { | 900 | static struct attribute *cpu_common_attrs[] = { |
933 | #ifdef CONFIG_HOTPLUG_CPU | 901 | #ifdef CONFIG_HOTPLUG_CPU |
934 | &attr_configure.attr, | 902 | &attr_configure.attr, |
935 | #endif | 903 | #endif |
936 | &attr_address.attr, | 904 | &attr_address.attr, |
937 | &attr_polarization.attr, | ||
938 | NULL, | 905 | NULL, |
939 | }; | 906 | }; |
940 | 907 | ||
@@ -1055,11 +1022,20 @@ static int __devinit smp_add_present_cpu(int cpu) | |||
1055 | rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group); | 1022 | rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group); |
1056 | if (rc) | 1023 | if (rc) |
1057 | goto out_cpu; | 1024 | goto out_cpu; |
1058 | if (!cpu_online(cpu)) | 1025 | if (cpu_online(cpu)) { |
1059 | goto out; | 1026 | rc = sysfs_create_group(&s->kobj, &cpu_online_attr_group); |
1060 | rc = sysfs_create_group(&s->kobj, &cpu_online_attr_group); | 1027 | if (rc) |
1061 | if (!rc) | 1028 | goto out_online; |
1062 | return 0; | 1029 | } |
1030 | rc = topology_cpu_init(c); | ||
1031 | if (rc) | ||
1032 | goto out_topology; | ||
1033 | return 0; | ||
1034 | |||
1035 | out_topology: | ||
1036 | if (cpu_online(cpu)) | ||
1037 | sysfs_remove_group(&s->kobj, &cpu_online_attr_group); | ||
1038 | out_online: | ||
1063 | sysfs_remove_group(&s->kobj, &cpu_common_attr_group); | 1039 | sysfs_remove_group(&s->kobj, &cpu_common_attr_group); |
1064 | out_cpu: | 1040 | out_cpu: |
1065 | #ifdef CONFIG_HOTPLUG_CPU | 1041 | #ifdef CONFIG_HOTPLUG_CPU |
@@ -1111,61 +1087,16 @@ static ssize_t __ref rescan_store(struct sysdev_class *class, | |||
1111 | static SYSDEV_CLASS_ATTR(rescan, 0200, NULL, rescan_store); | 1087 | static SYSDEV_CLASS_ATTR(rescan, 0200, NULL, rescan_store); |
1112 | #endif /* CONFIG_HOTPLUG_CPU */ | 1088 | #endif /* CONFIG_HOTPLUG_CPU */ |
1113 | 1089 | ||
1114 | static ssize_t dispatching_show(struct sysdev_class *class, | 1090 | static int __init s390_smp_init(void) |
1115 | struct sysdev_class_attribute *attr, | ||
1116 | char *buf) | ||
1117 | { | 1091 | { |
1118 | ssize_t count; | 1092 | int cpu, rc; |
1119 | |||
1120 | mutex_lock(&smp_cpu_state_mutex); | ||
1121 | count = sprintf(buf, "%d\n", cpu_management); | ||
1122 | mutex_unlock(&smp_cpu_state_mutex); | ||
1123 | return count; | ||
1124 | } | ||
1125 | |||
1126 | static ssize_t dispatching_store(struct sysdev_class *dev, | ||
1127 | struct sysdev_class_attribute *attr, | ||
1128 | const char *buf, | ||
1129 | size_t count) | ||
1130 | { | ||
1131 | int val, rc; | ||
1132 | char delim; | ||
1133 | |||
1134 | if (sscanf(buf, "%d %c", &val, &delim) != 1) | ||
1135 | return -EINVAL; | ||
1136 | if (val != 0 && val != 1) | ||
1137 | return -EINVAL; | ||
1138 | rc = 0; | ||
1139 | get_online_cpus(); | ||
1140 | mutex_lock(&smp_cpu_state_mutex); | ||
1141 | if (cpu_management == val) | ||
1142 | goto out; | ||
1143 | rc = topology_set_cpu_management(val); | ||
1144 | if (!rc) | ||
1145 | cpu_management = val; | ||
1146 | out: | ||
1147 | mutex_unlock(&smp_cpu_state_mutex); | ||
1148 | put_online_cpus(); | ||
1149 | return rc ? rc : count; | ||
1150 | } | ||
1151 | static SYSDEV_CLASS_ATTR(dispatching, 0644, dispatching_show, | ||
1152 | dispatching_store); | ||
1153 | |||
1154 | static int __init topology_init(void) | ||
1155 | { | ||
1156 | int cpu; | ||
1157 | int rc; | ||
1158 | 1093 | ||
1159 | register_cpu_notifier(&smp_cpu_nb); | 1094 | register_cpu_notifier(&smp_cpu_nb); |
1160 | |||
1161 | #ifdef CONFIG_HOTPLUG_CPU | 1095 | #ifdef CONFIG_HOTPLUG_CPU |
1162 | rc = sysdev_class_create_file(&cpu_sysdev_class, &attr_rescan); | 1096 | rc = sysdev_class_create_file(&cpu_sysdev_class, &attr_rescan); |
1163 | if (rc) | 1097 | if (rc) |
1164 | return rc; | 1098 | return rc; |
1165 | #endif | 1099 | #endif |
1166 | rc = sysdev_class_create_file(&cpu_sysdev_class, &attr_dispatching); | ||
1167 | if (rc) | ||
1168 | return rc; | ||
1169 | for_each_present_cpu(cpu) { | 1100 | for_each_present_cpu(cpu) { |
1170 | rc = smp_add_present_cpu(cpu); | 1101 | rc = smp_add_present_cpu(cpu); |
1171 | if (rc) | 1102 | if (rc) |
@@ -1173,4 +1104,4 @@ static int __init topology_init(void) | |||
1173 | } | 1104 | } |
1174 | return 0; | 1105 | return 0; |
1175 | } | 1106 | } |
1176 | subsys_initcall(topology_init); | 1107 | subsys_initcall(s390_smp_init); |