Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

amd-pstate: Make certain freq_attrs conditionally visible

Certain amd_pstate freq_attrs such as amd_pstate_hw_prefcore and
amd_pstate_prefcore_ranking are enabled even when preferred core is
not supported on the platform.

Similarly there are common freq_attrs between the amd-pstate and the
amd-pstate-epp drivers (eg: amd_pstate_max_freq,
amd_pstate_lowest_nonlinear_freq, etc.) but are duplicated in two
different freq_attr structs.

Unify all the attributes in a single place and associate each of them
with a visibility function that determines whether the attribute
should be visible based on the underlying platform support and the
current amd_pstate mode.

Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>

authored by

Gautham R. Shenoy and committed by
Mario Limonciello (AMD)
e67a5b65 fcc25a29

+93 -31
+93 -31
drivers/cpufreq/amd-pstate.c
··· 1220 1220 return sysfs_emit(buf, "%s\n", energy_perf_strings[preference]); 1221 1221 } 1222 1222 1223 + cpufreq_freq_attr_ro(amd_pstate_max_freq); 1224 + cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq); 1225 + 1226 + cpufreq_freq_attr_ro(amd_pstate_highest_perf); 1227 + cpufreq_freq_attr_ro(amd_pstate_prefcore_ranking); 1228 + cpufreq_freq_attr_ro(amd_pstate_hw_prefcore); 1229 + cpufreq_freq_attr_rw(energy_performance_preference); 1230 + cpufreq_freq_attr_ro(energy_performance_available_preferences); 1231 + 1232 + struct freq_attr_visibility { 1233 + struct freq_attr *attr; 1234 + bool (*visibility_fn)(void); 1235 + }; 1236 + 1237 + /* For attributes which are always visible */ 1238 + static bool always_visible(void) 1239 + { 1240 + return true; 1241 + } 1242 + 1243 + /* Determines whether prefcore related attributes should be visible */ 1244 + static bool prefcore_visibility(void) 1245 + { 1246 + return amd_pstate_prefcore; 1247 + } 1248 + 1249 + /* Determines whether energy performance preference should be visible */ 1250 + static bool epp_visibility(void) 1251 + { 1252 + return cppc_state == AMD_PSTATE_ACTIVE; 1253 + } 1254 + 1255 + static struct freq_attr_visibility amd_pstate_attr_visibility[] = { 1256 + {&amd_pstate_max_freq, always_visible}, 1257 + {&amd_pstate_lowest_nonlinear_freq, always_visible}, 1258 + {&amd_pstate_highest_perf, always_visible}, 1259 + {&amd_pstate_prefcore_ranking, prefcore_visibility}, 1260 + {&amd_pstate_hw_prefcore, prefcore_visibility}, 1261 + {&energy_performance_preference, epp_visibility}, 1262 + {&energy_performance_available_preferences, epp_visibility}, 1263 + }; 1264 + 1265 + static struct freq_attr **get_freq_attrs(void) 1266 + { 1267 + bool attr_visible[ARRAY_SIZE(amd_pstate_attr_visibility)]; 1268 + struct freq_attr **attrs; 1269 + int i, j, count; 1270 + 1271 + for (i = 0, count = 0; i < ARRAY_SIZE(amd_pstate_attr_visibility); i++) { 1272 + struct freq_attr_visibility *v = &amd_pstate_attr_visibility[i]; 1273 + 1274 + attr_visible[i] = v->visibility_fn(); 1275 + if (attr_visible[i]) 1276 + count++; 1277 + } 1278 + 1279 + /* amd_pstate_{max_freq, lowest_nonlinear_freq, highest_perf} should always be visible */ 1280 + BUG_ON(!count); 1281 + 1282 + attrs = kcalloc(count + 1, sizeof(struct freq_attr *), GFP_KERNEL); 1283 + if (!attrs) 1284 + return ERR_PTR(-ENOMEM); 1285 + 1286 + for (i = 0, j = 0; i < ARRAY_SIZE(amd_pstate_attr_visibility); i++) { 1287 + if (!attr_visible[i]) 1288 + continue; 1289 + 1290 + attrs[j++] = amd_pstate_attr_visibility[i].attr; 1291 + } 1292 + 1293 + return attrs; 1294 + } 1295 + 1223 1296 static void amd_pstate_driver_cleanup(void) 1224 1297 { 1225 1298 if (amd_pstate_prefcore) 1226 1299 sched_clear_itmt_support(); 1227 1300 1228 1301 cppc_state = AMD_PSTATE_DISABLE; 1302 + kfree(current_pstate_driver->attr); 1303 + current_pstate_driver->attr = NULL; 1229 1304 current_pstate_driver = NULL; 1230 1305 } 1231 1306 ··· 1325 1250 1326 1251 static int amd_pstate_register_driver(int mode) 1327 1252 { 1253 + struct freq_attr **attr = NULL; 1328 1254 int ret; 1329 1255 1330 1256 ret = amd_pstate_set_driver(mode); ··· 1333 1257 return ret; 1334 1258 1335 1259 cppc_state = mode; 1260 + 1261 + /* 1262 + * Note: It is important to compute the attrs _after_ 1263 + * re-initializing the cppc_state. Some attributes become 1264 + * visible only when cppc_state is AMD_PSTATE_ACTIVE. 1265 + */ 1266 + attr = get_freq_attrs(); 1267 + if (IS_ERR(attr)) { 1268 + ret = (int) PTR_ERR(attr); 1269 + pr_err("Couldn't compute freq_attrs for current mode %s [%d]\n", 1270 + amd_pstate_get_mode_string(cppc_state), ret); 1271 + amd_pstate_driver_cleanup(); 1272 + return ret; 1273 + } 1274 + 1275 + current_pstate_driver->attr = attr; 1336 1276 1337 1277 /* at least one CPU supports CPB */ 1338 1278 current_pstate_driver->boost_enabled = cpu_feature_enabled(X86_FEATURE_CPB); ··· 1491 1399 return sysfs_emit(buf, "%s\n", str_enabled_disabled(amd_pstate_prefcore)); 1492 1400 } 1493 1401 1494 - cpufreq_freq_attr_ro(amd_pstate_max_freq); 1495 - cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq); 1496 - 1497 - cpufreq_freq_attr_ro(amd_pstate_highest_perf); 1498 - cpufreq_freq_attr_ro(amd_pstate_prefcore_ranking); 1499 - cpufreq_freq_attr_ro(amd_pstate_hw_prefcore); 1500 - cpufreq_freq_attr_rw(energy_performance_preference); 1501 - cpufreq_freq_attr_ro(energy_performance_available_preferences); 1502 1402 static DEVICE_ATTR_RW(status); 1503 1403 static DEVICE_ATTR_RO(prefcore); 1504 - 1505 - static struct freq_attr *amd_pstate_attr[] = { 1506 - &amd_pstate_max_freq, 1507 - &amd_pstate_lowest_nonlinear_freq, 1508 - &amd_pstate_highest_perf, 1509 - &amd_pstate_prefcore_ranking, 1510 - &amd_pstate_hw_prefcore, 1511 - NULL, 1512 - }; 1513 - 1514 - static struct freq_attr *amd_pstate_epp_attr[] = { 1515 - &amd_pstate_max_freq, 1516 - &amd_pstate_lowest_nonlinear_freq, 1517 - &amd_pstate_highest_perf, 1518 - &amd_pstate_prefcore_ranking, 1519 - &amd_pstate_hw_prefcore, 1520 - &energy_performance_preference, 1521 - &energy_performance_available_preferences, 1522 - NULL, 1523 - }; 1524 1404 1525 1405 static struct attribute *pstate_global_attributes[] = { 1526 1406 &dev_attr_status.attr, ··· 1760 1696 .set_boost = amd_pstate_set_boost, 1761 1697 .update_limits = amd_pstate_update_limits, 1762 1698 .name = "amd-pstate", 1763 - .attr = amd_pstate_attr, 1764 1699 }; 1765 1700 1766 1701 static struct cpufreq_driver amd_pstate_epp_driver = { ··· 1775 1712 .update_limits = amd_pstate_update_limits, 1776 1713 .set_boost = amd_pstate_set_boost, 1777 1714 .name = "amd-pstate-epp", 1778 - .attr = amd_pstate_epp_attr, 1779 1715 }; 1780 1716 1781 1717 /* ··· 1920 1858 return ret; 1921 1859 1922 1860 global_attr_free: 1923 - cpufreq_unregister_driver(current_pstate_driver); 1861 + amd_pstate_unregister_driver(0); 1924 1862 return ret; 1925 1863 } 1926 1864 device_initcall(amd_pstate_init);