]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
tools/power/x86/intel-speed-select: Implement 'perf-profile info' on CascadeLake-N
authorPrarit Bhargava <prarit@redhat.com>
Thu, 10 Oct 2019 20:29:44 +0000 (13:29 -0700)
committerAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Tue, 15 Oct 2019 08:02:30 +0000 (11:02 +0300)
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 <prarit@redhat.com>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
tools/power/x86/intel-speed-select/isst-config.c
tools/power/x86/intel-speed-select/isst-display.c
tools/power/x86/intel-speed-select/isst.h

index 449025c6ea465f61c9c3c3d46c9d72651291d1dd..3c0eb4240df4bc72392531908e6de1a83f694448 100644 (file)
@@ -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) {
index 40346d534f789a120f36ecc95e1527f35d074b94..8309810e7425622d2aefa2212fb886d6befa389d 100644 (file)
@@ -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);
index d280b27d600d538658445158e8fb0132a96c3c56..bef27bd6138efdf824bc08ca60d9a146ea04a50c 100644 (file)
@@ -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