Commit 062e4aac authored by Prarit Bhargava's avatar Prarit Bhargava Committed by Andy Shevchenko
Browse files

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: default avatarPrarit Bhargava <prarit@redhat.com>
Signed-off-by: default avatarSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
parent c829f0ef
Loading
Loading
Loading
Loading
+158 −5
Original line number Diff line number Diff line
@@ -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,6 +2040,7 @@ void process_command(int argc, char **argv,
		}
	}

	if (!is_clx_n_platform())
		create_cpu_map();

	i = 0;
+12 −2
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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