From abd120e3bdf3dd72ba1ed9ac077a861e0e3dc43a Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 10 Oct 2019 13:29:36 -0700 Subject: tools/power/x86/intel-speed-select: Remove warning for unused result MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix warning for: isst-config.c: In function ‘set_cpu_online_offline’: isst-config.c:221:3: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Wunused-result] write(fd, "1\n", 2); Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 2a9890c8395a..21fcfe621d3a 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -169,7 +169,7 @@ int get_topo_max_cpus(void) static void set_cpu_online_offline(int cpu, int state) { char buffer[128]; - int fd; + int fd, ret; snprintf(buffer, sizeof(buffer), "/sys/devices/system/cpu/cpu%d/online", cpu); @@ -179,9 +179,12 @@ static void set_cpu_online_offline(int cpu, int state) err(-1, "%s open failed", buffer); if (state) - write(fd, "1\n", 2); + ret = write(fd, "1\n", 2); else - write(fd, "0\n", 2); + ret = write(fd, "0\n", 2); + + if (ret == -1) + perror("Online/Offline: Operation failed\n"); close(fd); } -- cgit From 354bd06f40c4ba7b2f12d9f0f119dff62a2f922f Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 10 Oct 2019 13:29:37 -0700 Subject: tools/power/x86/intel-speed-select: Base-freq feature auto mode Introduce --auto|-a option to base-freq enable feature, so that it does in one step for users who are OK by setting all cores with higher base frequency to be set in CLOS 0 and remaining in CLOS 3. This option also sets corresponding clos.min to CLOS 0 and CLOS3. In this way, users don't have to take multiple steps to enable base-freq feature. For users who want more fine grain control, they can always use core-power feature to set custom CLOS configuration and assignment. Also adjust cpufreq/scaling_min_freq for higher and lower priority cores. For example user can use: intel-speed-select base-freq enable --auto Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 232 ++++++++++++++++++++++- 1 file changed, 223 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 21fcfe621d3a..82502a38446e 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -39,6 +39,7 @@ static unsigned long long fact_trl; static int out_format_json; static int cmd_help; static int force_online_offline; +static int auto_mode; /* clos related */ static int current_clos = -1; @@ -855,23 +856,227 @@ static void dump_pbf_config(void) isst_ctdp_display_information_end(outf); } +static int set_clos_param(int cpu, int clos, int epp, int wt, int min, int max) +{ + struct isst_clos_config clos_config; + int ret; + + ret = isst_pm_get_clos(cpu, clos, &clos_config); + if (ret) { + perror("isst_pm_get_clos"); + return ret; + } + clos_config.clos_min = min; + clos_config.clos_max = max; + clos_config.epp = epp; + clos_config.clos_prop_prio = wt; + ret = isst_set_clos(cpu, clos, &clos_config); + if (ret) { + perror("isst_pm_set_clos"); + return ret; + } + + return 0; +} + +static int set_cpufreq_cpuinfo_scaling_min(int cpu, int max) +{ + char buffer[128], min_freq[16]; + int fd, ret, len; + + if (!CPU_ISSET_S(cpu, present_cpumask_size, present_cpumask)) + return -1; + + if (max) + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", cpu); + else + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_min_freq", cpu); + + fd = open(buffer, O_RDONLY); + if (fd < 0) + return fd; + + len = read(fd, min_freq, sizeof(min_freq)); + close(fd); + + if (len < 0) + return len; + + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); + + fd = open(buffer, O_WRONLY); + if (fd < 0) + return fd; + + len = strlen(min_freq); + ret = write(fd, min_freq, len); + if (ret == -1) { + close(fd); + return ret; + } + close(fd); + + return 0; +} + +static void set_scaling_min_to_cpuinfo_max(int cpu) +{ + int i, pkg_id, die_id; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + for (i = 0; i < get_topo_max_cpus(); ++i) { + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + set_cpufreq_cpuinfo_scaling_min(i, 1); + } +} + +static void set_scaling_min_to_cpuinfo_min(int cpu) +{ + int i, pkg_id, die_id; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + for (i = 0; i < get_topo_max_cpus(); ++i) { + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + set_cpufreq_cpuinfo_scaling_min(i, 0); + } +} + +static int set_core_priority_and_min(int cpu, int mask_size, + cpu_set_t *cpu_mask, int min_high, + int min_low) +{ + int pkg_id, die_id, ret, i; + + if (!CPU_COUNT_S(mask_size, cpu_mask)) + return -1; + + ret = set_clos_param(cpu, 0, 0, 0, min_high, 0xff); + if (ret) + return ret; + + ret = set_clos_param(cpu, 1, 15, 0, min_low, 0xff); + if (ret) + return ret; + + ret = set_clos_param(cpu, 2, 15, 0, min_low, 0xff); + if (ret) + return ret; + + ret = set_clos_param(cpu, 3, 15, 0, min_low, 0xff); + if (ret) + return ret; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + for (i = 0; i < get_topo_max_cpus(); ++i) { + int clos; + + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + if (CPU_ISSET_S(i, mask_size, cpu_mask)) + clos = 0; + else + clos = 3; + + debug_printf("Associate cpu: %d clos: %d\n", i, clos); + ret = isst_clos_associate(i, clos); + if (ret) { + perror("isst_clos_associate"); + return ret; + } + } + + return 0; +} + +static int set_pbf_core_power(int cpu) +{ + struct isst_pbf_info pbf_info; + struct isst_pkg_ctdp pkg_dev; + int ret; + + ret = isst_get_ctdp_levels(cpu, &pkg_dev); + if (ret) { + perror("isst_get_ctdp_levels"); + return ret; + } + debug_printf("Current_level: %d\n", pkg_dev.current_level); + + ret = isst_get_pbf_info(cpu, pkg_dev.current_level, &pbf_info); + if (ret) { + perror("isst_get_pbf_info"); + return ret; + } + debug_printf("p1_high: %d p1_low: %d\n", pbf_info.p1_high, + pbf_info.p1_low); + + ret = set_core_priority_and_min(cpu, pbf_info.core_cpumask_size, + pbf_info.core_cpumask, + pbf_info.p1_high, pbf_info.p1_low); + if (ret) { + perror("set_core_priority_and_min"); + return ret; + } + + ret = isst_pm_qos_config(cpu, 1, 1); + if (ret) { + perror("isst_pm_qos_config"); + return ret; + } + + return 0; +} + static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, void *arg4) { int ret; int status = *(int *)arg4; + if (auto_mode) { + if (status) { + ret = set_pbf_core_power(cpu); + if (ret) + goto disp_result; + } else { + isst_pm_qos_config(cpu, 0, 0); + } + } + ret = isst_set_pbf_fact_status(cpu, 1, status); if (ret) { perror("isst_set_pbf"); + if (auto_mode) + isst_pm_qos_config(cpu, 0, 0); } else { - if (status) - isst_display_result(cpu, outf, "base-freq", "enable", - ret); - else - isst_display_result(cpu, outf, "base-freq", "disable", - ret); + if (auto_mode) { + if (status) + set_scaling_min_to_cpuinfo_max(cpu); + else + set_scaling_min_to_cpuinfo_min(cpu); + } } + +disp_result: + if (status) + isst_display_result(cpu, outf, "base-freq", "enable", + ret); + else + isst_display_result(cpu, outf, "base-freq", "disable", + ret); } static void set_pbf_enable(void) @@ -880,7 +1085,10 @@ static void set_pbf_enable(void) if (cmd_help) { fprintf(stderr, - "Enable Intel Speed Select Technology base frequency feature [No command arguments are required]\n"); + "Enable Intel Speed Select Technology base frequency feature\n"); + fprintf(stderr, + "\tOptional Arguments: -a|--auto : Use priority of cores to set core-power associations\n"); + exit(0); } @@ -900,7 +1108,9 @@ static void set_pbf_disable(void) if (cmd_help) { fprintf(stderr, - "Disable Intel Speed Select Technology base frequency feature [No command arguments are required]\n"); + "Disable Intel Speed Select Technology base frequency feature\n"); + fprintf(stderr, + "\tOptional Arguments: -a|--auto : Also disable core-power associations\n"); exit(0); } @@ -1420,15 +1630,19 @@ static void parse_cmd_args(int argc, int start, char **argv) { "max", required_argument, 0, 'm' }, { "priority", required_argument, 0, 'p' }, { "weight", required_argument, 0, 'w' }, + { "auto", no_argument, 0, 'a' }, { 0, 0, 0, 0 } }; option_index = start; optind = start + 1; - while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:ho", + while ((opt = getopt_long(argc, argv, "b:l:t:c:d:e:n:m:p:w:hoa", long_options, &option_index)) != -1) { switch (opt) { + case 'a': + auto_mode = 1; + break; case 'b': fact_bucket = atoi(optarg); break; -- cgit From a6a82f9bcd2ad3fab5f20fc406727dc62775db92 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 10 Oct 2019 13:29:38 -0700 Subject: tools/power/x86/intel-speed-select: Turbo-freq feature auto mode Introduce --auto|-a option to turbo-freq enable feature, so that it does in one step for users who are OK by setting all passed target cores as high priority and set in CLOS 0 and remaining in CLOS 3. In this way, users don't have to take multiple steps to enable turbo-freq feature. For users who want more fine grain control, they can always use core-power feature to set custom CLOS configuration and assignment. While here also print the error to output when clos configuration fails. For example intel-speed-select -c 0-4 turbo-freq enable --auto The above command will enable turbo-freq and core-power feature. Also mark CPU 0 to CPU 4 as high priority. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 152 ++++++++++++++++++----- 1 file changed, 124 insertions(+), 28 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 82502a38446e..e1ca7c5b8037 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1173,40 +1173,58 @@ static void set_fact_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, int ret; int status = *(int *)arg4; + if (auto_mode) { + if (status) { + ret = isst_pm_qos_config(cpu, 1, 1); + if (ret) + goto disp_results; + } else { + isst_pm_qos_config(cpu, 0, 0); + } + } + ret = isst_set_pbf_fact_status(cpu, 0, status); - if (ret) + if (ret) { perror("isst_set_fact"); - else { - if (status) { - struct isst_pkg_ctdp pkg_dev; + if (auto_mode) + isst_pm_qos_config(cpu, 0, 0); - ret = isst_get_ctdp_levels(cpu, &pkg_dev); - if (ret) { - isst_display_result(cpu, outf, "turbo-freq", - "enable", ret); - return; - } + goto disp_results; + } + + /* Set TRL */ + if (status) { + struct isst_pkg_ctdp pkg_dev; + + ret = isst_get_ctdp_levels(cpu, &pkg_dev); + if (!ret) ret = isst_set_trl(cpu, fact_trl); - isst_display_result(cpu, outf, "turbo-freq", "enable", - ret); - } else { - /* Since we modified TRL during Fact enable, restore it */ - isst_set_trl_from_current_tdp(cpu, fact_trl); - isst_display_result(cpu, outf, "turbo-freq", "disable", - ret); - } + if (ret && auto_mode) + isst_pm_qos_config(cpu, 0, 0); + } + +disp_results: + if (status) { + isst_display_result(cpu, outf, "turbo-freq", "enable", ret); + } else { + /* Since we modified TRL during Fact enable, restore it */ + isst_set_trl_from_current_tdp(cpu, fact_trl); + isst_display_result(cpu, outf, "turbo-freq", "disable", ret); } } static void set_fact_enable(void) { - int status = 1; + int status = 1, i, ret; if (cmd_help) { fprintf(stderr, "Enable Intel Speed Select Technology Turbo frequency feature\n"); fprintf(stderr, "Optional: -t|--trl : Specify turbo ratio limit\n"); + fprintf(stderr, + "\tOptional Arguments: -a|--auto : Designate specified target CPUs with"); + fprintf(stderr, "-C|--cpu option as as high priority using core-power feature\n"); exit(0); } @@ -1218,6 +1236,83 @@ static void set_fact_enable(void) for_each_online_package_in_set(set_fact_for_cpu, NULL, NULL, NULL, &status); isst_ctdp_display_information_end(outf); + + if (auto_mode) { + /* + * When we adjust CLOS param, we have to set for siblings also. + * So for the each user specified CPU, also add the sibling + * in the present_cpu_mask. + */ + for (i = 0; i < get_topo_max_cpus(); ++i) { + char buffer[128], sibling_list[128], *cpu_str; + int fd, len; + + if (!CPU_ISSET_S(i, target_cpumask_size, target_cpumask)) + continue; + + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", i); + + fd = open(buffer, O_RDONLY); + if (fd < 0) + continue; + + len = read(fd, sibling_list, sizeof(sibling_list)); + close(fd); + + if (len < 0) + continue; + + cpu_str = strtok(sibling_list, ","); + while (cpu_str != NULL) { + int cpu; + + sscanf(cpu_str, "%d", &cpu); + CPU_SET_S(cpu, target_cpumask_size, target_cpumask); + cpu_str = strtok(NULL, ","); + } + } + + for (i = 0; i < get_topo_max_cpus(); ++i) { + int clos; + + if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) + continue; + + ret = set_clos_param(i, 0, 0, 0, 0, 0xff); + if (ret) + goto error_disp; + + ret = set_clos_param(i, 1, 15, 0, 0, 0xff); + if (ret) + goto error_disp; + + ret = set_clos_param(i, 2, 15, 0, 0, 0xff); + if (ret) + goto error_disp; + + ret = set_clos_param(i, 3, 15, 0, 0, 0xff); + if (ret) + goto error_disp; + + if (CPU_ISSET_S(i, target_cpumask_size, target_cpumask)) + clos = 0; + else + clos = 3; + + debug_printf("Associate cpu: %d clos: %d\n", i, clos); + ret = isst_clos_associate(i, clos); + if (ret) + goto error_disp; + } + isst_display_result(i, outf, "turbo-freq --auto", "enable", 0); + } + + return; + +error_disp: + isst_display_result(i, outf, "turbo-freq --auto", "enable", ret); + } static void set_fact_disable(void) @@ -1229,6 +1324,8 @@ static void set_fact_disable(void) "Disable Intel Speed Select Technology turbo frequency feature\n"); fprintf(stderr, "Optional: -t|--trl : Specify turbo ratio limit\n"); + fprintf(stderr, + "\tOptional Arguments: -a|--auto : Also disable core-power associations\n"); exit(0); } @@ -1249,16 +1346,15 @@ static void enable_clos_qos_config(int cpu, void *arg1, void *arg2, void *arg3, int status = *(int *)arg4; ret = isst_pm_qos_config(cpu, status, clos_priority_type); - if (ret) { + if (ret) perror("isst_pm_qos_config"); - } else { - if (status) - isst_display_result(cpu, outf, "core-power", "enable", - ret); - else - isst_display_result(cpu, outf, "core-power", "disable", - ret); - } + + if (status) + isst_display_result(cpu, outf, "core-power", "enable", + ret); + else + isst_display_result(cpu, outf, "core-power", "disable", + ret); } static void set_clos_enable(void) -- cgit From 4e26fabfe15ca67125f1b6984671c2e9048d64a5 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 10 Oct 2019 13:29:39 -0700 Subject: tools/power/x86/intel-speed-select: Refuse to disable core-power when getting used The turbo-freq feature is dependent on the core-power feature. If the core-power feature is disabled while the turbo-freq feature is enabled, this will break the turbo-freq feature. This is a firmware limitation, where they can't return error under this scenario. So when trying to disable core-power, make sure that the turbo-freq feature is not enabled. If it enabled, return error if user is trying to disable the core-power feature. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-core.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 6dee5332c9d3..67d32f2b9bea 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -649,6 +649,27 @@ int isst_pm_qos_config(int cpu, int enable_clos, int priority_type) unsigned int req, resp; int ret; + if (!enable_clos) { + struct isst_pkg_ctdp pkg_dev; + struct isst_pkg_ctdp_level_info ctdp_level; + + ret = isst_get_ctdp_levels(cpu, &pkg_dev); + if (ret) { + debug_printf("isst_get_ctdp_levels\n"); + return ret; + } + + ret = isst_get_ctdp_control(cpu, pkg_dev.current_level, + &ctdp_level); + if (ret) + return ret; + + if (ctdp_level.fact_enabled) { + debug_printf("Turbo-freq feature must be disabled first\n"); + return -EINVAL; + } + } + ret = isst_send_mbox_command(cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, &resp); if (ret) -- cgit From ce1326a2f9f7bf8920bc7f07e7b13ce8737b4681 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 10 Oct 2019 13:29:40 -0700 Subject: tools/power/x86/intel-speed-select: Add int argument to command functions The current code structure has similar but separate command functions for the enable and disable operations. This can be improved by adding an int argument to the command function structure, and interpreting 1 as enable and 0 as disable. This change results in the removal of the disable command functions. Add int argument to the command function structure. Signed-off-by: Prarit Bhargava Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 213 +++++++++-------------- 1 file changed, 86 insertions(+), 127 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index e1ca7c5b8037..4927aebee306 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -11,7 +11,8 @@ struct process_cmd_struct { char *feature; char *command; - void (*process_fn)(void); + void (*process_fn)(int arg); + int arg; }; static const char *version_str = "v1.0"; @@ -682,7 +683,7 @@ static void exec_on_get_ctdp_cpu(int cpu, void *arg1, void *arg2, void *arg3, } #define _get_tdp_level(desc, suffix, object, help) \ - static void get_tdp_##object(void) \ + static void get_tdp_##object(int arg) \ { \ struct isst_pkg_ctdp ctdp; \ \ @@ -728,7 +729,7 @@ static void dump_isst_config_for_cpu(int cpu, void *arg1, void *arg2, } } -static void dump_isst_config(void) +static void dump_isst_config(int arg) { if (cmd_help) { fprintf(stderr, @@ -791,7 +792,7 @@ static void set_tdp_level_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, } } -static void set_tdp_level(void) +static void set_tdp_level(int arg) { if (cmd_help) { fprintf(stderr, "Set Config TDP level\n"); @@ -831,7 +832,7 @@ static void dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, } } -static void dump_pbf_config(void) +static void dump_pbf_config(int arg) { if (cmd_help) { fprintf(stderr, @@ -1079,48 +1080,33 @@ disp_result: ret); } -static void set_pbf_enable(void) +static void set_pbf_enable(int arg) { - int status = 1; + int enable = arg; if (cmd_help) { - fprintf(stderr, - "Enable Intel Speed Select Technology base frequency feature\n"); - fprintf(stderr, - "\tOptional Arguments: -a|--auto : Use priority of cores to set core-power associations\n"); - - exit(0); - } - - isst_ctdp_display_information_start(outf); - if (max_target_cpus) - for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL, - NULL, &status); - else - for_each_online_package_in_set(set_pbf_for_cpu, NULL, NULL, - NULL, &status); - isst_ctdp_display_information_end(outf); -} - -static void set_pbf_disable(void) -{ - int status = 0; + if (enable) { + fprintf(stderr, + "Enable Intel Speed Select Technology base frequency feature\n"); + fprintf(stderr, + "\tOptional Arguments: -a|--auto : Use priority of cores to set core-power associations\n"); + } else { - if (cmd_help) { - fprintf(stderr, - "Disable Intel Speed Select Technology base frequency feature\n"); - fprintf(stderr, - "\tOptional Arguments: -a|--auto : Also disable core-power associations\n"); + fprintf(stderr, + "Disable Intel Speed Select Technology base frequency feature\n"); + fprintf(stderr, + "\tOptional Arguments: -a|--auto : Also disable core-power associations\n"); + } exit(0); } isst_ctdp_display_information_start(outf); if (max_target_cpus) for_each_online_target_cpu_in_set(set_pbf_for_cpu, NULL, NULL, - NULL, &status); + NULL, &enable); else for_each_online_package_in_set(set_pbf_for_cpu, NULL, NULL, - NULL, &status); + NULL, &enable); isst_ctdp_display_information_end(outf); } @@ -1138,7 +1124,7 @@ static void dump_fact_config_for_cpu(int cpu, void *arg1, void *arg2, fact_avx, &fact_info); } -static void dump_fact_config(void) +static void dump_fact_config(int arg) { if (cmd_help) { fprintf(stderr, @@ -1213,31 +1199,41 @@ disp_results: } } -static void set_fact_enable(void) +static void set_fact_enable(int arg) { - int status = 1, i, ret; + int i, ret, enable = arg; if (cmd_help) { - fprintf(stderr, - "Enable Intel Speed Select Technology Turbo frequency feature\n"); - fprintf(stderr, - "Optional: -t|--trl : Specify turbo ratio limit\n"); - fprintf(stderr, - "\tOptional Arguments: -a|--auto : Designate specified target CPUs with"); - fprintf(stderr, "-C|--cpu option as as high priority using core-power feature\n"); + if (enable) { + fprintf(stderr, + "Enable Intel Speed Select Technology Turbo frequency feature\n"); + fprintf(stderr, + "Optional: -t|--trl : Specify turbo ratio limit\n"); + fprintf(stderr, + "\tOptional Arguments: -a|--auto : Designate specified target CPUs with"); + fprintf(stderr, + "-C|--cpu option as as high priority using core-power feature\n"); + } else { + fprintf(stderr, + "Disable Intel Speed Select Technology turbo frequency feature\n"); + fprintf(stderr, + "Optional: -t|--trl : Specify turbo ratio limit\n"); + fprintf(stderr, + "\tOptional Arguments: -a|--auto : Also disable core-power associations\n"); + } exit(0); } isst_ctdp_display_information_start(outf); if (max_target_cpus) for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL, - NULL, &status); + NULL, &enable); else for_each_online_package_in_set(set_fact_for_cpu, NULL, NULL, - NULL, &status); + NULL, &enable); isst_ctdp_display_information_end(outf); - if (auto_mode) { + if (enable && auto_mode) { /* * When we adjust CLOS param, we have to set for siblings also. * So for the each user specified CPU, also add the sibling @@ -1315,30 +1311,6 @@ error_disp: } -static void set_fact_disable(void) -{ - int status = 0; - - if (cmd_help) { - fprintf(stderr, - "Disable Intel Speed Select Technology turbo frequency feature\n"); - fprintf(stderr, - "Optional: -t|--trl : Specify turbo ratio limit\n"); - fprintf(stderr, - "\tOptional Arguments: -a|--auto : Also disable core-power associations\n"); - exit(0); - } - - isst_ctdp_display_information_start(outf); - if (max_target_cpus) - for_each_online_target_cpu_in_set(set_fact_for_cpu, NULL, NULL, - NULL, &status); - else - for_each_online_package_in_set(set_fact_for_cpu, NULL, NULL, - NULL, &status); - isst_ctdp_display_information_end(outf); -} - static void enable_clos_qos_config(int cpu, void *arg1, void *arg2, void *arg3, void *arg4) { @@ -1357,19 +1329,25 @@ static void enable_clos_qos_config(int cpu, void *arg1, void *arg2, void *arg3, ret); } -static void set_clos_enable(void) +static void set_clos_enable(int arg) { - int status = 1; + int enable = arg; if (cmd_help) { - fprintf(stderr, "Enable core-power for a package/die\n"); - fprintf(stderr, - "\tClos Enable: Specify priority type with [--priority|-p]\n"); - fprintf(stderr, "\t\t 0: Proportional, 1: Ordered\n"); + if (enable) { + fprintf(stderr, + "Enable core-power for a package/die\n"); + fprintf(stderr, + "\tClos Enable: Specify priority type with [--priority|-p]\n"); + fprintf(stderr, "\t\t 0: Proportional, 1: Ordered\n"); + } else { + fprintf(stderr, + "Disable core-power: [No command arguments are required]\n"); + } exit(0); } - if (cpufreq_sysfs_present()) { + if (enable && cpufreq_sysfs_present()) { fprintf(stderr, "cpufreq subsystem and core-power enable will interfere with each other!\n"); } @@ -1377,30 +1355,10 @@ static void set_clos_enable(void) isst_ctdp_display_information_start(outf); if (max_target_cpus) for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL, - NULL, NULL, &status); - else - for_each_online_package_in_set(enable_clos_qos_config, NULL, - NULL, NULL, &status); - isst_ctdp_display_information_end(outf); -} - -static void set_clos_disable(void) -{ - int status = 0; - - if (cmd_help) { - fprintf(stderr, - "Disable core-power: [No command arguments are required]\n"); - exit(0); - } - - isst_ctdp_display_information_start(outf); - if (max_target_cpus) - for_each_online_target_cpu_in_set(enable_clos_qos_config, NULL, - NULL, NULL, &status); + NULL, NULL, &enable); else for_each_online_package_in_set(enable_clos_qos_config, NULL, - NULL, NULL, &status); + NULL, NULL, &enable); isst_ctdp_display_information_end(outf); } @@ -1418,7 +1376,7 @@ static void dump_clos_config_for_cpu(int cpu, void *arg1, void *arg2, &clos_config); } -static void dump_clos_config(void) +static void dump_clos_config(int arg) { if (cmd_help) { fprintf(stderr, @@ -1454,7 +1412,7 @@ static void get_clos_info_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, isst_clos_display_clos_information(cpu, outf, enable, prio_type); } -static void dump_clos_info(void) +static void dump_clos_info(int arg) { if (cmd_help) { fprintf(stderr, @@ -1497,7 +1455,7 @@ static void set_clos_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, isst_display_result(cpu, outf, "core-power", "config", ret); } -static void set_clos_config(void) +static void set_clos_config(int arg) { if (cmd_help) { fprintf(stderr, @@ -1561,7 +1519,7 @@ static void set_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, isst_display_result(cpu, outf, "core-power", "assoc", ret); } -static void set_clos_assoc(void) +static void set_clos_assoc(int arg) { if (cmd_help) { fprintf(stderr, "Associate a clos id to a CPU\n"); @@ -1595,7 +1553,7 @@ static void get_clos_assoc_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, isst_clos_display_assoc_information(cpu, outf, clos); } -static void get_clos_assoc(void) +static void get_clos_assoc(int arg) { if (cmd_help) { fprintf(stderr, "Get associate clos id to a CPU\n"); @@ -1616,26 +1574,27 @@ static void get_clos_assoc(void) } static struct process_cmd_struct isst_cmds[] = { - { "perf-profile", "get-lock-status", get_tdp_locked }, - { "perf-profile", "get-config-levels", get_tdp_levels }, - { "perf-profile", "get-config-version", get_tdp_version }, - { "perf-profile", "get-config-enabled", get_tdp_enabled }, - { "perf-profile", "get-config-current-level", get_tdp_current_level }, - { "perf-profile", "set-config-level", set_tdp_level }, - { "perf-profile", "info", dump_isst_config }, - { "base-freq", "info", dump_pbf_config }, - { "base-freq", "enable", set_pbf_enable }, - { "base-freq", "disable", set_pbf_disable }, - { "turbo-freq", "info", dump_fact_config }, - { "turbo-freq", "enable", set_fact_enable }, - { "turbo-freq", "disable", set_fact_disable }, - { "core-power", "info", dump_clos_info }, - { "core-power", "enable", set_clos_enable }, - { "core-power", "disable", set_clos_disable }, - { "core-power", "config", set_clos_config }, - { "core-power", "get-config", dump_clos_config }, - { "core-power", "assoc", set_clos_assoc }, - { "core-power", "get-assoc", get_clos_assoc }, + { "perf-profile", "get-lock-status", get_tdp_locked, 0 }, + { "perf-profile", "get-config-levels", get_tdp_levels, 0 }, + { "perf-profile", "get-config-version", get_tdp_version, 0 }, + { "perf-profile", "get-config-enabled", get_tdp_enabled, 0 }, + { "perf-profile", "get-config-current-level", get_tdp_current_level, + 0 }, + { "perf-profile", "set-config-level", set_tdp_level, 0 }, + { "perf-profile", "info", dump_isst_config, 0 }, + { "base-freq", "info", dump_pbf_config, 0 }, + { "base-freq", "enable", set_pbf_enable, 1 }, + { "base-freq", "disable", set_pbf_enable, 0 }, + { "turbo-freq", "info", dump_fact_config, 0 }, + { "turbo-freq", "enable", set_fact_enable, 1 }, + { "turbo-freq", "disable", set_fact_enable, 0 }, + { "core-power", "info", dump_clos_info, 0 }, + { "core-power", "enable", set_clos_enable, 1 }, + { "core-power", "disable", set_clos_enable, 0 }, + { "core-power", "config", set_clos_config, 0 }, + { "core-power", "get-config", dump_clos_config, 0 }, + { "core-power", "assoc", set_clos_assoc, 0 }, + { "core-power", "get-assoc", get_clos_assoc, 0 }, { NULL, NULL, NULL } }; @@ -1884,7 +1843,7 @@ void process_command(int argc, char **argv) if (!strcmp(isst_cmds[i].feature, feature) && !strcmp(isst_cmds[i].command, cmd)) { parse_cmd_args(argc, optind + 1, argv); - isst_cmds[i].process_fn(); + isst_cmds[i].process_fn(isst_cmds[i].arg); matched = 1; break; } -- cgit From 210369dc73b23fab1b9727fba35c2f83d00b6277 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 10 Oct 2019 13:29:41 -0700 Subject: tools/power/x86/intel-speed-select: Make process_command generic Make the process_command take any help command and command list. This will make it easier to help commands and a command list for CascadeLake-N. Signed-off-by: Prarit Bhargava Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 4927aebee306..907b79e16c68 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1816,7 +1816,9 @@ static struct process_cmd_help_struct isst_help_cmds[] = { { NULL, NULL } }; -void process_command(int argc, char **argv) +void process_command(int argc, char **argv, + struct process_cmd_help_struct *help_cmds, + struct process_cmd_struct *cmds) { int i = 0, matched = 0; char *feature = argv[optind]; @@ -1827,9 +1829,9 @@ void process_command(int argc, char **argv) debug_printf("feature name [%s] command [%s]\n", feature, cmd); if (!strcmp(cmd, "-h") || !strcmp(cmd, "--help")) { - while (isst_help_cmds[i].feature) { - if (!strcmp(isst_help_cmds[i].feature, feature)) { - isst_help_cmds[i].process_fn(); + while (help_cmds[i].feature) { + if (!strcmp(help_cmds[i].feature, feature)) { + help_cmds[i].process_fn(); exit(0); } ++i; @@ -1839,11 +1841,11 @@ void process_command(int argc, char **argv) create_cpu_map(); i = 0; - while (isst_cmds[i].feature) { - if (!strcmp(isst_cmds[i].feature, feature) && - !strcmp(isst_cmds[i].command, cmd)) { + while (cmds[i].feature) { + if (!strcmp(cmds[i].feature, feature) && + !strcmp(cmds[i].command, cmd)) { parse_cmd_args(argc, optind + 1, argv); - isst_cmds[i].process_fn(isst_cmds[i].arg); + cmds[i].process_fn(cmds[i].arg); matched = 1; break; } @@ -1964,7 +1966,7 @@ static void cmdline(int argc, char **argv) if (ret) goto out; - process_command(argc, argv); + process_command(argc, argv, isst_help_cmds, isst_cmds); out: free_cpu_set(present_cpumask); free_cpu_set(target_cpumask); -- cgit From 1c1d935c8418a63d110b2b31c57ba3d75f94f49d Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 10 Oct 2019 13:29:42 -0700 Subject: tools/power/x86/intel-speed-select: Add check for CascadeLake-N models Three CascadeLake-N models (6252N, 6230N, and 5218N) have SST-PBF support. Return an error if the CascadeLake processor is not one of these specific models. Signed-off-by: Prarit Bhargava Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 43 ++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 907b79e16c68..67a866e2dac4 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -23,6 +23,7 @@ static int debug_flag; static FILE *outf; static int cpu_model; +static int cpu_stepping; #define MAX_CPUS_IN_ONE_REQ 64 static short max_target_cpus; @@ -72,7 +73,16 @@ void debug_printf(const char *format, ...) va_end(args); } -static void update_cpu_model(void) + +int is_clx_n_platform(void) +{ + if (cpu_model == 0x55) + if (cpu_stepping == 0x6 || cpu_stepping == 0x7) + return 1; + return 0; +} + +static int update_cpu_model(void) { unsigned int ebx, ecx, edx; unsigned int fms, family; @@ -82,6 +92,33 @@ static void update_cpu_model(void) cpu_model = (fms >> 4) & 0xf; if (family == 6 || family == 0xf) cpu_model += ((fms >> 16) & 0xf) << 4; + + cpu_stepping = fms & 0xf; + /* only three CascadeLake-N models are supported */ + if (is_clx_n_platform()) { + FILE *fp; + size_t n = 0; + char *line = NULL; + int ret = 1; + + fp = fopen("/proc/cpuinfo", "r"); + if (!fp) + err(-1, "cannot open /proc/cpuinfo\n"); + + while (getline(&line, &n, fp) > 0) { + if (strstr(line, "model name")) { + if (strstr(line, "6252N") || + strstr(line, "6230N") || + strstr(line, "5218N")) + ret = 0; + break; + } + } + free(line); + fclose(fp); + return ret; + } + return 0; } /* Open a file, and exit on failure */ @@ -1956,7 +1993,9 @@ static void cmdline(int argc, char **argv) fprintf(stderr, "Feature name and|or command not specified\n"); exit(0); } - update_cpu_model(); + ret = update_cpu_model(); + if (ret) + err(-1, "Invalid CPU model (%d)\n", cpu_model); printf("Intel(R) Speed Select Technology\n"); printf("Executing on CPU model:%d[0x%x]\n", cpu_model, cpu_model); set_max_cpu_num(); -- cgit From c829f0ef7bfc4b294e67506779853547e8b52c68 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 10 Oct 2019 13:29:43 -0700 Subject: tools/power/x86/intel-speed-select: Implement CascadeLake-N help and command functions structures CascadeLake-N only supports SST-BF and needs some of the perf-profile commands, and the base-freq commands. Add help functions, and create an empty command structures (the functions will be implemented later in this patchset). Call these functions when running on CascadeLake-N. Signed-off-by: Prarit Bhargava Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 37 +++++++++++++++++------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 67a866e2dac4..449025c6ea46 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1610,6 +1610,10 @@ static void get_clos_assoc(int arg) isst_ctdp_display_information_end(outf); } +static struct process_cmd_struct clx_n_cmds[] = { + { NULL, NULL, NULL, 0 } +}; + static struct process_cmd_struct isst_cmds[] = { { "perf-profile", "get-lock-status", get_tdp_locked, 0 }, { "perf-profile", "get-config-levels", get_tdp_levels, 0 }, @@ -1798,12 +1802,15 @@ static void isst_help(void) TDP, etc.\n"); printf("\nCommands : For feature=perf-profile\n"); printf("\tinfo\n"); - printf("\tget-lock-status\n"); - printf("\tget-config-levels\n"); - printf("\tget-config-version\n"); - printf("\tget-config-enabled\n"); - printf("\tget-config-current-level\n"); - printf("\tset-config-level\n"); + + if (!is_clx_n_platform()) { + printf("\tget-lock-status\n"); + printf("\tget-config-levels\n"); + printf("\tget-config-version\n"); + printf("\tget-config-enabled\n"); + printf("\tget-config-current-level\n"); + printf("\tset-config-level\n"); + } } static void pbf_help(void) @@ -1853,6 +1860,12 @@ static struct process_cmd_help_struct isst_help_cmds[] = { { NULL, NULL } }; +static struct process_cmd_help_struct clx_n_help_cmds[] = { + { "perf-profile", isst_help }, + { "base-freq", pbf_help }, + { NULL, NULL } +}; + void process_command(int argc, char **argv, struct process_cmd_help_struct *help_cmds, struct process_cmd_struct *cmds) @@ -2001,11 +2014,15 @@ static void cmdline(int argc, char **argv) set_max_cpu_num(); set_cpu_present_cpu_mask(); set_cpu_target_cpu_mask(); - ret = isst_fill_platform_info(); - if (ret) - goto out; - process_command(argc, argv, isst_help_cmds, isst_cmds); + if (!is_clx_n_platform()) { + ret = isst_fill_platform_info(); + if (ret) + goto out; + process_command(argc, argv, isst_help_cmds, isst_cmds); + } else { + process_command(argc, argv, clx_n_help_cmds, clx_n_cmds); + } out: free_cpu_set(present_cpumask); free_cpu_set(target_cpumask); -- cgit From 062e4aac92e8acbab2fd135e90b580b903c3724b Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 10 Oct 2019 13:29:44 -0700 Subject: tools/power/x86/intel-speed-select: Implement 'perf-profile info' on CascadeLake-N Add functionality for "perf-profile info" on CascadeLake-N. Sample output: intel-speed-select perf-profile info Intel(R) Speed Select Technology Executing on CPU model:85[0x55] package-0 die-0 cpu-0 perf-profile-level-0 cpu-count:20 enable-cpu-mask:00000000,000fffff enable-cpu-list:0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 thermal-design-power-ratio:23 base-frequency(MHz):2300 speed-select-turbo-freq:unsupported speed-select-base-freq:enabled speed-select-base-freq high-priority-base-frequency(MHz):2700000 high-priority-cpu-mask:00000000,0000e8c0 high-priority-cpu-list:6,7,11,13,14,15 low-priority-base-frequency(MHz):2100000 package-1 die-0 cpu-20 perf-profile-level-0 cpu-count:20 enable-cpu-mask:000000ff,fff00000 enable-cpu-list:20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39 thermal-design-power-ratio:23 base-frequency(MHz):2300 speed-select-turbo-freq:unsupported speed-select-base-freq:enabled speed-select-base-freq high-priority-base-frequency(MHz):2700000 high-priority-cpu-mask:0000000e,8c000000 high-priority-cpu-list:26,27,31,33,34,35 low-priority-base-frequency(MHz):2100000 Signed-off-by: Prarit Bhargava Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 163 +++++++++++++++++++++- tools/power/x86/intel-speed-select/isst-display.c | 14 +- tools/power/x86/intel-speed-select/isst.h | 3 + 3 files changed, 173 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 449025c6ea46..3c0eb4240df4 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -750,6 +750,152 @@ _get_tdp_level("get-config-current_level", levels, current_level, "Current TDP Level"); _get_tdp_level("get-lock-status", levels, locked, "TDP lock status"); +struct isst_pkg_ctdp clx_n_pkg_dev; + +static int clx_n_get_base_ratio(void) +{ + FILE *fp; + char *begin, *end, *line = NULL; + char number[5]; + float value = 0; + size_t n = 0; + + fp = fopen("/proc/cpuinfo", "r"); + if (!fp) + err(-1, "cannot open /proc/cpuinfo\n"); + + while (getline(&line, &n, fp) > 0) { + if (strstr(line, "model name")) { + /* this is true for CascadeLake-N */ + begin = strstr(line, "@ ") + 2; + end = strstr(line, "GHz"); + strncpy(number, begin, end - begin); + value = atof(number) * 10; + break; + } + } + free(line); + fclose(fp); + + return (int)(value); +} + +static int clx_n_config(int cpu) +{ + int i, ret, pkg_id, die_id; + unsigned long cpu_bf; + struct isst_pkg_ctdp_level_info *ctdp_level; + struct isst_pbf_info *pbf_info; + + ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; + pbf_info = &ctdp_level->pbf_info; + ctdp_level->core_cpumask_size = + alloc_cpu_set(&ctdp_level->core_cpumask); + + /* find the frequency base ratio */ + ctdp_level->tdp_ratio = clx_n_get_base_ratio(); + if (ctdp_level->tdp_ratio == 0) { + debug_printf("CLX: cn base ratio is zero\n"); + ret = -1; + goto error_ret; + } + + /* find the high and low priority frequencies */ + pbf_info->p1_high = 0; + pbf_info->p1_low = ~0; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + + for (i = 0; i < topo_max_cpus; i++) { + if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) + continue; + + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + CPU_SET_S(i, ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask); + + cpu_bf = parse_int_file(1, + "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", + i); + if (cpu_bf > pbf_info->p1_high) + pbf_info->p1_high = cpu_bf; + if (cpu_bf < pbf_info->p1_low) + pbf_info->p1_low = cpu_bf; + } + + if (pbf_info->p1_high == ~0UL) { + debug_printf("CLX: maximum base frequency not set\n"); + ret = -1; + goto error_ret; + } + + if (pbf_info->p1_low == 0) { + debug_printf("CLX: minimum base frequency not set\n"); + ret = -1; + goto error_ret; + } + + /* convert frequencies back to ratios */ + pbf_info->p1_high = pbf_info->p1_high / DISP_FREQ_MULTIPLIER; + pbf_info->p1_low = pbf_info->p1_low / DISP_FREQ_MULTIPLIER; + + /* create high priority cpu mask */ + pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask); + for (i = 0; i < topo_max_cpus; i++) { + if (!CPU_ISSET_S(i, present_cpumask_size, present_cpumask)) + continue; + + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + cpu_bf = parse_int_file(1, + "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", + i); + cpu_bf = cpu_bf / DISP_FREQ_MULTIPLIER; + if (cpu_bf == pbf_info->p1_high) + CPU_SET_S(i, pbf_info->core_cpumask_size, + pbf_info->core_cpumask); + } + + /* extra ctdp & pbf struct parameters */ + ctdp_level->processed = 1; + ctdp_level->pbf_support = 1; /* PBF is always supported and enabled */ + ctdp_level->pbf_enabled = 1; + ctdp_level->fact_support = 0; /* FACT is never supported */ + ctdp_level->fact_enabled = 0; + + return 0; + +error_ret: + free_cpu_set(ctdp_level->core_cpumask); + return ret; +} + +static void dump_clx_n_config_for_cpu(int cpu, void *arg1, void *arg2, + void *arg3, void *arg4) +{ + int ret; + + ret = clx_n_config(cpu); + if (ret) { + perror("isst_get_process_ctdp"); + } else { + struct isst_pkg_ctdp_level_info *ctdp_level; + struct isst_pbf_info *pbf_info; + + ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; + pbf_info = &ctdp_level->pbf_info; + isst_ctdp_display_information(cpu, outf, tdp_level, &clx_n_pkg_dev); + free_cpu_set(ctdp_level->core_cpumask); + free_cpu_set(pbf_info->core_cpumask); + } +} + static void dump_isst_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, void *arg4) { @@ -768,6 +914,8 @@ static void dump_isst_config_for_cpu(int cpu, void *arg1, void *arg2, static void dump_isst_config(int arg) { + void *fn; + if (cmd_help) { fprintf(stderr, "Print Intel(R) Speed Select Technology Performance profile configuration\n"); @@ -779,14 +927,17 @@ static void dump_isst_config(int arg) exit(0); } + if (!is_clx_n_platform()) + fn = dump_isst_config_for_cpu; + else + fn = dump_clx_n_config_for_cpu; + isst_ctdp_display_information_start(outf); if (max_target_cpus) - for_each_online_target_cpu_in_set(dump_isst_config_for_cpu, - NULL, NULL, NULL, NULL); + for_each_online_target_cpu_in_set(fn, NULL, NULL, NULL, NULL); else - for_each_online_package_in_set(dump_isst_config_for_cpu, NULL, - NULL, NULL, NULL); + for_each_online_package_in_set(fn, NULL, NULL, NULL, NULL); isst_ctdp_display_information_end(outf); } @@ -1611,6 +1762,7 @@ static void get_clos_assoc(int arg) } static struct process_cmd_struct clx_n_cmds[] = { + { "perf-profile", "info", dump_isst_config, 0 }, { NULL, NULL, NULL, 0 } }; @@ -1888,7 +2040,8 @@ void process_command(int argc, char **argv, } } - create_cpu_map(); + if (!is_clx_n_platform()) + create_cpu_map(); i = 0; while (cmds[i].feature) { diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 40346d534f78..8309810e7425 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -6,8 +6,6 @@ #include "isst.h" -#define DISP_FREQ_MULTIPLIER 100 - static void printcpulist(int str_len, char *str, int mask_size, cpu_set_t *cpu_mask) { @@ -204,6 +202,9 @@ static void _isst_pbf_display_information(int cpu, FILE *outf, int level, pbf_info->p1_low * DISP_FREQ_MULTIPLIER); format_and_print(outf, disp_level + 1, header, value); + if (is_clx_n_platform()) + return; + snprintf(header, sizeof(header), "tjunction-temperature(C)"); snprintf(value, sizeof(value), "%d", pbf_info->t_prochot); format_and_print(outf, disp_level + 1, header, value); @@ -377,6 +378,15 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, snprintf(value, sizeof(value), "unsupported"); format_and_print(outf, base_level + 4, header, value); + if (is_clx_n_platform()) { + if (ctdp_level->pbf_support) + _isst_pbf_display_information(cpu, outf, + tdp_level, + &ctdp_level->pbf_info, + base_level + 4); + continue; + } + snprintf(header, sizeof(header), "thermal-design-power(W)"); snprintf(value, sizeof(value), "%d", ctdp_level->pkg_tdp); format_and_print(outf, base_level + 4, header, value); diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index d280b27d600d..bef27bd6138e 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -69,6 +69,8 @@ #define PM_CLOS_OFFSET 0x08 #define PQR_ASSOC_OFFSET 0x20 +#define DISP_FREQ_MULTIPLIER 100 + struct isst_clos_config { int pkg_id; int die_id; @@ -237,4 +239,5 @@ extern void isst_display_result(int cpu, FILE *outf, char *feature, char *cmd, extern int isst_clos_get_clos_information(int cpu, int *enable, int *type); extern void isst_clos_display_clos_information(int cpu, FILE *outf, int clos_enable, int type); +extern int is_clx_n_platform(void); #endif -- cgit From 1aa7177cdcb38d114e0a80dc27482e645d8068f2 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Thu, 10 Oct 2019 13:29:45 -0700 Subject: tools/power/x86/intel-speed-select: Implement base-freq commands on CascadeLake-N Add functionality for base-freq info|enable|disable info on CascadeLake-N. Sample output: Intel(R) Speed Select Technology Executing on CPU model:85[0x55] package-0 die-0 cpu-0 speed-select-base-freq high-priority-base-frequency(MHz):2700000 high-priority-cpu-mask:00000000,0000e8c0 high-priority-cpu-list:6,7,11,13,14,15 low-priority-base-frequency(MHz):2100000 package-1 die-0 cpu-20 speed-select-base-freq high-priority-base-frequency(MHz):2700000 high-priority-cpu-mask:0000000e,8c000000 high-priority-cpu-list:26,27,31,33,34,35 low-priority-base-frequency(MHz):2100000 The enable command always returns success, and the disable command always returns failed because SST-BF cannot be enabled or disabled from the OS on CascadeLake-N. Enable command also have support for --auto|-a option, which sets cpufreq scaling_min to max, so that the high priority base frequency can be the required minimum for high priority cores. Disable command with -a/--auto option reset the setting back to the min frequency. Signed-off-by: Prarit Bhargava Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 51 ++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 3c0eb4240df4..1c20048b42e7 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1005,6 +1005,26 @@ static void set_tdp_level(int arg) isst_ctdp_display_information_end(outf); } +static void clx_n_dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, + void *arg3, void *arg4) +{ + int ret; + + ret = clx_n_config(cpu); + if (ret) { + perror("isst_get_process_ctdp"); + } else { + struct isst_pkg_ctdp_level_info *ctdp_level; + struct isst_pbf_info *pbf_info; + + ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; + pbf_info = &ctdp_level->pbf_info; + isst_pbf_display_information(cpu, outf, tdp_level, pbf_info); + free_cpu_set(ctdp_level->core_cpumask); + free_cpu_set(pbf_info->core_cpumask); + } +} + static void dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, void *arg4) { @@ -1022,6 +1042,8 @@ static void dump_pbf_config_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, static void dump_pbf_config(int arg) { + void *fn; + if (cmd_help) { fprintf(stderr, "Print Intel(R) Speed Select Technology base frequency configuration for a TDP level\n"); @@ -1035,13 +1057,18 @@ static void dump_pbf_config(int arg) exit(1); } + if (!is_clx_n_platform()) + fn = dump_pbf_config_for_cpu; + else + fn = clx_n_dump_pbf_config_for_cpu; + isst_ctdp_display_information_start(outf); + if (max_target_cpus) - for_each_online_target_cpu_in_set(dump_pbf_config_for_cpu, NULL, - NULL, NULL, NULL); + for_each_online_target_cpu_in_set(fn, NULL, NULL, NULL, NULL); else - for_each_online_package_in_set(dump_pbf_config_for_cpu, NULL, - NULL, NULL, NULL); + for_each_online_package_in_set(fn, NULL, NULL, NULL, NULL); + isst_ctdp_display_information_end(outf); } @@ -1235,6 +1262,19 @@ static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, int ret; int status = *(int *)arg4; + if (is_clx_n_platform()) { + if (status == 0) { + ret = -1; + if (auto_mode) + set_scaling_min_to_cpuinfo_min(cpu); + } else { + ret = 0; + if (auto_mode) + set_scaling_min_to_cpuinfo_max(cpu); + } + goto disp_result; + } + if (auto_mode) { if (status) { ret = set_pbf_core_power(cpu); @@ -1763,6 +1803,9 @@ static void get_clos_assoc(int arg) static struct process_cmd_struct clx_n_cmds[] = { { "perf-profile", "info", dump_isst_config, 0 }, + { "base-freq", "info", dump_pbf_config, 0 }, + { "base-freq", "enable", set_pbf_enable, 1 }, + { "base-freq", "disable", set_pbf_enable, 0 }, { NULL, NULL, NULL, 0 } }; -- cgit From 263225c983aa27719fe06836426e270b658036ed Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 4 Nov 2019 03:02:37 -0800 Subject: tools/power/x86/intel-speed-select: Extend command set for perf-profile Add support for uncore P0, uncore P1, P1 for base and AVX levels and memory frequency. These commands are optional, so continue on failure. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-core.c | 67 +++++++++++++++++++++++ tools/power/x86/intel-speed-select/isst-display.c | 39 ++++++++++++- 2 files changed, 105 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 67d32f2b9bea..ca3bd5b2cf45 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -95,6 +95,69 @@ int isst_get_pwr_info(int cpu, int config_index, return 0; } +void isst_get_uncore_p0_p1_info(int cpu, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + ret = isst_send_mbox_command(cpu, CONFIG_TDP, + CONFIG_TDP_GET_UNCORE_P0_P1_INFO, 0, + config_index, &resp); + if (ret) { + ctdp_level->uncore_p0 = 0; + ctdp_level->uncore_p1 = 0; + return; + } + + ctdp_level->uncore_p0 = resp & GENMASK(7, 0); + ctdp_level->uncore_p1 = (resp & GENMASK(15, 8)) >> 8; + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_UNCORE_P0_P1_INFO resp:%x uncore p0:%d uncore p1:%d\n", + cpu, config_index, resp, ctdp_level->uncore_p0, + ctdp_level->uncore_p1); +} + +void isst_get_p1_info(int cpu, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0, + config_index, &resp); + if (ret) { + ctdp_level->sse_p1 = 0; + ctdp_level->avx2_p1 = 0; + ctdp_level->avx512_p1 = 0; + return; + } + + ctdp_level->sse_p1 = resp & GENMASK(7, 0); + ctdp_level->avx2_p1 = (resp & GENMASK(15, 8)) >> 8; + ctdp_level->avx512_p1 = (resp & GENMASK(23, 16)) >> 16; + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d\n", + cpu, config_index, resp, ctdp_level->sse_p1, + ctdp_level->avx2_p1, ctdp_level->avx512_p1); +} + +void isst_get_uncore_mem_freq(int cpu, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + unsigned int resp; + int ret; + ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ, + 0, config_index, &resp); + if (ret) { + ctdp_level->mem_freq = 0; + return; + } + + ctdp_level->mem_freq = resp & GENMASK(7, 0); + debug_printf( + "cpu:%d ctdp:%d CONFIG_TDP_GET_MEM_FREQ resp:%x uncore mem_freq:%d\n", + cpu, config_index, resp, ctdp_level->mem_freq); +} + int isst_get_tjmax_info(int cpu, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level) { @@ -600,6 +663,10 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) if (ret) return ret; + isst_get_uncore_p0_p1_info(cpu, i, ctdp_level); + isst_get_p1_info(cpu, i, ctdp_level); + isst_get_uncore_mem_freq(cpu, i, ctdp_level); + if (ctdp_level->pbf_support) { ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info); if (!ret) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 8309810e7425..d330f7a90c76 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -352,10 +352,47 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, format_and_print(outf, base_level + 4, header, value); snprintf(header, sizeof(header), "base-frequency(MHz)"); + if (!ctdp_level->sse_p1) + ctdp_level->sse_p1 = ctdp_level->tdp_ratio; snprintf(value, sizeof(value), "%d", - ctdp_level->tdp_ratio * DISP_FREQ_MULTIPLIER); + ctdp_level->sse_p1 * DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 4, header, value); + if (ctdp_level->avx2_p1) { + snprintf(header, sizeof(header), "base-frequency-avx2(MHz)"); + snprintf(value, sizeof(value), "%d", + ctdp_level->avx2_p1 * DISP_FREQ_MULTIPLIER); + format_and_print(outf, base_level + 4, header, value); + } + + if (ctdp_level->avx512_p1) { + snprintf(header, sizeof(header), "base-frequency-avx512(MHz)"); + snprintf(value, sizeof(value), "%d", + ctdp_level->avx512_p1 * DISP_FREQ_MULTIPLIER); + format_and_print(outf, base_level + 4, header, value); + } + + if (ctdp_level->uncore_p1) { + snprintf(header, sizeof(header), "uncore-frequency-min(MHz)"); + snprintf(value, sizeof(value), "%d", + ctdp_level->uncore_p1 * DISP_FREQ_MULTIPLIER); + format_and_print(outf, base_level + 4, header, value); + } + + if (ctdp_level->uncore_p0) { + snprintf(header, sizeof(header), "uncore-frequency-max(MHz)"); + snprintf(value, sizeof(value), "%d", + ctdp_level->uncore_p0 * DISP_FREQ_MULTIPLIER); + format_and_print(outf, base_level + 4, header, value); + } + + if (ctdp_level->mem_freq) { + snprintf(header, sizeof(header), "mem-frequency(MHz)"); + snprintf(value, sizeof(value), "%d", + ctdp_level->mem_freq * DISP_FREQ_MULTIPLIER); + format_and_print(outf, base_level + 4, header, value); + } + snprintf(header, sizeof(header), "speed-select-turbo-freq"); if (ctdp_level->fact_support) { -- cgit From 82d4a34ee6196a652f04f81d23ab296bddf8486d Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 4 Nov 2019 03:02:38 -0800 Subject: tools/power/x86/intel-speed-select: Change display of "avx" to "avx2" Make the avx level display consistent. Except for "turbo-ratio-limits-avx", everywhere else it is avx2. So change "turbo-ratio-limits-avx" to "turbo-ratio-limits-avx2". Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index d330f7a90c76..b7d58f7c5b3e 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -449,7 +449,7 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 6, header, value); } - snprintf(header, sizeof(header), "turbo-ratio-limits-avx"); + snprintf(header, sizeof(header), "turbo-ratio-limits-avx2"); format_and_print(outf, base_level + 4, header, NULL); for (j = 0; j < 8; ++j) { snprintf(header, sizeof(header), "bucket-%d", j); -- cgit From 91d928147bb0d03219fd6cc079e16fd74e232e2b Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 4 Nov 2019 03:02:39 -0800 Subject: tools/power/x86/intel-speed-select: Correct CLX-N frequency units In CLX_N base_frequency is read from cpufreq sysfs, where units are in KHz. The internal units in the code matches the real ratios which are in 100MHz scale. So when storing units for CLX-N frequencies, convert to 100MHz scale. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 1c20048b42e7..bfa42fc6c4d2 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -840,8 +840,8 @@ static int clx_n_config(int cpu) } /* convert frequencies back to ratios */ - pbf_info->p1_high = pbf_info->p1_high / DISP_FREQ_MULTIPLIER; - pbf_info->p1_low = pbf_info->p1_low / DISP_FREQ_MULTIPLIER; + pbf_info->p1_high = pbf_info->p1_high / 100000; + pbf_info->p1_low = pbf_info->p1_low / 100000; /* create high priority cpu mask */ pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask); @@ -856,7 +856,7 @@ static int clx_n_config(int cpu) cpu_bf = parse_int_file(1, "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", i); - cpu_bf = cpu_bf / DISP_FREQ_MULTIPLIER; + cpu_bf = cpu_bf / 100000; if (cpu_bf == pbf_info->p1_high) CPU_SET_S(i, pbf_info->core_cpumask_size, pbf_info->core_cpumask); -- cgit From a9b2f8e2fa6c0f791f2345afb826d47c6a0f0e2c Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 4 Nov 2019 03:02:40 -0800 Subject: tools/power/x86/intel-speed-select: Auto mode for CLX There is an expectation in the CLX platform for SST base-freq feature that Scaling min frequency be different for high and low priority cores. This is the way the firmware will understand the priority. So this change will look at high priority and low priority cores, and set scaling_min_freq to P1High for high priority cores and P1Low to low priority cores. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 112 ++++++++++++++++++++--- 1 file changed, 100 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index bfa42fc6c4d2..c563ecaf44e1 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1095,7 +1095,73 @@ static int set_clos_param(int cpu, int clos, int epp, int wt, int min, int max) return 0; } -static int set_cpufreq_cpuinfo_scaling_min(int cpu, int max) +static int set_cpufreq_scaling_min_max(int cpu, int max, int freq) +{ + char buffer[128], freq_str[16]; + int fd, ret, len; + + if (max) + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); + else + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); + + fd = open(buffer, O_WRONLY); + if (fd < 0) + return fd; + + snprintf(freq_str, sizeof(freq_str), "%d", freq); + len = strlen(freq_str); + ret = write(fd, freq_str, len); + if (ret == -1) { + close(fd); + return ret; + } + close(fd); + + return 0; +} + +static int set_clx_pbf_cpufreq_scaling_min_max(int cpu) +{ + struct isst_pkg_ctdp_level_info *ctdp_level; + struct isst_pbf_info *pbf_info; + int i, pkg_id, die_id, freq, freq_high, freq_low; + int ret; + + ret = clx_n_config(cpu); + if (ret) { + perror("set_clx_pbf_cpufreq_scaling_min_max"); + return ret; + } + + ctdp_level = &clx_n_pkg_dev.ctdp_level[0]; + pbf_info = &ctdp_level->pbf_info; + freq_high = pbf_info->p1_high * 100000; + freq_low = pbf_info->p1_low * 100000; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + for (i = 0; i < get_topo_max_cpus(); ++i) { + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + if (CPU_ISSET_S(i, pbf_info->core_cpumask_size, + pbf_info->core_cpumask)) + freq = freq_high; + else + freq = freq_low; + + set_cpufreq_scaling_min_max(i, 1, freq); + set_cpufreq_scaling_min_max(i, 0, freq); + } + + return 0; +} + +static int set_cpufreq_scaling_min_max_from_cpuinfo(int cpu, int cpuinfo_max, int scaling_max) { char buffer[128], min_freq[16]; int fd, ret, len; @@ -1103,7 +1169,7 @@ static int set_cpufreq_cpuinfo_scaling_min(int cpu, int max) if (!CPU_ISSET_S(cpu, present_cpumask_size, present_cpumask)) return -1; - if (max) + if (cpuinfo_max) snprintf(buffer, sizeof(buffer), "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", cpu); else @@ -1120,8 +1186,12 @@ static int set_cpufreq_cpuinfo_scaling_min(int cpu, int max) if (len < 0) return len; - snprintf(buffer, sizeof(buffer), - "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); + if (scaling_max) + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpu); + else + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq", cpu); fd = open(buffer, O_WRONLY); if (fd < 0) @@ -1149,7 +1219,7 @@ static void set_scaling_min_to_cpuinfo_max(int cpu) die_id != get_physical_die_id(i)) continue; - set_cpufreq_cpuinfo_scaling_min(i, 1); + set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 0); } } @@ -1164,7 +1234,22 @@ static void set_scaling_min_to_cpuinfo_min(int cpu) die_id != get_physical_die_id(i)) continue; - set_cpufreq_cpuinfo_scaling_min(i, 0); + set_cpufreq_scaling_min_max_from_cpuinfo(i, 0, 0); + } +} + +static void set_scaling_max_to_cpuinfo_max(int cpu) +{ + int i, pkg_id, die_id; + + pkg_id = get_physical_package_id(cpu); + die_id = get_physical_die_id(cpu); + for (i = 0; i < get_topo_max_cpus(); ++i) { + if (pkg_id != get_physical_package_id(i) || + die_id != get_physical_die_id(i)) + continue; + + set_cpufreq_scaling_min_max_from_cpuinfo(i, 1, 1); } } @@ -1263,14 +1348,17 @@ static void set_pbf_for_cpu(int cpu, void *arg1, void *arg2, void *arg3, int status = *(int *)arg4; if (is_clx_n_platform()) { - if (status == 0) { - ret = -1; - if (auto_mode) - set_scaling_min_to_cpuinfo_min(cpu); - } else { + if (status) { ret = 0; if (auto_mode) - set_scaling_min_to_cpuinfo_max(cpu); + set_clx_pbf_cpufreq_scaling_min_max(cpu); + + } else { + ret = -1; + if (auto_mode) { + set_scaling_max_to_cpuinfo_max(cpu); + set_scaling_min_to_cpuinfo_min(cpu); + } } goto disp_result; } -- cgit From cd0e63706549c3e0d61f5fe48806a4528c575035 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 4 Nov 2019 03:02:41 -0800 Subject: tools/power/x86/intel-speed-select: Use mailbox for CLOS_PM_QOS_CONFIG Use mailbox to read/write CLOS_PM_QOS_CONFIG instead of read/write to MMIO offset. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index c563ecaf44e1..2a3650f025b9 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -574,12 +574,6 @@ int isst_send_mbox_command(unsigned int cpu, unsigned char command, if (!ret && !write) *resp = value; break; - case CLOS_PM_QOS_CONFIG: - ret = isst_send_mmio_command(cpu, PM_QOS_CONFIG_OFFSET, - write, &value); - if (!ret && !write) - *resp = value; - break; case CLOS_STATUS: break; default: -- cgit From 40dee9dda37d5596ad119d3c3962ca49d3f035a5 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 4 Nov 2019 03:02:42 -0800 Subject: tools/power/x86/intel-speed-select: Make CLOS frequency in MHz To be consistant with the other frequency units, change the CLOS unit to MHz instead of ratios. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 11 +++++++---- tools/power/x86/intel-speed-select/isst-display.c | 6 +++--- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 2a3650f025b9..a8ada9a4f020 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1775,9 +1775,9 @@ static void set_clos_config(int arg) fprintf(stderr, "\tSpecify clos EPP with [--epp|-e]\n"); fprintf(stderr, "\tSpecify clos Proportional Priority [--weight|-w]\n"); - fprintf(stderr, "\tSpecify clos min with [--min|-n]\n"); - fprintf(stderr, "\tSpecify clos max with [--max|-m]\n"); - fprintf(stderr, "\tSpecify clos desired with [--desired|-d]\n"); + fprintf(stderr, "\tSpecify clos min in MHz with [--min|-n]\n"); + fprintf(stderr, "\tSpecify clos max in MHz with [--max|-m]\n"); + fprintf(stderr, "\tSpecify clos desired in MHz with [--desired|-d]\n"); exit(0); } @@ -1799,7 +1799,7 @@ static void set_clos_config(int arg) clos_min = 0; } if (clos_max < 0) { - fprintf(stderr, "clos max is not specified, default: 0xff\n"); + fprintf(stderr, "clos max is not specified, default: 25500 MHz\n"); clos_max = 0xff; } if (clos_desired < 0) { @@ -2049,15 +2049,18 @@ static void parse_cmd_args(int argc, int start, char **argv) break; case 'd': clos_desired = atoi(optarg); + clos_desired /= DISP_FREQ_MULTIPLIER; break; case 'e': clos_epp = atoi(optarg); break; case 'n': clos_min = atoi(optarg); + clos_min /= DISP_FREQ_MULTIPLIER; break; case 'm': clos_max = atoi(optarg); + clos_max /= DISP_FREQ_MULTIPLIER; break; case 'p': clos_priority_type = atoi(optarg); diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index b7d58f7c5b3e..b8f04347ad3f 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -556,15 +556,15 @@ void isst_clos_display_information(int cpu, FILE *outf, int clos, format_and_print(outf, 5, header, value); snprintf(header, sizeof(header), "clos-min"); - snprintf(value, sizeof(value), "%d", clos_config->clos_min); + snprintf(value, sizeof(value), "%d MHz", clos_config->clos_min * DISP_FREQ_MULTIPLIER); format_and_print(outf, 5, header, value); snprintf(header, sizeof(header), "clos-max"); - snprintf(value, sizeof(value), "%d", clos_config->clos_max); + snprintf(value, sizeof(value), "%d MHz", clos_config->clos_max * DISP_FREQ_MULTIPLIER); format_and_print(outf, 5, header, value); snprintf(header, sizeof(header), "clos-desired"); - snprintf(value, sizeof(value), "%d", clos_config->clos_desired); + snprintf(value, sizeof(value), "%d MHz", clos_config->clos_desired * DISP_FREQ_MULTIPLIER); format_and_print(outf, 5, header, value); format_and_print(outf, 1, NULL, NULL); -- cgit From 21c3390d61286912cef312dc4752719142ce0d54 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 4 Nov 2019 03:02:43 -0800 Subject: tools/power/x86/intel-speed-select: Use Frequency weight for CLOS Use different frequency weights for CLOS 0 and and CLOS1-3, to define relative priority for power budgeting. This will be used for --auto mode to enable base-freq and turbo-freq feature. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index a8ada9a4f020..2d7ed27af7e0 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1260,15 +1260,15 @@ static int set_core_priority_and_min(int cpu, int mask_size, if (ret) return ret; - ret = set_clos_param(cpu, 1, 15, 0, min_low, 0xff); + ret = set_clos_param(cpu, 1, 15, 15, min_low, 0xff); if (ret) return ret; - ret = set_clos_param(cpu, 2, 15, 0, min_low, 0xff); + ret = set_clos_param(cpu, 2, 15, 15, min_low, 0xff); if (ret) return ret; - ret = set_clos_param(cpu, 3, 15, 0, min_low, 0xff); + ret = set_clos_param(cpu, 3, 15, 15, min_low, 0xff); if (ret) return ret; @@ -1589,15 +1589,15 @@ static void set_fact_enable(int arg) if (ret) goto error_disp; - ret = set_clos_param(i, 1, 15, 0, 0, 0xff); + ret = set_clos_param(i, 1, 15, 15, 0, 0xff); if (ret) goto error_disp; - ret = set_clos_param(i, 2, 15, 0, 0, 0xff); + ret = set_clos_param(i, 2, 15, 15, 0, 0xff); if (ret) goto error_disp; - ret = set_clos_param(i, 3, 15, 0, 0, 0xff); + ret = set_clos_param(i, 3, 15, 15, 0, 0xff); if (ret) goto error_disp; -- cgit From 7af5a95bb752702bfc91fc513d37f1f799e6fd1f Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 4 Nov 2019 03:02:44 -0800 Subject: tools/power/x86/intel-speed-select: Support platform with limited Intel(R) Speed Select There are some platforms, where there limited support of Intel(R) SST features. Here perf-profile has only one base configuration and limited support of commands. But still has support for discovery of base-freq and turbo-freq features. So it is important to show minimum features to use base-freq and turbo-freq features. Here the change are: - When there is no support of CONFIG_TDP_GET_LEVELS_INFO, then instead of treating this as fatal error, treat this with number of config levels = 0, that means only base level 0 is present. - There is no support of mail box commands to get base frequencies or turbo frequencies. Here present base frequency by reading cpufreq base freq and turbo frequency by reading MSR 0x1AD. - Don't display any field, which has value == 0. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 6 ++ tools/power/x86/intel-speed-select/isst-core.c | 74 +++++++++++++----- tools/power/x86/intel-speed-select/isst-display.c | 92 ++++++++++++----------- tools/power/x86/intel-speed-select/isst.h | 1 + 4 files changed, 113 insertions(+), 60 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 2d7ed27af7e0..2dffb67d3194 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -200,6 +200,11 @@ int get_physical_die_id(int cpu) return ret; } +int get_cpufreq_base_freq(int cpu) +{ + return parse_int_file(0, "/sys/devices/system/cpu/cpu%d/cpufreq/base_frequency", cpu); +} + int get_topo_max_cpus(void) { return topo_max_cpus; @@ -598,6 +603,7 @@ int isst_send_mbox_command(unsigned int cpu, unsigned char command, fprintf(outf, "Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n", cpu, command, sub_command, parameter, req_data); + return -1; } else { *resp = mbox_cmds.mbox_cmd[0].resp_data; debug_printf( diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index ca3bd5b2cf45..8b3e1c7abb42 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -13,8 +13,14 @@ int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev) ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp); - if (ret) - return ret; + if (ret) { + pkg_dev->levels = 0; + pkg_dev->locked = 1; + pkg_dev->current_level = 0; + pkg_dev->version = 0; + pkg_dev->enabled = 0; + return 0; + } debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", cpu, resp); @@ -212,6 +218,27 @@ int isst_get_coremask_info(int cpu, int config_index, return 0; } +int isst_get_get_trl_from_msr(int cpu, int *trl) +{ + unsigned long long msr_trl; + int ret; + + ret = isst_send_msr_command(cpu, 0x1AD, 0, &msr_trl); + if (ret) + return ret; + + trl[0] = msr_trl & GENMASK(7, 0); + trl[1] = (msr_trl & GENMASK(15, 8)) >> 8; + trl[2] = (msr_trl & GENMASK(23, 16)) >> 16; + trl[3] = (msr_trl & GENMASK(31, 24)) >> 24; + trl[4] = (msr_trl & GENMASK(39, 32)) >> 32; + trl[5] = (msr_trl & GENMASK(47, 40)) >> 40; + trl[6] = (msr_trl & GENMASK(55, 48)) >> 48; + trl[7] = (msr_trl & GENMASK(63, 56)) >> 56; + + return 0; +} + int isst_get_get_trl(int cpu, int level, int avx_level, int *trl) { unsigned int req, resp; @@ -321,7 +348,7 @@ int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info) CONFIG_TDP_PBF_GET_CORE_MASK_INFO, 0, (i << 8) | level, &resp); if (ret) - return ret; + break; debug_printf( "cpu:%d CONFIG_TDP_PBF_GET_CORE_MASK_INFO resp:%x\n", @@ -386,7 +413,7 @@ int isst_set_pbf_fact_status(int cpu, int pbf, int enable) ret = isst_get_ctdp_levels(cpu, &pkg_dev); if (ret) - return ret; + debug_printf("cpu:%d No support for dynamic ISST\n", cpu); current_level = pkg_dev.current_level; @@ -626,6 +653,32 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) if (ret) return ret; + if (ctdp_level->pbf_support) { + ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info); + if (!ret) + ctdp_level->pbf_found = 1; + } + + if (ctdp_level->fact_support) { + ret = isst_get_fact_info(cpu, i, + &ctdp_level->fact_info); + if (ret) + return ret; + } + + if (!pkg_dev->enabled) { + int freq; + + freq = get_cpufreq_base_freq(cpu); + if (freq > 0) { + ctdp_level->sse_p1 = freq / 100000; + ctdp_level->tdp_ratio = ctdp_level->sse_p1; + } + + isst_get_get_trl_from_msr(cpu, ctdp_level->trl_sse_active_cores); + continue; + } + ret = isst_get_tdp_info(cpu, i, ctdp_level); if (ret) return ret; @@ -666,19 +719,6 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) isst_get_uncore_p0_p1_info(cpu, i, ctdp_level); isst_get_p1_info(cpu, i, ctdp_level); isst_get_uncore_mem_freq(cpu, i, ctdp_level); - - if (ctdp_level->pbf_support) { - ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info); - if (!ret) - ctdp_level->pbf_found = 1; - } - - if (ctdp_level->fact_support) { - ret = isst_get_fact_info(cpu, i, - &ctdp_level->fact_info); - if (ret) - return ret; - } } pkg_dev->processed = 1; diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index b8f04347ad3f..c976bfe9b503 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -335,17 +335,19 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, snprintf(value, sizeof(value), "%d", j); format_and_print(outf, base_level + 4, header, value); - snprintf(header, sizeof(header), "enable-cpu-mask"); - printcpumask(sizeof(value), value, - ctdp_level->core_cpumask_size, - ctdp_level->core_cpumask); - format_and_print(outf, base_level + 4, header, value); + if (ctdp_level->core_cpumask_size) { + snprintf(header, sizeof(header), "enable-cpu-mask"); + printcpumask(sizeof(value), value, + ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask); + format_and_print(outf, base_level + 4, header, value); - snprintf(header, sizeof(header), "enable-cpu-list"); - printcpulist(sizeof(value), value, - ctdp_level->core_cpumask_size, - ctdp_level->core_cpumask); - format_and_print(outf, base_level + 4, header, value); + snprintf(header, sizeof(header), "enable-cpu-list"); + printcpulist(sizeof(value), value, + ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask); + format_and_print(outf, base_level + 4, header, value); + } snprintf(header, sizeof(header), "thermal-design-power-ratio"); snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio); @@ -424,13 +426,17 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, continue; } - snprintf(header, sizeof(header), "thermal-design-power(W)"); - snprintf(value, sizeof(value), "%d", ctdp_level->pkg_tdp); - format_and_print(outf, base_level + 4, header, value); + if (ctdp_level->pkg_tdp) { + snprintf(header, sizeof(header), "thermal-design-power(W)"); + snprintf(value, sizeof(value), "%d", ctdp_level->pkg_tdp); + format_and_print(outf, base_level + 4, header, value); + } - snprintf(header, sizeof(header), "tjunction-max(C)"); - snprintf(value, sizeof(value), "%d", ctdp_level->t_proc_hot); - format_and_print(outf, base_level + 4, header, value); + if (ctdp_level->t_proc_hot) { + snprintf(header, sizeof(header), "tjunction-max(C)"); + snprintf(value, sizeof(value), "%d", ctdp_level->t_proc_hot); + format_and_print(outf, base_level + 4, header, value); + } snprintf(header, sizeof(header), "turbo-ratio-limits-sse"); format_and_print(outf, base_level + 4, header, NULL); @@ -449,41 +455,41 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 6, header, value); } - snprintf(header, sizeof(header), "turbo-ratio-limits-avx2"); - format_and_print(outf, base_level + 4, header, NULL); - for (j = 0; j < 8; ++j) { - snprintf(header, sizeof(header), "bucket-%d", j); - format_and_print(outf, base_level + 5, header, NULL); - snprintf(header, sizeof(header), "core-count"); - snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); - format_and_print(outf, base_level + 6, header, value); + if (ctdp_level->trl_avx_active_cores[0]) { + snprintf(header, sizeof(header), "turbo-ratio-limits-avx2"); + format_and_print(outf, base_level + 4, header, NULL); + for (j = 0; j < 8; ++j) { + snprintf(header, sizeof(header), "bucket-%d", j); + format_and_print(outf, base_level + 5, header, NULL); - snprintf(header, sizeof(header), - "max-turbo-frequency(MHz)"); - snprintf(value, sizeof(value), "%d", - ctdp_level->trl_avx_active_cores[j] * - DISP_FREQ_MULTIPLIER); - format_and_print(outf, base_level + 6, header, value); + snprintf(header, sizeof(header), "core-count"); + snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); + format_and_print(outf, base_level + 6, header, value); + + snprintf(header, sizeof(header), "max-turbo-frequency(MHz)"); + snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_active_cores[j] * DISP_FREQ_MULTIPLIER); + format_and_print(outf, base_level + 6, header, value); + } } - snprintf(header, sizeof(header), "turbo-ratio-limits-avx512"); - format_and_print(outf, base_level + 4, header, NULL); - for (j = 0; j < 8; ++j) { - snprintf(header, sizeof(header), "bucket-%d", j); - format_and_print(outf, base_level + 5, header, NULL); + if (ctdp_level->trl_avx_512_active_cores[0]) { + snprintf(header, sizeof(header), "turbo-ratio-limits-avx512"); + format_and_print(outf, base_level + 4, header, NULL); + for (j = 0; j < 8; ++j) { + snprintf(header, sizeof(header), "bucket-%d", j); + format_and_print(outf, base_level + 5, header, NULL); - snprintf(header, sizeof(header), "core-count"); - snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); - format_and_print(outf, base_level + 6, header, value); + snprintf(header, sizeof(header), "core-count"); + snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff); + format_and_print(outf, base_level + 6, header, value); - snprintf(header, sizeof(header), - "max-turbo-frequency(MHz)"); - snprintf(value, sizeof(value), "%d", - ctdp_level->trl_avx_512_active_cores[j] * - DISP_FREQ_MULTIPLIER); + snprintf(header, sizeof(header), "max-turbo-frequency(MHz)"); + snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_512_active_cores[j] * DISP_FREQ_MULTIPLIER); format_and_print(outf, base_level + 6, header, value); + } } + if (ctdp_level->pbf_support) _isst_pbf_display_information(cpu, outf, i, &ctdp_level->pbf_info, diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index bef27bd6138e..84f56a468f82 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -240,4 +240,5 @@ extern int isst_clos_get_clos_information(int cpu, int *enable, int *type); extern void isst_clos_display_clos_information(int cpu, FILE *outf, int clos_enable, int type); extern int is_clx_n_platform(void); +extern int get_cpufreq_base_freq(int cpu); #endif -- cgit From de7f9d3ddc8c71a116fbdfa298a19abd8d46e696 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 4 Nov 2019 03:02:45 -0800 Subject: tools/power/x86/intel-speed-select: Use core count for base-freq mask Some firmware implementation gives error when a command is sent get mask for core count 32-61. So use core count to decide. But there is no function to get core count. So introduce one function to get core count. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 23 ++++++++++++++++++++++- tools/power/x86/intel-speed-select/isst-core.c | 7 +++++-- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 28 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 2dffb67d3194..e0bad43697dc 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -338,6 +338,7 @@ void free_cpu_set(cpu_set_t *cpu_set) } static int cpu_cnt[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE]; +static long long core_mask[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE]; static void set_cpu_present_cpu_mask(void) { size_t size; @@ -362,13 +363,33 @@ static void set_cpu_present_cpu_mask(void) pkg_id = get_physical_package_id(i); if (pkg_id < MAX_PACKAGE_COUNT && - die_id < MAX_DIE_PER_PACKAGE) + die_id < MAX_DIE_PER_PACKAGE) { + int core_id = get_physical_core_id(i); + cpu_cnt[pkg_id][die_id]++; + core_mask[pkg_id][die_id] |= (1ULL << core_id); + } } closedir(dir); } } +int get_core_count(int pkg_id, int die_id) +{ + int cnt = 0; + + if (pkg_id < MAX_PACKAGE_COUNT && die_id < MAX_DIE_PER_PACKAGE) { + int i; + + for (i = 0; i < sizeof(long long) * 8; ++i) { + if (core_mask[pkg_id][die_id] & (1ULL << i)) + cnt++; + } + } + + return cnt; +} + int get_cpu_count(int pkg_id, int die_id) { if (pkg_id < MAX_PACKAGE_COUNT && die_id < MAX_DIE_PER_PACKAGE) diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 8b3e1c7abb42..52698553de92 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -335,12 +335,15 @@ int isst_set_tdp_level(int cpu, int tdp_level) int isst_get_pbf_info(int cpu, int level, struct isst_pbf_info *pbf_info) { + int i, ret, core_cnt, max; unsigned int req, resp; - int i, ret; pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask); - for (i = 0; i < 2; ++i) { + core_cnt = get_core_count(get_physical_package_id(cpu), get_physical_die_id(cpu)); + max = core_cnt > 32 ? 2 : 1; + + for (i = 0; i < max; ++i) { unsigned long long mask; int count; diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 84f56a468f82..cdf0f8a6dbbf 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -163,6 +163,7 @@ struct isst_pkg_ctdp { extern int get_topo_max_cpus(void); extern int get_cpu_count(int pkg_id, int die_id); +extern int get_core_count(int pkg_id, int die_id); /* Common interfaces */ extern void debug_printf(const char *format, ...); -- cgit From 5c14aba77874d350db8973f4c980fd92c8b1fa07 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 4 Nov 2019 03:02:46 -0800 Subject: tools/power/x86/intel-speed-select: Increment version Since the tool now adds support for another Intel SST implementation, increment version number. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index e0bad43697dc..944183f9ed5a 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -15,7 +15,7 @@ struct process_cmd_struct { int arg; }; -static const char *version_str = "v1.0"; +static const char *version_str = "v1.1"; static const int supported_api_ver = 1; static struct isst_if_platform_info isst_platform_info; static char *progname; -- cgit From 20183ccd3e4d01d23b0a01fe9f3ee73fbae312fa Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Fri, 15 Nov 2019 12:35:22 -0800 Subject: tools/power/x86/intel-speed-select: Ignore missing config level It is possible that certain config levels are not available, even if the max level includes the level. There can be missing levels in some platforms. So ignore the level when called for information dump for all levels and fail if specifically ask for the missing level. Here the changes is to continue reading information about other levels even if we fail to get information for the current level. But use the "processed" flag to indicate the failure. When the "processed" flag is not set, don't dump information about that level. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-core.c | 8 ++++---- tools/power/x86/intel-speed-select/isst-display.c | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 52698553de92..aa19c9998e6c 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -646,7 +646,6 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) i); ctdp_level = &pkg_dev->ctdp_level[i]; - ctdp_level->processed = 1; ctdp_level->level = i; ctdp_level->control_cpu = cpu; ctdp_level->pkg_id = get_physical_package_id(cpu); @@ -654,7 +653,10 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) ret = isst_get_ctdp_control(cpu, i, ctdp_level); if (ret) - return ret; + continue; + + pkg_dev->processed = 1; + ctdp_level->processed = 1; if (ctdp_level->pbf_support) { ret = isst_get_pbf_info(cpu, i, &ctdp_level->pbf_info); @@ -724,8 +726,6 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) isst_get_uncore_mem_freq(cpu, i, ctdp_level); } - pkg_dev->processed = 1; - return 0; } diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index c976bfe9b503..040dd09d5eee 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -315,7 +315,8 @@ void isst_ctdp_display_information(int cpu, FILE *outf, int tdp_level, char value[256]; int i, base_level = 1; - print_package_info(cpu, outf); + if (pkg_dev->processed) + print_package_info(cpu, outf); for (i = 0; i <= pkg_dev->levels; ++i) { struct isst_pkg_ctdp_level_info *ctdp_level; -- cgit From 1434a3d357d656d4b11fcbdc9b6c35dc673292a0 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Tue, 19 Nov 2019 16:22:54 -0800 Subject: tools/power/x86/intel-speed-select: Display TRL buckets for just base config level When only base config level is present, this tool is displaying TRL (Turbo-ratio-limits) by reading legacy MSR. In this case, also present core count for TRL by reading MSR 0x1AE. Signed-off-by: Srinivas Pandruvada Signed-off-by: Andy Shevchenko --- tools/power/x86/intel-speed-select/isst-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index aa19c9998e6c..d14c7bcd327a 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -681,6 +681,7 @@ int isst_get_process_ctdp(int cpu, int tdp_level, struct isst_pkg_ctdp *pkg_dev) } isst_get_get_trl_from_msr(cpu, ctdp_level->trl_sse_active_cores); + isst_get_trl_bucket_info(cpu, &ctdp_level->buckets_info); continue; } -- cgit