diff options
| -rw-r--r-- | Documentation/ABI/testing/sysfs-devices-system-cpu | 10 | ||||
| -rw-r--r-- | include/linux/cpu.h | 3 | ||||
| -rw-r--r-- | kernel/cpu.c | 64 |
3 files changed, 47 insertions, 30 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index 9605dbd4b5b5..5eea46fefcb2 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu | |||
| @@ -511,10 +511,12 @@ Description: Control Symetric Multi Threading (SMT) | |||
| 511 | control: Read/write interface to control SMT. Possible | 511 | control: Read/write interface to control SMT. Possible |
| 512 | values: | 512 | values: |
| 513 | 513 | ||
| 514 | "on" SMT is enabled | 514 | "on" SMT is enabled |
| 515 | "off" SMT is disabled | 515 | "off" SMT is disabled |
| 516 | "forceoff" SMT is force disabled. Cannot be changed. | 516 | "forceoff" SMT is force disabled. Cannot be changed. |
| 517 | "notsupported" SMT is not supported by the CPU | 517 | "notsupported" SMT is not supported by the CPU |
| 518 | "notimplemented" SMT runtime toggling is not | ||
| 519 | implemented for the architecture | ||
| 518 | 520 | ||
| 519 | If control status is "forceoff" or "notsupported" writes | 521 | If control status is "forceoff" or "notsupported" writes |
| 520 | are rejected. | 522 | are rejected. |
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 5041357d0297..ae99dde02320 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h | |||
| @@ -175,6 +175,7 @@ enum cpuhp_smt_control { | |||
| 175 | CPU_SMT_DISABLED, | 175 | CPU_SMT_DISABLED, |
| 176 | CPU_SMT_FORCE_DISABLED, | 176 | CPU_SMT_FORCE_DISABLED, |
| 177 | CPU_SMT_NOT_SUPPORTED, | 177 | CPU_SMT_NOT_SUPPORTED, |
| 178 | CPU_SMT_NOT_IMPLEMENTED, | ||
| 178 | }; | 179 | }; |
| 179 | 180 | ||
| 180 | #if defined(CONFIG_SMP) && defined(CONFIG_HOTPLUG_SMT) | 181 | #if defined(CONFIG_SMP) && defined(CONFIG_HOTPLUG_SMT) |
| @@ -182,7 +183,7 @@ extern enum cpuhp_smt_control cpu_smt_control; | |||
| 182 | extern void cpu_smt_disable(bool force); | 183 | extern void cpu_smt_disable(bool force); |
| 183 | extern void cpu_smt_check_topology(void); | 184 | extern void cpu_smt_check_topology(void); |
| 184 | #else | 185 | #else |
| 185 | # define cpu_smt_control (CPU_SMT_ENABLED) | 186 | # define cpu_smt_control (CPU_SMT_NOT_IMPLEMENTED) |
| 186 | static inline void cpu_smt_disable(bool force) { } | 187 | static inline void cpu_smt_disable(bool force) { } |
| 187 | static inline void cpu_smt_check_topology(void) { } | 188 | static inline void cpu_smt_check_topology(void) { } |
| 188 | #endif | 189 | #endif |
diff --git a/kernel/cpu.c b/kernel/cpu.c index 6754f3ecfd94..b8bf3f93e39b 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
| @@ -2033,19 +2033,6 @@ static const struct attribute_group cpuhp_cpu_root_attr_group = { | |||
| 2033 | 2033 | ||
| 2034 | #ifdef CONFIG_HOTPLUG_SMT | 2034 | #ifdef CONFIG_HOTPLUG_SMT |
| 2035 | 2035 | ||
| 2036 | static const char *smt_states[] = { | ||
| 2037 | [CPU_SMT_ENABLED] = "on", | ||
| 2038 | [CPU_SMT_DISABLED] = "off", | ||
| 2039 | [CPU_SMT_FORCE_DISABLED] = "forceoff", | ||
| 2040 | [CPU_SMT_NOT_SUPPORTED] = "notsupported", | ||
| 2041 | }; | ||
| 2042 | |||
| 2043 | static ssize_t | ||
| 2044 | show_smt_control(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 2045 | { | ||
| 2046 | return snprintf(buf, PAGE_SIZE - 2, "%s\n", smt_states[cpu_smt_control]); | ||
| 2047 | } | ||
| 2048 | |||
| 2049 | static void cpuhp_offline_cpu_device(unsigned int cpu) | 2036 | static void cpuhp_offline_cpu_device(unsigned int cpu) |
| 2050 | { | 2037 | { |
| 2051 | struct device *dev = get_cpu_device(cpu); | 2038 | struct device *dev = get_cpu_device(cpu); |
| @@ -2116,9 +2103,10 @@ static int cpuhp_smt_enable(void) | |||
| 2116 | return ret; | 2103 | return ret; |
| 2117 | } | 2104 | } |
| 2118 | 2105 | ||
| 2106 | |||
| 2119 | static ssize_t | 2107 | static ssize_t |
| 2120 | store_smt_control(struct device *dev, struct device_attribute *attr, | 2108 | __store_smt_control(struct device *dev, struct device_attribute *attr, |
| 2121 | const char *buf, size_t count) | 2109 | const char *buf, size_t count) |
| 2122 | { | 2110 | { |
| 2123 | int ctrlval, ret; | 2111 | int ctrlval, ret; |
| 2124 | 2112 | ||
| @@ -2156,14 +2144,44 @@ store_smt_control(struct device *dev, struct device_attribute *attr, | |||
| 2156 | unlock_device_hotplug(); | 2144 | unlock_device_hotplug(); |
| 2157 | return ret ? ret : count; | 2145 | return ret ? ret : count; |
| 2158 | } | 2146 | } |
| 2147 | |||
| 2148 | #else /* !CONFIG_HOTPLUG_SMT */ | ||
| 2149 | static ssize_t | ||
| 2150 | __store_smt_control(struct device *dev, struct device_attribute *attr, | ||
| 2151 | const char *buf, size_t count) | ||
| 2152 | { | ||
| 2153 | return -ENODEV; | ||
| 2154 | } | ||
| 2155 | #endif /* CONFIG_HOTPLUG_SMT */ | ||
| 2156 | |||
| 2157 | static const char *smt_states[] = { | ||
| 2158 | [CPU_SMT_ENABLED] = "on", | ||
| 2159 | [CPU_SMT_DISABLED] = "off", | ||
| 2160 | [CPU_SMT_FORCE_DISABLED] = "forceoff", | ||
| 2161 | [CPU_SMT_NOT_SUPPORTED] = "notsupported", | ||
| 2162 | [CPU_SMT_NOT_IMPLEMENTED] = "notimplemented", | ||
| 2163 | }; | ||
| 2164 | |||
| 2165 | static ssize_t | ||
| 2166 | show_smt_control(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 2167 | { | ||
| 2168 | const char *state = smt_states[cpu_smt_control]; | ||
| 2169 | |||
| 2170 | return snprintf(buf, PAGE_SIZE - 2, "%s\n", state); | ||
| 2171 | } | ||
| 2172 | |||
| 2173 | static ssize_t | ||
| 2174 | store_smt_control(struct device *dev, struct device_attribute *attr, | ||
| 2175 | const char *buf, size_t count) | ||
| 2176 | { | ||
| 2177 | return __store_smt_control(dev, attr, buf, count); | ||
| 2178 | } | ||
| 2159 | static DEVICE_ATTR(control, 0644, show_smt_control, store_smt_control); | 2179 | static DEVICE_ATTR(control, 0644, show_smt_control, store_smt_control); |
| 2160 | 2180 | ||
| 2161 | static ssize_t | 2181 | static ssize_t |
| 2162 | show_smt_active(struct device *dev, struct device_attribute *attr, char *buf) | 2182 | show_smt_active(struct device *dev, struct device_attribute *attr, char *buf) |
| 2163 | { | 2183 | { |
| 2164 | bool active = topology_max_smt_threads() > 1; | 2184 | return snprintf(buf, PAGE_SIZE - 2, "%d\n", sched_smt_active()); |
| 2165 | |||
| 2166 | return snprintf(buf, PAGE_SIZE - 2, "%d\n", active); | ||
| 2167 | } | 2185 | } |
| 2168 | static DEVICE_ATTR(active, 0444, show_smt_active, NULL); | 2186 | static DEVICE_ATTR(active, 0444, show_smt_active, NULL); |
| 2169 | 2187 | ||
| @@ -2179,21 +2197,17 @@ static const struct attribute_group cpuhp_smt_attr_group = { | |||
| 2179 | NULL | 2197 | NULL |
| 2180 | }; | 2198 | }; |
| 2181 | 2199 | ||
| 2182 | static int __init cpu_smt_state_init(void) | 2200 | static int __init cpu_smt_sysfs_init(void) |
| 2183 | { | 2201 | { |
| 2184 | return sysfs_create_group(&cpu_subsys.dev_root->kobj, | 2202 | return sysfs_create_group(&cpu_subsys.dev_root->kobj, |
| 2185 | &cpuhp_smt_attr_group); | 2203 | &cpuhp_smt_attr_group); |
| 2186 | } | 2204 | } |
| 2187 | 2205 | ||
| 2188 | #else | ||
| 2189 | static inline int cpu_smt_state_init(void) { return 0; } | ||
| 2190 | #endif | ||
| 2191 | |||
| 2192 | static int __init cpuhp_sysfs_init(void) | 2206 | static int __init cpuhp_sysfs_init(void) |
| 2193 | { | 2207 | { |
| 2194 | int cpu, ret; | 2208 | int cpu, ret; |
| 2195 | 2209 | ||
| 2196 | ret = cpu_smt_state_init(); | 2210 | ret = cpu_smt_sysfs_init(); |
| 2197 | if (ret) | 2211 | if (ret) |
| 2198 | return ret; | 2212 | return ret; |
| 2199 | 2213 | ||
| @@ -2214,7 +2228,7 @@ static int __init cpuhp_sysfs_init(void) | |||
| 2214 | return 0; | 2228 | return 0; |
| 2215 | } | 2229 | } |
| 2216 | device_initcall(cpuhp_sysfs_init); | 2230 | device_initcall(cpuhp_sysfs_init); |
| 2217 | #endif | 2231 | #endif /* CONFIG_SYSFS && CONFIG_HOTPLUG_CPU */ |
| 2218 | 2232 | ||
| 2219 | /* | 2233 | /* |
| 2220 | * cpu_bit_bitmap[] is a special, "compressed" data structure that | 2234 | * cpu_bit_bitmap[] is a special, "compressed" data structure that |
