From a8c208d3708ab7da26eba5b7b528a0f9874ab071 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 20 Aug 2022 20:14:15 +0800 Subject: [PATCH 01/27] tools/power/x86/intel-speed-select: Move send_mbox_cmd to isst-core-mbox.c ANBZ: #9825 commit 2b86ed225e657867b405b3e9412e9efefcbe6ffb upstream. After the previous cleanup, there is no user of send_mbox_cmd outside of isst-core-mbox.c. Thus move send_mbox_cmd to isst-core-mbox.c as internal functions. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- .../x86/intel-speed-select/isst-core-mbox.c | 222 +++++++++++++++--- .../power/x86/intel-speed-select/isst-core.c | 160 +------------ 2 files changed, 195 insertions(+), 187 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 8e224d154e04..6eafef925d1a 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -5,6 +5,9 @@ */ #include "isst.h" +static int mbox_delay; +static int mbox_retries = 3; + static int mbox_get_disp_freq_multiplier(void) { return DISP_FREQ_MULTIPLIER; @@ -29,6 +32,20 @@ static char *mbox_get_trl_level_name(int level) } } +static void mbox_update_platform_param(enum isst_platform_param param, int value) +{ + switch (param) { + case ISST_PARAM_MBOX_DELAY: + mbox_delay = value; + break; + case ISST_PARAM_MBOX_RETRIES: + mbox_retries = value; + break; + default: + break; + } +} + static int mbox_is_punit_valid(struct isst_id *id) { if (id->cpu < 0) @@ -40,12 +57,156 @@ static int mbox_is_punit_valid(struct isst_id *id) return 1; } +static int _send_mmio_command(unsigned int cpu, unsigned int reg, int write, + unsigned int *value) +{ + struct isst_if_io_regs io_regs; + const char *pathname = "/dev/isst_interface"; + int cmd; + FILE *outf = get_output_file(); + int fd; + + debug_printf("mmio_cmd cpu:%d reg:%d write:%d\n", cpu, reg, write); + + fd = open(pathname, O_RDWR); + if (fd < 0) + err(-1, "%s open failed", pathname); + + io_regs.req_count = 1; + io_regs.io_reg[0].logical_cpu = cpu; + io_regs.io_reg[0].reg = reg; + cmd = ISST_IF_IO_CMD; + if (write) { + io_regs.io_reg[0].read_write = 1; + io_regs.io_reg[0].value = *value; + } else { + io_regs.io_reg[0].read_write = 0; + } + + if (ioctl(fd, cmd, &io_regs) == -1) { + if (errno == ENOTTY) { + perror("ISST_IF_IO_COMMAND\n"); + fprintf(stderr, "Check presence of kernel modules: isst_if_mmio\n"); + exit(0); + } + fprintf(outf, "Error: mmio_cmd cpu:%d reg:%x read_write:%x\n", + cpu, reg, write); + } else { + if (!write) + *value = io_regs.io_reg[0].value; + + debug_printf( + "mmio_cmd response: cpu:%d reg:%x rd_write:%x resp:%x\n", + cpu, reg, write, *value); + } + + close(fd); + + return 0; +} + +int _send_mbox_command(unsigned int cpu, unsigned char command, + unsigned char sub_command, unsigned int parameter, + unsigned int req_data, unsigned int *resp) +{ + const char *pathname = "/dev/isst_interface"; + int fd, retry; + struct isst_if_mbox_cmds mbox_cmds = { 0 }; + + debug_printf( + "mbox_send: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n", + cpu, command, sub_command, parameter, req_data); + + if (!is_skx_based_platform() && command == CONFIG_CLOS && + sub_command != CLOS_PM_QOS_CONFIG) { + unsigned int value; + int write = 0; + int clos_id, core_id, ret = 0; + + debug_printf("CPU %d\n", cpu); + + if (parameter & BIT(MBOX_CMD_WRITE_BIT)) { + value = req_data; + write = 1; + } + + switch (sub_command) { + case CLOS_PQR_ASSOC: + core_id = parameter & 0xff; + ret = _send_mmio_command( + cpu, PQR_ASSOC_OFFSET + core_id * 4, write, + &value); + if (!ret && !write) + *resp = value; + break; + case CLOS_PM_CLOS: + clos_id = parameter & 0x03; + ret = _send_mmio_command( + cpu, PM_CLOS_OFFSET + clos_id * 4, write, + &value); + if (!ret && !write) + *resp = value; + break; + case CLOS_STATUS: + break; + default: + break; + } + return ret; + } + + mbox_cmds.cmd_count = 1; + mbox_cmds.mbox_cmd[0].logical_cpu = cpu; + mbox_cmds.mbox_cmd[0].command = command; + mbox_cmds.mbox_cmd[0].sub_command = sub_command; + mbox_cmds.mbox_cmd[0].parameter = parameter; + mbox_cmds.mbox_cmd[0].req_data = req_data; + + if (mbox_delay) + usleep(mbox_delay * 1000); + + fd = open(pathname, O_RDWR); + if (fd < 0) + err(-1, "%s open failed", pathname); + + retry = mbox_retries; + do { + if (ioctl(fd, ISST_IF_MBOX_COMMAND, &mbox_cmds) == -1) { + if (errno == ENOTTY) { + perror("ISST_IF_MBOX_COMMAND\n"); + fprintf(stderr, "Check presence of kernel modules: isst_if_mbox_pci or isst_if_mbox_msr\n"); + exit(0); + } + debug_printf( + "Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x errorno:%d\n", + cpu, command, sub_command, parameter, req_data, errno); + --retry; + } else { + *resp = mbox_cmds.mbox_cmd[0].resp_data; + debug_printf( + "mbox_cmd response: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x resp:%x\n", + cpu, command, sub_command, parameter, req_data, *resp); + break; + } + } while (retry); + + close(fd); + + if (!retry) { + debug_printf("Failed mbox command even after retries\n"); + return -1; + + } + + return 0; +} + static int mbox_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap) { unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, READ_PM_CONFIG, PM_FEATURE, 0, 0, + ret = _send_mbox_command(id->cpu, READ_PM_CONFIG, PM_FEATURE, 0, 0, &resp); if (ret) return ret; @@ -63,7 +224,7 @@ static int mbox_get_config_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_ unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp); if (ret) { pkg_dev->levels = 0; @@ -92,7 +253,7 @@ static int mbox_get_ctdp_control(struct isst_id *id, int config_index, unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_CONTROL, 0, config_index, &resp); if (ret) @@ -130,7 +291,7 @@ static void _get_uncore_p0_p1_info(struct isst_id *id, int config_index, ctdp_level->uncore_p0 = 0; ctdp_level->uncore_p1 = 0; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_RATIO_INFO, 0, (BIT(16) | config_index) , &resp); if (ret) { @@ -149,7 +310,7 @@ static void _get_uncore_p0_p1_info(struct isst_id *id, int config_index, return; try_uncore_mbox: - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_UNCORE_P0_P1_INFO, 0, config_index, &resp); if (ret) { @@ -210,7 +371,7 @@ static void _get_p1_info(struct isst_id *id, int config_index, { unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_P1_INFO, 0, config_index, &resp); if (ret) { ctdp_level->sse_p1 = 0; @@ -234,7 +395,7 @@ static void _get_uncore_mem_freq(struct isst_id *id, int config_index, unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_MEM_FREQ, 0, config_index, &resp); if (ret) { ctdp_level->mem_freq = 0; @@ -267,7 +428,7 @@ static int mbox_get_tdp_info(struct isst_id *id, int config_index, unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO, 0, config_index, &resp); if (ret) { isst_display_error_info_message(1, "Invalid level, Can't get TDP information at level", 1, config_index); @@ -282,7 +443,7 @@ static int mbox_get_tdp_info(struct isst_id *id, int config_index, id->cpu, config_index, resp, ctdp_level->tdp_ratio, ctdp_level->pkg_tdp); - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO, 0, config_index, &resp); if (ret) return ret; @@ -306,7 +467,7 @@ static int mbox_get_pwr_info(struct isst_id *id, int config_index, unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO, 0, config_index, &resp); if (ret) return ret; @@ -333,7 +494,7 @@ static int mbox_get_coremask_info(struct isst_id *id, int config_index, unsigned long long mask; int cpu_count = 0; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_CORE_MASK, 0, (i << 8) | config_index, &resp); if (ret) @@ -362,7 +523,7 @@ static int mbox_get_get_trl(struct isst_id *id, int level, int avx_level, int *t int ret; req = level | (avx_level << 16); - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, &resp); if (ret) @@ -378,7 +539,7 @@ static int mbox_get_get_trl(struct isst_id *id, int level, int avx_level, int *t trl[3] = (resp & GENMASK(31, 24)) >> 24; req = level | BIT(8) | (avx_level << 16); - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req, &resp); if (ret) @@ -438,7 +599,7 @@ static int mbox_set_tdp_level(struct isst_id *id, int tdp_level) } - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_SET_LEVEL, 0, tdp_level, &resp); if (ret) { isst_display_error_info_message(1, "Set TDP level failed for level", 1, tdp_level); @@ -461,7 +622,7 @@ static int mbox_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info unsigned long long mask; int count; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_CORE_MASK_INFO, 0, (i << 8) | level, &resp); if (ret) @@ -479,7 +640,7 @@ static int mbox_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info } req = level; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_P1HI_P1LO_INFO, 0, req, &resp); if (ret) @@ -492,7 +653,7 @@ static int mbox_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info pbf_info->p1_high = (resp & GENMASK(15, 8)) >> 8; req = level; - ret = isst_send_mbox_command( + ret = _send_mbox_command( id->cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TDP_INFO, 0, req, &resp); if (ret) return ret; @@ -502,7 +663,7 @@ static int mbox_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info pbf_info->tdp = resp & 0xffff; req = level; - ret = isst_send_mbox_command( + ret = _send_mbox_command( id->cpu, CONFIG_TDP, CONFIG_TDP_PBF_GET_TJ_MAX_INFO, 0, req, &resp); if (ret) return ret; @@ -555,7 +716,7 @@ static int mbox_set_pbf_fact_status(struct isst_id *id, int pbf, int enable) req &= ~BIT(16); } - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_SET_TDP_CONTROL, 0, req, &resp); if (ret) return ret; @@ -575,7 +736,7 @@ static int _get_fact_bucket_info(struct isst_id *id, int level, for (i = 0; i < 2; ++i) { int j; - ret = isst_send_mbox_command( + ret = _send_mbox_command( id->cpu, CONFIG_TDP, CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_NUMCORES, 0, (i << 8) | level, &resp); @@ -596,7 +757,7 @@ static int _get_fact_bucket_info(struct isst_id *id, int level, for (i = 0; i < 2; ++i) { int j; - ret = isst_send_mbox_command( + ret = _send_mbox_command( id->cpu, CONFIG_TDP, CONFIG_TDP_GET_FACT_HP_TURBO_LIMIT_RATIOS, 0, (k << 16) | (i << 8) | level, &resp); @@ -622,7 +783,7 @@ static int mbox_get_fact_info(struct isst_id *id, int level, int fact_bucket, st unsigned int resp; int j, ret, print; - ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, + ret = _send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_FACT_LP_CLIPPING_RATIO, 0, level, &resp); if (ret) @@ -662,7 +823,7 @@ static int mbox_get_clos_information(struct isst_id *id, int *enable, int *type) unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, &resp); if (ret) return ret; @@ -692,7 +853,7 @@ static int _write_pm_config(struct isst_id *id, int cp_state) else req = 0; - ret = isst_send_mbox_command(id->cpu, WRITE_PM_CONFIG, PM_FEATURE, 0, req, + ret = _send_mbox_command(id->cpu, WRITE_PM_CONFIG, PM_FEATURE, 0, req, &resp); if (ret) return ret; @@ -735,7 +896,7 @@ static int mbox_pm_qos_config(struct isst_id *id, int enable_clos, int priority_ isst_display_error_info_message(0, "WRITE_PM_CONFIG command failed, ignoring error", 0, 0); } - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, 0, 0, &resp); if (ret) { isst_display_error_info_message(1, "CLOS_PM_QOS_CONFIG command failed", 0, 0); @@ -759,7 +920,7 @@ static int mbox_pm_qos_config(struct isst_id *id, int enable_clos, int priority_ else req = req & ~BIT(2); - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_QOS_CONFIG, BIT(MBOX_CMD_WRITE_BIT), req, &resp); if (ret) return ret; @@ -775,7 +936,7 @@ static int mbox_pm_get_clos(struct isst_id *id, int clos, struct isst_clos_confi unsigned int resp; int ret; - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, clos, 0, &resp); if (ret) return ret; @@ -803,7 +964,7 @@ static int mbox_set_clos(struct isst_id *id, int clos, struct isst_clos_config * param = BIT(MBOX_CMD_WRITE_BIT) | clos; - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PM_CLOS, param, req, &resp); if (ret) return ret; @@ -822,7 +983,7 @@ static int mbox_clos_get_assoc_status(struct isst_id *id, int *clos_id) core_id = find_phy_core_num(id->cpu); param = core_id; - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, 0, &resp); if (ret) return ret; @@ -844,7 +1005,7 @@ static int mbox_clos_associate(struct isst_id *id, int clos_id) core_id = find_phy_core_num(id->cpu); param = BIT(MBOX_CMD_WRITE_BIT) | core_id; - ret = isst_send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, + ret = _send_mbox_command(id->cpu, CONFIG_CLOS, CLOS_PQR_ASSOC, param, req, &resp); if (ret) return ret; @@ -859,6 +1020,7 @@ static struct isst_platform_ops mbox_ops = { .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, .get_trl_max_levels = mbox_get_trl_max_levels, .get_trl_level_name = mbox_get_trl_level_name, + .update_platform_param = mbox_update_platform_param, .is_punit_valid = mbox_is_punit_valid, .read_pm_config = mbox_read_pm_config, .get_config_levels = mbox_get_config_levels, diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 24b2c041bfe0..fcab70ef5704 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -6,9 +6,6 @@ #include "isst.h" -static int mbox_delay; -static int mbox_retries = 3; - static struct isst_platform_ops *isst_ops; #define CHECK_CB(_name) \ @@ -30,16 +27,9 @@ int isst_set_platform_ops(void) void isst_update_platform_param(enum isst_platform_param param, int value) { - switch (param) { - case ISST_PARAM_MBOX_DELAY: - mbox_delay = value; - break; - case ISST_PARAM_MBOX_RETRIES: - mbox_retries = value; - break; - default: - break; - } + CHECK_CB(update_platform_param); + + isst_ops->update_platform_param(param, value); } int isst_get_disp_freq_multiplier(void) @@ -66,150 +56,6 @@ int isst_is_punit_valid(struct isst_id *id) return isst_ops->is_punit_valid(id); } -static int isst_send_mmio_command(unsigned int cpu, unsigned int reg, int write, - unsigned int *value) -{ - struct isst_if_io_regs io_regs; - const char *pathname = "/dev/isst_interface"; - int cmd; - FILE *outf = get_output_file(); - int fd; - - debug_printf("mmio_cmd cpu:%d reg:%d write:%d\n", cpu, reg, write); - - fd = open(pathname, O_RDWR); - if (fd < 0) - err(-1, "%s open failed", pathname); - - io_regs.req_count = 1; - io_regs.io_reg[0].logical_cpu = cpu; - io_regs.io_reg[0].reg = reg; - cmd = ISST_IF_IO_CMD; - if (write) { - io_regs.io_reg[0].read_write = 1; - io_regs.io_reg[0].value = *value; - } else { - io_regs.io_reg[0].read_write = 0; - } - - if (ioctl(fd, cmd, &io_regs) == -1) { - if (errno == ENOTTY) { - perror("ISST_IF_IO_COMMAND\n"); - fprintf(stderr, "Check presence of kernel modules: isst_if_mmio\n"); - exit(0); - } - fprintf(outf, "Error: mmio_cmd cpu:%d reg:%x read_write:%x\n", - cpu, reg, write); - } else { - if (!write) - *value = io_regs.io_reg[0].value; - - debug_printf( - "mmio_cmd response: cpu:%d reg:%x rd_write:%x resp:%x\n", - cpu, reg, write, *value); - } - - close(fd); - - return 0; -} - -int isst_send_mbox_command(unsigned int cpu, unsigned char command, - unsigned char sub_command, unsigned int parameter, - unsigned int req_data, unsigned int *resp) -{ - const char *pathname = "/dev/isst_interface"; - int fd, retry; - struct isst_if_mbox_cmds mbox_cmds = { 0 }; - - debug_printf( - "mbox_send: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x\n", - cpu, command, sub_command, parameter, req_data); - - if (!is_skx_based_platform() && command == CONFIG_CLOS && - sub_command != CLOS_PM_QOS_CONFIG) { - unsigned int value; - int write = 0; - int clos_id, core_id, ret = 0; - - debug_printf("CPU %d\n", cpu); - - if (parameter & BIT(MBOX_CMD_WRITE_BIT)) { - value = req_data; - write = 1; - } - - switch (sub_command) { - case CLOS_PQR_ASSOC: - core_id = parameter & 0xff; - ret = isst_send_mmio_command( - cpu, PQR_ASSOC_OFFSET + core_id * 4, write, - &value); - if (!ret && !write) - *resp = value; - break; - case CLOS_PM_CLOS: - clos_id = parameter & 0x03; - ret = isst_send_mmio_command( - cpu, PM_CLOS_OFFSET + clos_id * 4, write, - &value); - if (!ret && !write) - *resp = value; - break; - case CLOS_STATUS: - break; - default: - break; - } - return ret; - } - - mbox_cmds.cmd_count = 1; - mbox_cmds.mbox_cmd[0].logical_cpu = cpu; - mbox_cmds.mbox_cmd[0].command = command; - mbox_cmds.mbox_cmd[0].sub_command = sub_command; - mbox_cmds.mbox_cmd[0].parameter = parameter; - mbox_cmds.mbox_cmd[0].req_data = req_data; - - if (mbox_delay) - usleep(mbox_delay * 1000); - - fd = open(pathname, O_RDWR); - if (fd < 0) - err(-1, "%s open failed", pathname); - - retry = mbox_retries; - - do { - if (ioctl(fd, ISST_IF_MBOX_COMMAND, &mbox_cmds) == -1) { - if (errno == ENOTTY) { - perror("ISST_IF_MBOX_COMMAND\n"); - fprintf(stderr, "Check presence of kernel modules: isst_if_mbox_pci or isst_if_mbox_msr\n"); - exit(0); - } - debug_printf( - "Error: mbox_cmd cpu:%d command:%x sub_command:%x parameter:%x req_data:%x errorno:%d\n", - cpu, command, sub_command, parameter, req_data, errno); - --retry; - } else { - *resp = mbox_cmds.mbox_cmd[0].resp_data; - debug_printf( - "mbox_cmd response: cpu:%d command:%x sub_command:%x parameter:%x req_data:%x resp:%x\n", - cpu, command, sub_command, parameter, req_data, *resp); - break; - } - } while (retry); - - close(fd); - - if (!retry) { - debug_printf("Failed mbox command even after retries\n"); - return -1; - - } - return 0; -} - int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write, unsigned long long *req_resp) { -- Gitee From 7200c9e31b6c609f8ef07b6d79f351e7cb076304 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 20 Aug 2022 20:40:48 +0800 Subject: [PATCH 02/27] tools/power/x86/intel-speed-select: Allow api_version based platform callbacks ANBZ: #9825 commit 05aab5b8c1b78c028cd95701e788623de744d1cd upstream. Different api_version suggests different kernel driver used and different interface is used to communication with the hardware. Allow setting platform specific callbacks based on api_version. Currently, all platforms with api_version 1 uses Mbox/MMIO interfaces. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-config.c | 6 ++++-- tools/power/x86/intel-speed-select/isst-core.c | 13 ++++++++++--- tools/power/x86/intel-speed-select/isst.h | 8 ++------ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 346f8271b00f..fb83f74f15a4 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -803,8 +803,10 @@ static int isst_fill_platform_info(void) const char *pathname = "/dev/isst_interface"; int fd; - if (is_clx_n_platform()) + if (is_clx_n_platform()) { + isst_platform_info.api_version = 1; goto set_platform_ops; + } fd = open(pathname, O_RDWR); if (fd < 0) @@ -824,7 +826,7 @@ static int isst_fill_platform_info(void) } set_platform_ops: - if (isst_set_platform_ops()) { + if (isst_set_platform_ops(isst_platform_info.api_version)) { fprintf(stderr, "Failed to set platform callbacks\n"); exit(0); } diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index fcab70ef5704..674097289ebf 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -16,9 +16,16 @@ static struct isst_platform_ops *isst_ops; } \ } while (0) -int isst_set_platform_ops(void) -{ - isst_ops = mbox_get_platform_ops(); +int isst_set_platform_ops(int api_version) +{ + switch (api_version) { + case 1: + isst_ops = mbox_get_platform_ops(); + break; + default: + isst_ops = NULL; + break; + } if (!isst_ops) return -1; diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 8192e683ac92..6839ad2d2b9d 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -185,6 +185,7 @@ struct isst_platform_ops { int (*get_disp_freq_multiplier)(void); int (*get_trl_max_levels)(void); char *(*get_trl_level_name)(int level); + void (*update_platform_param)(enum isst_platform_param param, int value); int (*is_punit_valid)(struct isst_id *id); int (*read_pm_config)(struct isst_id *id, int *cp_state, int *cp_cap); int (*get_config_levels)(struct isst_id *id, struct isst_pkg_ctdp *pkg_ctdp); @@ -226,15 +227,10 @@ extern void set_cpu_mask_from_punit_coremask(struct isst_id *id, size_t core_cpumask_size, cpu_set_t *core_cpumask, int *cpu_cnt); -extern int isst_send_mbox_command(unsigned int cpu, unsigned char command, - unsigned char sub_command, - unsigned int write, - unsigned int req_data, unsigned int *resp); - extern int isst_send_msr_command(unsigned int cpu, unsigned int command, int write, unsigned long long *req_resp); -extern int isst_set_platform_ops(void); +extern int isst_set_platform_ops(int api_version); extern void isst_update_platform_param(enum isst_platform_param, int vale); extern int isst_get_disp_freq_multiplier(void); extern int isst_get_trl_max_levels(void); -- Gitee From 64c32e9ec6fc33adfa1805afa03b607bd82362d1 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 9 Aug 2022 01:56:04 +0800 Subject: [PATCH 03/27] tools/power/x86/intel-speed-select: Introduce is_debug_enabled() ANBZ: #9825 commit 9798768ce9bc4da626091f4f87fc0a8edbee44d5 upstream. Platform specific code also needs to give debug output. Introduce is_debug_enabled() for this purpose. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-config.c | 5 +++++ tools/power/x86/intel-speed-select/isst.h | 1 + 2 files changed, 6 insertions(+) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index fb83f74f15a4..591fe30a55b0 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -77,6 +77,11 @@ FILE *get_output_file(void) return outf; } +int is_debug_enabled(void) +{ + return debug_flag; +} + void debug_printf(const char *format, ...) { va_list args; diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 6839ad2d2b9d..b3bf989690d6 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -216,6 +216,7 @@ extern int get_max_punit_core_id(struct isst_id *id); /* Common interfaces */ FILE *get_output_file(void); +extern int is_debug_enabled(void); extern void debug_printf(const char *format, ...); extern int out_format_is_json(void); extern void set_isst_id(struct isst_id *id, int cpu); -- Gitee From b2baad0239cd519adb268b79343e42d1805e38fa Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 16 Aug 2022 21:20:00 +0800 Subject: [PATCH 04/27] tools/power/x86/intel-speed-select: Support large clos_min/max ANBZ: #9825 commit 20f06c9db22bf45de595a2a5855630b075596217 upstream. clos_min/max in TPMI interface is frequency in MHz, thus clos_min/max needs to support larger values. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index b3bf989690d6..b854f4bf795f 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -92,10 +92,10 @@ struct isst_id { }; struct isst_clos_config { + unsigned int clos_min; + unsigned int clos_max; unsigned char epp; unsigned char clos_prop_prio; - unsigned char clos_min; - unsigned char clos_max; unsigned char clos_desired; }; -- Gitee From 51b29a90f196b48271eec90b080f6ea6c7c8ff52 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 20 Aug 2022 20:51:33 +0800 Subject: [PATCH 05/27] tools/power/x86/intel-speed-select: Introduce api_version helper ANBZ: #9825 commit 887e5be91dd253ff73c0b2644442c0cae5d6dca0 upstream. In some cases, the output format may be different with different api_version because of different capabilities or for backward capabilities reason. Introduce api_version() to get the api_version of the platform running. No functional changes are expected. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-config.c | 5 +++++ tools/power/x86/intel-speed-select/isst.h | 1 + 2 files changed, 6 insertions(+) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 591fe30a55b0..891693ac1234 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -166,6 +166,11 @@ static int update_cpu_model(void) return 0; } +int api_version(void) +{ + return isst_platform_info.api_version; +} + /* Open a file, and exit on failure */ static FILE *fopen_or_exit(const char *path, const char *mode) { diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index b854f4bf795f..3efa7251001f 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -213,6 +213,7 @@ extern int is_cpu_in_power_domain(int cpu, struct isst_id *id); extern int get_topo_max_cpus(void); extern int get_cpu_count(struct isst_id *id); extern int get_max_punit_core_id(struct isst_id *id); +extern int api_version(void); /* Common interfaces */ FILE *get_output_file(void); -- Gitee From 4140b1749f0a3a059abafab9567dc2cf33741f79 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 6 Mar 2023 09:26:28 -0800 Subject: [PATCH 06/27] tools/power/x86/intel-speed-select: Get punit core mapping information ANBZ: #9825 commit a0ca5a097342f78d41e104d8d6bb0742ff0e7330 upstream. Get punit core mapping information using format of MSR 0x54. Based on the API version, decode is done using new format. The new format also include a power domain ID. TPMI SST information is for each power domain. Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- .../x86/intel-speed-select/isst-config.c | 57 +++++++++++++------ 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 891693ac1234..136da390b4b2 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -669,6 +669,46 @@ int get_cpu_count(struct isst_id *id) return cpu_cnt[id->pkg][id->die][id->punit]; } +static void update_punit_cpu_info(__u32 physical_cpu, struct _cpu_map *cpu_map) +{ + if (api_version() > 1) { + /* + * MSR 0x54 format + * [15:11] PM_DOMAIN_ID + * [10:3] MODULE_ID (aka IDI_AGENT_ID) + * [2:0] LP_ID (We don't care about these bits we only + * care die and core id + * For Atom: + * [2] Always 0 + * [1:0] core ID within module + * For Core + * [2:1] Always 0 + * [0] thread ID + */ + cpu_map->punit_id = (physical_cpu >> 11) & 0x1f; + cpu_map->punit_cpu_core = (physical_cpu >> 3) & 0xff; + cpu_map->punit_cpu = physical_cpu & 0x7ff; + } else { + int punit_id; + + /* + * MSR 0x53 format + * Format + * Bit 0 – thread ID + * Bit 8:1 – core ID + * Bit 13:9 – punit ID + */ + cpu_map->punit_cpu = physical_cpu & 0x1ff; + cpu_map->punit_cpu_core = (cpu_map->punit_cpu >> 1); // shift to get core id + punit_id = (physical_cpu >> 9) & 0x1f; + + if (punit_id >= MAX_PUNIT_PER_DIE) + punit_id = 0; + + cpu_map->punit_id = punit_id; + } +} + static void create_cpu_map(void) { const char *pathname = "/dev/isst_interface"; @@ -727,24 +767,9 @@ static void create_cpu_map(void) fprintf(outf, "Error: map logical_cpu:%d\n", map.cpu_map[0].logical_cpu); } else { - /* - * Format - * Bit 0 – thread ID - * Bit 8:1 – core ID - * Bit 13:9 – punit ID - */ - cpu_map[i].punit_cpu = map.cpu_map[0].physical_cpu & 0x1ff; - cpu_map[i].punit_cpu_core = (cpu_map[i].punit_cpu >> - 1); // shift to get core id - punit_id = (map.cpu_map[0].physical_cpu >> 9) & 0x1f; - - if (punit_id >= MAX_PUNIT_PER_DIE) - punit_id = 0; - - cpu_map[i].punit_id = punit_id; + update_punit_cpu_info(map.cpu_map[0].physical_cpu, &cpu_map[i]); } } - cpu_map[i].initialized = 1; cpu_cnt[pkg_id][die_id][punit_id]++; -- Gitee From bd55e2976debf1bc184b576a0a5f60c4410242be Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 9 Aug 2022 00:01:00 +0800 Subject: [PATCH 07/27] tools/power/x86/intel-speed-select: Introduce TPMI interface support ANBZ: #9825 commit 79554aaa224a3b99f95b9c2843dc904764c32541 upstream. TPMI (Topology Aware Register and PM Capsule Interface) creates a flexible, extendable and software-PCIe-driver-enumerable MMIO interface for PM features. SST feature is exposed via the TPMI interface on newer Xeon platforms. Kernel TPMI based SST driver provides a series of new IOCTLs for userspace to use. Introduce support for the platforms that do SST control via TPMI interface. Compared with previous platforms, Newer Xeons also supports multi-punit in a package/die, including cpu punit and non-cpu punit. These have already been handled in the generic code. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/Build | 2 +- .../x86/intel-speed-select/isst-core-tpmi.c | 787 ++++++++++++++++++ .../power/x86/intel-speed-select/isst-core.c | 3 + tools/power/x86/intel-speed-select/isst.h | 3 + 4 files changed, 794 insertions(+), 1 deletion(-) create mode 100644 tools/power/x86/intel-speed-select/isst-core-tpmi.c diff --git a/tools/power/x86/intel-speed-select/Build b/tools/power/x86/intel-speed-select/Build index 32a2493b5233..5a9637e1678c 100644 --- a/tools/power/x86/intel-speed-select/Build +++ b/tools/power/x86/intel-speed-select/Build @@ -1 +1 @@ -intel-speed-select-y += isst-config.o isst-core.o isst-display.o isst-daemon.o hfi-events.o isst-core-mbox.o +intel-speed-select-y += isst-config.o isst-core.o isst-display.o isst-daemon.o hfi-events.o isst-core-mbox.o isst-core-tpmi.o diff --git a/tools/power/x86/intel-speed-select/isst-core-tpmi.c b/tools/power/x86/intel-speed-select/isst-core-tpmi.c new file mode 100644 index 000000000000..19caa9c78d41 --- /dev/null +++ b/tools/power/x86/intel-speed-select/isst-core-tpmi.c @@ -0,0 +1,787 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Intel Speed Select -- Enumerate and control features for TPMI Interface + * Copyright (c) 2022 Intel Corporation. + */ + +#include +#include "isst.h" + +int tpmi_process_ioctl(int ioctl_no, void *info) +{ + const char *pathname = "/dev/isst_interface"; + int fd; + + if (is_debug_enabled()) { + debug_printf("Issue IOCTL: "); + switch (ioctl_no) { + case ISST_IF_CORE_POWER_STATE: + debug_printf("ISST_IF_CORE_POWER_STATE\n"); + break; + case ISST_IF_CLOS_PARAM: + debug_printf("ISST_IF_CLOS_PARAM\n"); + break; + case ISST_IF_CLOS_ASSOC: + debug_printf("ISST_IF_CLOS_ASSOC\n"); + break; + case ISST_IF_PERF_LEVELS: + debug_printf("ISST_IF_PERF_LEVELS\n"); + break; + case ISST_IF_PERF_SET_LEVEL: + debug_printf("ISST_IF_PERF_SET_LEVEL\n"); + break; + case ISST_IF_PERF_SET_FEATURE: + debug_printf("ISST_IF_PERF_SET_FEATURE\n"); + break; + case ISST_IF_GET_PERF_LEVEL_INFO: + debug_printf("ISST_IF_GET_PERF_LEVEL_INFO\n"); + break; + case ISST_IF_GET_PERF_LEVEL_CPU_MASK: + debug_printf("ISST_IF_GET_PERF_LEVEL_CPU_MASK\n"); + break; + case ISST_IF_GET_BASE_FREQ_INFO: + debug_printf("ISST_IF_GET_BASE_FREQ_INFO\n"); + break; + case ISST_IF_GET_BASE_FREQ_CPU_MASK: + debug_printf("ISST_IF_GET_BASE_FREQ_CPU_MASK\n"); + break; + case ISST_IF_GET_TURBO_FREQ_INFO: + debug_printf("ISST_IF_GET_TURBO_FREQ_INFO\n"); + break; + case ISST_IF_COUNT_TPMI_INSTANCES: + debug_printf("ISST_IF_COUNT_TPMI_INSTANCES\n"); + break; + default: + debug_printf("%d\n", ioctl_no); + break; + } + } + + fd = open(pathname, O_RDWR); + if (fd < 0) + return -1; + + if (ioctl(fd, ioctl_no, info) == -1) { + debug_printf("IOCTL %d Failed\n", ioctl_no); + close(fd); + return -1; + } + + close(fd); + + return 0; +} + +static int tpmi_get_disp_freq_multiplier(void) +{ + return 1; +} + +static int tpmi_get_trl_max_levels(void) +{ + return TRL_MAX_LEVELS; +} + +static char *tpmi_get_trl_level_name(int level) +{ + switch (level) { + case 0: + return "level-0"; + case 1: + return "level-1"; + case 2: + return "level-2"; + case 3: + return "level-3"; + case 4: + return "level-4"; + case 5: + return "level-5"; + case 6: + return "level-6"; + case 7: + return "level-7"; + default: + return NULL; + } +} + + +static void tpmi_update_platform_param(enum isst_platform_param param, int value) +{ + /* No params need to be updated for now */ +} + +static int tpmi_is_punit_valid(struct isst_id *id) +{ + struct isst_tpmi_instance_count info; + int ret; + + if (id->punit < 0) + return 0; + + info.socket_id = id->pkg; + ret = tpmi_process_ioctl(ISST_IF_COUNT_TPMI_INSTANCES, &info); + if (ret == -1) + return 0; + + if (info.valid_mask & BIT(id->punit)) + return 1; + + return 0; +} + +static int tpmi_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap) +{ + struct isst_core_power info; + int ret; + + info.get_set = 0; + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info); + if (ret == -1) + return ret; + + *cp_state = info.enable; + *cp_cap = info.supported; + + return 0; +} + +int tpmi_get_config_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev) +{ + struct isst_perf_level_info info; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + + ret = tpmi_process_ioctl(ISST_IF_PERF_LEVELS, &info); + if (ret == -1) + return ret; + + pkg_dev->version = info.feature_rev; + pkg_dev->levels = info.max_level; + pkg_dev->locked = info.locked; + pkg_dev->current_level = info.current_level; + pkg_dev->locked = info.locked; + pkg_dev->enabled = info.enabled; + + return 0; +} + +static int tpmi_get_ctdp_control(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + struct isst_core_power core_power_info; + struct isst_perf_level_info info; + int level_mask; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + + ret = tpmi_process_ioctl(ISST_IF_PERF_LEVELS, &info); + if (ret == -1) + return -1; + + if (config_index != 0xff) + level_mask = 1 << config_index; + else + level_mask = config_index; + + if (!(info.level_mask & level_mask)) + return -1; + + ctdp_level->fact_support = info.sst_tf_support; + ctdp_level->pbf_support = info.sst_bf_support; + ctdp_level->fact_enabled = !!(info.feature_state & BIT(1)); + ctdp_level->pbf_enabled = !!(info.feature_state & BIT(0)); + + core_power_info.get_set = 0; + core_power_info.socket_id = id->pkg; + core_power_info.power_domain_id = id->punit; + + ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &core_power_info); + if (ret == -1) + return ret; + + ctdp_level->sst_cp_support = core_power_info.supported; + ctdp_level->sst_cp_enabled = core_power_info.enable; + + debug_printf + ("cpu:%d CONFIG_TDP_GET_TDP_CONTROL fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n", + id->cpu, ctdp_level->fact_support, ctdp_level->pbf_support, + ctdp_level->fact_enabled, ctdp_level->pbf_enabled); + + return 0; +} + +static int tpmi_get_tdp_info(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + struct isst_perf_level_data_info info; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = config_index; + + ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); + if (ret == -1) + return ret; + + ctdp_level->pkg_tdp = info.thermal_design_power_w; + ctdp_level->tdp_ratio = info.tdp_ratio; + ctdp_level->sse_p1 = info.base_freq_mhz; + ctdp_level->avx2_p1 = info.base_freq_avx2_mhz; + ctdp_level->avx512_p1 = info.base_freq_avx512_mhz; + ctdp_level->amx_p1 = info.base_freq_amx_mhz; + + ctdp_level->t_proc_hot = info.tjunction_max_c; + ctdp_level->mem_freq = info.max_memory_freq_mhz; + ctdp_level->cooling_type = info.cooling_type; + + ctdp_level->uncore_p0 = info.p0_fabric_freq_mhz; + ctdp_level->uncore_p1 = info.p1_fabric_freq_mhz; + ctdp_level->uncore_pm = info.pm_fabric_freq_mhz; + + debug_printf + ("cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO tdp_ratio:%d pkg_tdp:%d ctdp_level->t_proc_hot:%d\n", + id->cpu, config_index, ctdp_level->tdp_ratio, ctdp_level->pkg_tdp, + ctdp_level->t_proc_hot); + + return 0; +} + +static int tpmi_get_pwr_info(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + /* TBD */ + ctdp_level->pkg_max_power = 0; + ctdp_level->pkg_min_power = 0; + + debug_printf + ("cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO pkg_max_power:%d pkg_min_power:%d\n", + id->cpu, config_index, ctdp_level->pkg_max_power, + ctdp_level->pkg_min_power); + + return 0; +} + +int tpmi_get_coremask_info(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + struct isst_perf_level_cpu_mask info; + int ret, cpu_count; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = config_index; + info.punit_cpu_map = 1; + + ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_CPU_MASK, &info); + if (ret == -1) + return ret; + + set_cpu_mask_from_punit_coremask(id, info.mask, + ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask, &cpu_count); + ctdp_level->cpu_count = cpu_count; + + debug_printf("cpu:%d ctdp:%d core_mask ino cpu count:%d\n", + id->cpu, config_index, ctdp_level->cpu_count); + + return 0; +} + +static int tpmi_get_get_trls(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + struct isst_perf_level_data_info info; + int ret, i, j; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = config_index; + + ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); + if (ret == -1) + return ret; + + if (info.max_buckets > TRL_MAX_BUCKETS) + info.max_buckets = TRL_MAX_BUCKETS; + + if (info.max_trl_levels > TRL_MAX_LEVELS) + info.max_trl_levels = TRL_MAX_LEVELS; + + for (i = 0; i < info.max_trl_levels; ++i) + for (j = 0; j < info.max_buckets; ++j) + ctdp_level->trl_ratios[i][j] = info.trl_freq_mhz[i][j]; + + return 0; +} + +static int tpmi_get_get_trl(struct isst_id *id, int level, int config_index, + int *trl) +{ + struct isst_pkg_ctdp_level_info ctdp_level; + int ret, i; + + ret = tpmi_get_get_trls(id, config_index, &ctdp_level); + if (ret) + return ret; + + /* FIX ME: Just return for level 0 */ + for (i = 0; i < 8; ++i) + trl[i] = ctdp_level.trl_ratios[0][i]; + + return 0; +} + +static int tpmi_get_trl_bucket_info(struct isst_id *id, int config_index, + unsigned long long *buckets_info) +{ + struct isst_perf_level_data_info info; + unsigned char *mask = (unsigned char *)buckets_info; + int ret, i; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = config_index; + + ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); + if (ret == -1) + return ret; + + if (info.max_buckets > TRL_MAX_BUCKETS) + info.max_buckets = TRL_MAX_BUCKETS; + + for (i = 0; i < info.max_buckets; ++i) + mask[i] = info.bucket_core_counts[i]; + + debug_printf("cpu:%d TRL bucket info: 0x%llx\n", id->cpu, + *buckets_info); + + return 0; +} + +static int tpmi_set_tdp_level(struct isst_id *id, int tdp_level) +{ + struct isst_perf_level_control info; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = tdp_level; + + ret = tpmi_process_ioctl(ISST_IF_PERF_SET_LEVEL, &info); + if (ret == -1) + return ret; + + return 0; +} + +static int _pbf_get_coremask_info(struct isst_id *id, int config_index, + struct isst_pbf_info *pbf_info) +{ + struct isst_perf_level_cpu_mask info; + int ret, cpu_count; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = config_index; + info.punit_cpu_map = 1; + + ret = tpmi_process_ioctl(ISST_IF_GET_BASE_FREQ_CPU_MASK, &info); + if (ret == -1) + return ret; + + set_cpu_mask_from_punit_coremask(id, info.mask, + pbf_info->core_cpumask_size, + pbf_info->core_cpumask, &cpu_count); + + debug_printf("cpu:%d ctdp:%d pbf core_mask info cpu count:%d\n", + id->cpu, config_index, cpu_count); + + return 0; +} + +static int tpmi_get_pbf_info(struct isst_id *id, int level, + struct isst_pbf_info *pbf_info) +{ + struct isst_base_freq_info info; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = level; + + ret = tpmi_process_ioctl(ISST_IF_GET_BASE_FREQ_INFO, &info); + if (ret == -1) + return ret; + + pbf_info->p1_low = info.low_base_freq_mhz; + pbf_info->p1_high = info.high_base_freq_mhz; + pbf_info->tdp = info.thermal_design_power_w; + pbf_info->t_prochot = info.tjunction_max_c; + + debug_printf("cpu:%d ctdp:%d pbf info:%d:%d:%d:%d\n", + id->cpu, level, pbf_info->p1_low, pbf_info->p1_high, + pbf_info->tdp, pbf_info->t_prochot); + + return _pbf_get_coremask_info(id, level, pbf_info); +} + +static int tpmi_set_pbf_fact_status(struct isst_id *id, int pbf, int enable) +{ + struct isst_pkg_ctdp pkg_dev; + struct isst_pkg_ctdp_level_info ctdp_level; + int current_level; + struct isst_perf_feature_control info; + int ret; + + ret = isst_get_ctdp_levels(id, &pkg_dev); + if (ret) + debug_printf("cpu:%d No support for dynamic ISST\n", id->cpu); + + current_level = pkg_dev.current_level; + + ret = isst_get_ctdp_control(id, current_level, &ctdp_level); + if (ret) + return ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + + info.feature = 0; + + if (pbf) { + if (ctdp_level.fact_enabled) + info.feature |= BIT(1); + + if (enable) + info.feature |= BIT(0); + else + info.feature &= ~BIT(0); + } else { + + if (enable && !ctdp_level.sst_cp_enabled) + isst_display_error_info_message(0, + "Make sure to execute before: core-power enable", + 0, 0); + + if (ctdp_level.pbf_enabled) + info.feature |= BIT(0); + + if (enable) + info.feature |= BIT(1); + else + info.feature &= ~BIT(1); + } + + ret = tpmi_process_ioctl(ISST_IF_PERF_SET_FEATURE, &info); + if (ret == -1) + return ret; + + return 0; +} + +static int tpmi_get_fact_info(struct isst_id *id, int level, int fact_bucket, + struct isst_fact_info *fact_info) +{ + struct isst_turbo_freq_info info; + int i, j; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = level; + + ret = tpmi_process_ioctl(ISST_IF_GET_TURBO_FREQ_INFO, &info); + if (ret == -1) + return ret; + + for (i = 0; i < info.max_clip_freqs; ++i) + fact_info->lp_ratios[i] = info.lp_clip_freq_mhz[i]; + + if (info.max_buckets > TRL_MAX_BUCKETS) + info.max_buckets = TRL_MAX_BUCKETS; + + if (info.max_trl_levels > TRL_MAX_LEVELS) + info.max_trl_levels = TRL_MAX_LEVELS; + + for (i = 0; i < info.max_trl_levels; ++i) { + for (j = 0; j < info.max_buckets; ++j) + fact_info->bucket_info[j].hp_ratios[i] = + info.trl_freq_mhz[i][j]; + } + + for (i = 0; i < info.max_buckets; ++i) + fact_info->bucket_info[i].hp_cores = info.bucket_core_counts[i]; + + return 0; +} + +static void _set_uncore_min_max(struct isst_id *id, int max, int freq) +{ + DIR *dir; + FILE *filep; + struct dirent *entry; + char buffer[512]; + unsigned int tmp_id; + int ret; + + dir = opendir("/sys/devices/system/cpu/intel_uncore_frequency/"); + if (!dir) + return; + + while ((entry = readdir(dir)) != NULL ) { + /* Check domain_id */ + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/intel_uncore_frequency/%s/domain_id", entry->d_name); + + filep = fopen(buffer, "r"); + if (!filep) + goto end; + + ret = fscanf(filep, "%u", &tmp_id); + fclose(filep); + if (ret != 1) + goto end; + + if (tmp_id != id->punit) + continue; + + /* Check package_id */ + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/intel_uncore_frequency/%s/package_id", entry->d_name); + + filep = fopen(buffer, "r"); + if (!filep) + goto end; + + ret = fscanf(filep, "%u", &tmp_id); + fclose(filep); + + if (ret != 1) + goto end; + + if (tmp_id != id->pkg) + continue; + + /* Found the right sysfs path, adjust and quit */ + if (max) + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/intel_uncore_frequency/%s/max_freq_khz", entry->d_name); + else + snprintf(buffer, sizeof(buffer), + "/sys/devices/system/cpu/intel_uncore_frequency/%s/min_freq_khz", entry->d_name); + + filep = fopen(buffer, "w"); + if (!filep) + goto end; + + fprintf(filep, "%d\n", freq); + fclose(filep); + break; + } + +end: + closedir(dir); +} + +static void tpmi_adjust_uncore_freq(struct isst_id *id, int config_index, + struct isst_pkg_ctdp_level_info *ctdp_level) +{ + struct isst_perf_level_data_info info; + int ret; + + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.level = config_index; + + ret = tpmi_process_ioctl(ISST_IF_GET_PERF_LEVEL_INFO, &info); + if (ret == -1) + return; + + ctdp_level->uncore_p0 = info.p0_fabric_freq_mhz; + ctdp_level->uncore_p1 = info.p1_fabric_freq_mhz; + ctdp_level->uncore_pm = info.pm_fabric_freq_mhz; + + if (ctdp_level->uncore_pm) + _set_uncore_min_max(id, 0, ctdp_level->uncore_pm * 100000); + + if (ctdp_level->uncore_p0) + _set_uncore_min_max(id, 1, ctdp_level->uncore_p0 * 100000); + + return; +} + +static int tpmi_get_clos_information(struct isst_id *id, int *enable, int *type) +{ + struct isst_core_power info; + int ret; + + info.get_set = 0; + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info); + if (ret == -1) + return ret; + + *enable = info.enable; + *type = info.priority_type; + + return 0; +} + +static int tpmi_pm_qos_config(struct isst_id *id, int enable_clos, + int priority_type) +{ + struct isst_core_power info; + int ret; + + info.get_set = 1; + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.enable = enable_clos; + info.priority_type = priority_type; + ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info); + if (ret == -1) + return ret; + + return 0; +} + +int tpmi_pm_get_clos(struct isst_id *id, int clos, + struct isst_clos_config *clos_config) +{ + struct isst_clos_param info; + int ret; + + info.get_set = 0; + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.clos = clos; + + ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info); + if (ret == -1) + return ret; + + clos_config->epp = 0; + clos_config->clos_prop_prio = info.prop_prio; + clos_config->clos_min = info.min_freq_mhz; + clos_config->clos_max = info.max_freq_mhz; + clos_config->clos_desired = 0; + + debug_printf("cpu:%d clos:%d min:%d max:%d\n", id->cpu, clos, + clos_config->clos_min, clos_config->clos_max); + + return 0; +} + +int tpmi_set_clos(struct isst_id *id, int clos, + struct isst_clos_config *clos_config) +{ + struct isst_clos_param info; + int ret; + + info.get_set = 1; + info.socket_id = id->pkg; + info.power_domain_id = id->punit; + info.clos = clos; + info.prop_prio = clos_config->clos_prop_prio; + + info.min_freq_mhz = clos_config->clos_min; + info.max_freq_mhz = clos_config->clos_max; + + if (info.min_freq_mhz <= 0xff) + info.min_freq_mhz *= 100; + if (info.max_freq_mhz <= 0xff) + info.max_freq_mhz *= 100; + + ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info); + if (ret == -1) + return ret; + + debug_printf("set cpu:%d clos:%d min:%d max:%d\n", id->cpu, clos, + clos_config->clos_min, clos_config->clos_max); + + return 0; +} + +static int tpmi_clos_get_assoc_status(struct isst_id *id, int *clos_id) +{ + struct isst_if_clos_assoc_cmds assoc_cmds; + int ret; + + assoc_cmds.cmd_count = 1; + assoc_cmds.get_set = 0; + assoc_cmds.punit_cpu_map = 1; + assoc_cmds.assoc_info[0].logical_cpu = find_phy_core_num(id->cpu); + assoc_cmds.assoc_info[0].socket_id = id->pkg; + assoc_cmds.assoc_info[0].power_domain_id = id->punit; + + ret = tpmi_process_ioctl(ISST_IF_CLOS_ASSOC, &assoc_cmds); + if (ret == -1) + return ret; + + *clos_id = assoc_cmds.assoc_info[0].clos; + + return 0; +} + +static int tpmi_clos_associate(struct isst_id *id, int clos_id) +{ + struct isst_if_clos_assoc_cmds assoc_cmds; + int ret; + + assoc_cmds.cmd_count = 1; + assoc_cmds.get_set = 1; + assoc_cmds.punit_cpu_map = 1; + assoc_cmds.assoc_info[0].logical_cpu = find_phy_core_num(id->cpu); + assoc_cmds.assoc_info[0].clos = clos_id; + assoc_cmds.assoc_info[0].socket_id = id->pkg; + assoc_cmds.assoc_info[0].power_domain_id = id->punit; + + ret = tpmi_process_ioctl(ISST_IF_CLOS_ASSOC, &assoc_cmds); + if (ret == -1) + return ret; + + return 0; +} + +static struct isst_platform_ops tpmi_ops = { + .get_disp_freq_multiplier = tpmi_get_disp_freq_multiplier, + .get_trl_max_levels = tpmi_get_trl_max_levels, + .get_trl_level_name = tpmi_get_trl_level_name, + .update_platform_param = tpmi_update_platform_param, + .is_punit_valid = tpmi_is_punit_valid, + .read_pm_config = tpmi_read_pm_config, + .get_config_levels = tpmi_get_config_levels, + .get_ctdp_control = tpmi_get_ctdp_control, + .get_tdp_info = tpmi_get_tdp_info, + .get_pwr_info = tpmi_get_pwr_info, + .get_coremask_info = tpmi_get_coremask_info, + .get_get_trl = tpmi_get_get_trl, + .get_get_trls = tpmi_get_get_trls, + .get_trl_bucket_info = tpmi_get_trl_bucket_info, + .set_tdp_level = tpmi_set_tdp_level, + .get_pbf_info = tpmi_get_pbf_info, + .set_pbf_fact_status = tpmi_set_pbf_fact_status, + .get_fact_info = tpmi_get_fact_info, + .adjust_uncore_freq = tpmi_adjust_uncore_freq, + .get_clos_information = tpmi_get_clos_information, + .pm_qos_config = tpmi_pm_qos_config, + .pm_get_clos = tpmi_pm_get_clos, + .set_clos = tpmi_set_clos, + .clos_get_assoc_status = tpmi_clos_get_assoc_status, + .clos_associate = tpmi_clos_associate, +}; + +struct isst_platform_ops *tpmi_get_platform_ops(void) +{ + return &tpmi_ops; +} diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index 674097289ebf..f0b96d7078d3 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -22,6 +22,9 @@ int isst_set_platform_ops(int api_version) case 1: isst_ops = mbox_get_platform_ops(); break; + case 2: + isst_ops = tpmi_get_platform_ops(); + break; default: isst_ops = NULL; break; diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 3efa7251001f..1984cc564fa9 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -143,12 +143,14 @@ struct isst_pkg_ctdp_level_info { int pkg_max_power; int fact; int t_proc_hot; + int cooling_type; int uncore_p0; int uncore_p1; int uncore_pm; int sse_p1; int avx2_p1; int avx512_p1; + int amx_p1; int mem_freq; size_t core_cpumask_size; cpu_set_t *core_cpumask; @@ -311,5 +313,6 @@ extern void hfi_exit(void); /* Interface specific callbacks */ extern struct isst_platform_ops *mbox_get_platform_ops(void); +extern struct isst_platform_ops *tpmi_get_platform_ops(void); #endif -- Gitee From 0022123e26e7ded4e42798a9a06eceb5f2652490 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 10 Aug 2022 17:14:11 +0800 Subject: [PATCH 08/27] tools/power/x86/intel-speed-select: Display punit info ANBZ: #9825 commit 46de87e39b871f926b429b14bde845412b541841 upstream. Display punit info for platforms with new api_version. For platforms with old api_version, don't display the punit info to be backward compatible. For example: Intel(R) Speed Select Technology Executing on CPU model:173[0xad] package-0 die-0 powerdomain-0 cpu-0 get-config-current_level:0 package-0 die-0 powerdomain-3 cpu--1 get-config-current_level:0 package-0 die-0 powerdomain-4 cpu--1 get-config-current_level:0 Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- .../x86/intel-speed-select/isst-display.c | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index af97ba5dbcc2..959d2d81e13a 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -169,21 +169,30 @@ static void format_and_print(FILE *outf, int level, char *header, char *value) static int print_package_info(struct isst_id *id, FILE *outf) { char header[256]; + int level = 1; if (out_format_is_json()) { - snprintf(header, sizeof(header), "package-%d:die-%d:cpu-%d", - id->pkg, id->die, id->cpu); - format_and_print(outf, 1, header, NULL); + if (api_version() > 1) + snprintf(header, sizeof(header), "package-%d:die-%d:powerdomain-%d:cpu-%d", + id->pkg, id->die, id->punit, id->cpu); + else + snprintf(header, sizeof(header), "package-%d:die-%d:cpu-%d", + id->pkg, id->die, id->cpu); + format_and_print(outf, level, header, NULL); return 1; } snprintf(header, sizeof(header), "package-%d", id->pkg); - format_and_print(outf, 1, header, NULL); + format_and_print(outf, level++, header, NULL); snprintf(header, sizeof(header), "die-%d", id->die); - format_and_print(outf, 2, header, NULL); + format_and_print(outf, level++, header, NULL); + if (api_version() > 1) { + snprintf(header, sizeof(header), "powerdomain-%d", id->punit); + format_and_print(outf, level++, header, NULL); + } snprintf(header, sizeof(header), "cpu-%d", id->cpu); - format_and_print(outf, 3, header, NULL); + format_and_print(outf, level, header, NULL); - return 3; + return level; } static void _isst_pbf_display_information(struct isst_id *id, FILE *outf, int level, @@ -306,22 +315,10 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l void isst_ctdp_display_core_info(struct isst_id *id, FILE *outf, char *prefix, unsigned int val, char *str0, char *str1) { - char header[256]; char value[256]; - int level = 1; + int level = print_package_info(id, outf); - if (out_format_is_json()) { - snprintf(header, sizeof(header), "package-%d:die-%d:cpu-%d", - id->pkg, id->die, id->cpu); - format_and_print(outf, level++, header, NULL); - } else { - snprintf(header, sizeof(header), "package-%d", id->pkg); - format_and_print(outf, level++, header, NULL); - snprintf(header, sizeof(header), "die-%d", id->die); - format_and_print(outf, level++, header, NULL); - snprintf(header, sizeof(header), "cpu-%d", id->cpu); - format_and_print(outf, level++, header, NULL); - } + level++; if (str0 && !val) snprintf(value, sizeof(value), "%s", str0); -- Gitee From 6882d9cf9ef32db1f1615297a865210ebc54d5f0 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 9 Aug 2022 03:29:23 +0800 Subject: [PATCH 09/27] tools/power/x86/intel-speed-select: Display amx_p1 and cooling_type ANBZ: #9825 commit 5f319081657cb653b55d2c9ef393fc5cd7aae6d4 upstream. amx_p1 and cooling_type are newly introduced for TPMI interface. Display amx_p1 and cooling_type info for platforms that support them. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-display.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 959d2d81e13a..8abb0335e091 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -421,6 +421,13 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level format_and_print(outf, level + 2, header, value); } + if (api_version() > 1 && ctdp_level->amx_p1) { + snprintf(header, sizeof(header), "base-frequency-amx(MHz)"); + snprintf(value, sizeof(value), "%d", + ctdp_level->amx_p1 * isst_get_disp_freq_multiplier()); + format_and_print(outf, level + 2, header, value); + } + if (ctdp_level->uncore_p1) { snprintf(header, sizeof(header), "uncore-frequency-base(MHz)"); snprintf(value, sizeof(value), "%d", @@ -435,6 +442,13 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level format_and_print(outf, level + 2, header, value); } + if (api_version() > 1) { + snprintf(header, sizeof(header), "cooling_type"); + snprintf(value, sizeof(value), "%d", + ctdp_level->cooling_type); + format_and_print(outf, level + 2, header, value); + } + snprintf(header, sizeof(header), "speed-select-turbo-freq"); if (ctdp_level->fact_support) { -- Gitee From f11030d54a05b5dc7ca0a4aeeadf5c5413540981 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 01:34:55 +0800 Subject: [PATCH 10/27] tools/power/x86/intel-speed-select: Allow display non-cpu power domain info ANBZ: #9825 commit 2e54ba89ec5286d041999e6566ae96267d33b002 upstream. Some power domain may not have CPUs associated, allow displaying information for these non-cpu power domains. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 8abb0335e091..1bfa8e4b39b2 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -682,8 +682,7 @@ void isst_display_result(struct isst_id *id, FILE *outf, char *feature, char *cm char value[256]; int level = 3; - if (id->cpu >= 0) - level = print_package_info(id, outf); + level = print_package_info(id, outf); snprintf(header, sizeof(header), "%s", feature); format_and_print(outf, level + 1, header, NULL); -- Gitee From 32ddc5df12a0a9f6fe42196940131d42941700c2 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 01:45:33 +0800 Subject: [PATCH 11/27] tools/power/x86/intel-speed-select: Prevent cpu clos config for non-cpu power domain ANBZ: #9825 commit 443bf104ef10cfc0d22698613f8ba178427d4538 upstream. Non-cpu power domain does not support cpu clos config. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-config.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 136da390b4b2..47431c577668 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -2077,6 +2077,9 @@ static void dump_clos_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, struct isst_clos_config clos_config; int ret; + if (id->cpu < 0) + return; + ret = isst_pm_get_clos(id, current_clos, &clos_config); if (ret) isst_display_error_info_message(1, "isst_pm_get_clos failed", 0, 0); @@ -2153,6 +2156,9 @@ static void set_clos_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, struct isst_clos_config clos_config; int ret; + if (id->cpu < 0) + return; + clos_config.epp = clos_epp; clos_config.clos_prop_prio = clos_prop_prio; clos_config.clos_min = clos_min; -- Gitee From cb9914982aa5104bc7c4d34d407baa690068ef46 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 01:51:15 +0800 Subject: [PATCH 12/27] tools/power/x86/intel-speed-select: Show level 0 name for new api_version ANBZ: #9825 commit ca7c5d5b75fdac884d2ad6acd7cb28e3f1dfee9c upstream. level 0 name is not shown in some case for backward compatibility reason. No need to keep this quirk for new api_version. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 1bfa8e4b39b2..4ad5df30ee83 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -284,7 +284,7 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l for (i = 0; i < trl_max_levels; i++) { if (fact_avx != 0xFF && !(fact_avx & (1 << i))) continue; - if (i == 0) + if (i == 0 && api_version() == 1) snprintf(header, sizeof(header), "high-priority-max-frequency(MHz)"); else @@ -301,7 +301,7 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l for (j = 0; j < trl_max_levels; j++) { /* No AVX level name for SSE to be consistent with previous formatting */ - if (j == 0) + if (j == 0 && api_version() == 1) snprintf(header, sizeof(header), "low-priority-max-frequency(MHz)"); else snprintf(header, sizeof(header), "low-priority-max-%s-frequency(MHz)", -- Gitee From b8c96af41e02d5d4e9961a9487702e707d0e9eee Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 21:18:03 +0800 Subject: [PATCH 13/27] tools/power/x86/intel-speed-select: Display fact info for non-cpu power domain ANBZ: #9825 commit b1e9b87b3b5999786685eb882afb99c468af94c1 upstream. Allow displaying SST-TF info for non-cpu power domain. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 4ad5df30ee83..1723e88411f5 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -253,7 +253,8 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l if (fact_bucket != 0xff && fact_bucket != j) continue; - if (!bucket_info[j].hp_cores) + /* core count must be valid for CPU power domain */ + if (!bucket_info[j].hp_cores && id->cpu >= 0) break; print = 1; -- Gitee From e5917c35c0af544a2fb45bb948b75cbb78e9d7cd Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 21:21:46 +0800 Subject: [PATCH 14/27] tools/power/x86/intel-speed-select: Hide invalid TRL level ANBZ: #9825 commit c5a295caefa33ce7599d7afbe7a2e9b1bc8d92a2 upstream. TRL levels with Zero ratio values is meaningless. Prevent these TRL levels from being displayed. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 1723e88411f5..d8b789b9656a 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -505,6 +505,9 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level } for (k = 0; k < trl_max_levels; k++) { + if (!ctdp_level->trl_ratios[k][0]) + continue; + snprintf(header, sizeof(header), "turbo-ratio-limits-%s", isst_get_trl_level_name(k)); format_and_print(outf, level + 2, header, NULL); -- Gitee From 79c64432b4054c005a049872e297a9c19b390f6a Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 18 Aug 2022 21:26:23 +0800 Subject: [PATCH 15/27] tools/power/x86/intel-speed-select: Remove cpu mask display for non-cpu power domain ANBZ: #9825 commit c7ff8ff3b29ee031a2194f67b5ceced9b77fdc21 upstream. Non CPU power domains will not have any CPUs. So don't display any CPU count or enable mask. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: subject and changelog edits] Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- .../x86/intel-speed-select/isst-display.c | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index d8b789b9656a..e3573895c8b0 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -356,31 +356,33 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level ctdp_level->level); format_and_print(outf, level + 1, header, NULL); - snprintf(header, sizeof(header), "cpu-count"); - j = get_cpu_count(id); - snprintf(value, sizeof(value), "%d", j); - format_and_print(outf, level + 2, header, value); - - j = CPU_COUNT_S(ctdp_level->core_cpumask_size, - ctdp_level->core_cpumask); - if (j) { - snprintf(header, sizeof(header), "enable-cpu-count"); + if (id->cpu >= 0) { + snprintf(header, sizeof(header), "cpu-count"); + j = get_cpu_count(id); snprintf(value, sizeof(value), "%d", j); format_and_print(outf, level + 2, 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, level + 2, header, value); + j = CPU_COUNT_S(ctdp_level->core_cpumask_size, + ctdp_level->core_cpumask); + if (j) { + snprintf(header, sizeof(header), "enable-cpu-count"); + snprintf(value, sizeof(value), "%d", j); + format_and_print(outf, level + 2, 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, level + 2, 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, level + 2, 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, level + 2, header, value); + } } snprintf(header, sizeof(header), "thermal-design-power-ratio"); -- Gitee From 74a978081db7c47f9a7aca1e8c38f90b58e38a52 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 2 Feb 2023 15:55:25 +0800 Subject: [PATCH 16/27] tools/power/x86/intel-speed-select: Avoid setting duplicate tdp level ANBZ: #9825 commit 14f0cf6cfa53a3a4f2f713b1d54eb71e96ff34cb upstream. If the new TDP level requetsted is same as the current TDP level, don't call into driver to change level. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: changelog edits] Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- .../x86/intel-speed-select/isst-config.c | 79 +++++++++++-------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 47431c577668..b10c6ecd9777 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1229,46 +1229,59 @@ static void adjust_scaling_max_from_base_freq(int cpu); static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3, void *arg4) { + struct isst_pkg_ctdp pkg_dev; int ret; + ret = isst_get_ctdp_levels(id, &pkg_dev); + if (ret) { + isst_display_error_info_message(1, "Get TDP level failed", 0, 0); + isst_ctdp_display_information_end(outf); + exit(1); + } + + if (pkg_dev.current_level == tdp_level) { + debug_printf("TDP level already set. Skipped\n"); + goto display_result; + } + ret = isst_set_tdp_level(id, tdp_level); if (ret) { isst_display_error_info_message(1, "Set TDP level failed", 0, 0); isst_ctdp_display_information_end(outf); exit(1); - } else { - isst_display_result(id, outf, "perf-profile", "set_tdp_level", - ret); - if (force_online_offline) { - struct isst_pkg_ctdp_level_info ctdp_level; - - /* Wait for updated base frequencies */ - usleep(2000); - - /* Adjusting uncore freq */ - isst_adjust_uncore_freq(id, tdp_level, &ctdp_level); - - fprintf(stderr, "Option is set to online/offline\n"); - ctdp_level.core_cpumask_size = - alloc_cpu_set(&ctdp_level.core_cpumask); - ret = isst_get_coremask_info(id, tdp_level, &ctdp_level); - if (ret) { - isst_display_error_info_message(1, "Can't get coremask, online/offline option is ignored", 0, 0); - return; - } - if (ctdp_level.cpu_count) { - int i, max_cpus = get_topo_max_cpus(); - for (i = 0; i < max_cpus; ++i) { - if (!is_cpu_in_power_domain(i, id)) - continue; - if (CPU_ISSET_S(i, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask)) { - fprintf(stderr, "online cpu %d\n", i); - set_cpu_online_offline(i, 1); - adjust_scaling_max_from_base_freq(i); - } else { - fprintf(stderr, "offline cpu %d\n", i); - set_cpu_online_offline(i, 0); - } + } + +display_result: + isst_display_result(id, outf, "perf-profile", "set_tdp_level", ret); + if (force_online_offline) { + struct isst_pkg_ctdp_level_info ctdp_level; + + /* Wait for updated base frequencies */ + usleep(2000); + + /* Adjusting uncore freq */ + isst_adjust_uncore_freq(id, tdp_level, &ctdp_level); + + fprintf(stderr, "Option is set to online/offline\n"); + ctdp_level.core_cpumask_size = + alloc_cpu_set(&ctdp_level.core_cpumask); + ret = isst_get_coremask_info(id, tdp_level, &ctdp_level); + if (ret) { + isst_display_error_info_message(1, "Can't get coremask, online/offline option is ignored", 0, 0); + return; + } + if (ctdp_level.cpu_count) { + int i, max_cpus = get_topo_max_cpus(); + for (i = 0; i < max_cpus; ++i) { + if (!is_cpu_in_power_domain(i, id)) + continue; + if (CPU_ISSET_S(i, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask)) { + fprintf(stderr, "online cpu %d\n", i); + set_cpu_online_offline(i, 1); + adjust_scaling_max_from_base_freq(i); + } else { + fprintf(stderr, "offline cpu %d\n", i); + set_cpu_online_offline(i, 0); } } } -- Gitee From 9fb4f7445cb46dab1c2d491cda73b60359ea749d Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 13 Sep 2022 20:23:19 +0800 Subject: [PATCH 17/27] tools/power/x86/intel-speed-select: Add cpu id check ANBZ: #9825 commit d0e12c46f518620551d719b19b93777dafd0b5e6 upstream. Some operations applies to cpu-power-domain only. Add check for cpu id for these functions. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-config.c | 16 ++++++++++++++-- tools/power/x86/intel-speed-select/isst-core.c | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index b10c6ecd9777..a04005622b32 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -800,6 +800,9 @@ void set_cpu_mask_from_punit_coremask(struct isst_id *id, unsigned long long cor { int i, cnt = 0; + if (id->cpu < 0) + return; + *cpu_cnt = 0; for (i = 0; i < 64; ++i) { @@ -1253,7 +1256,7 @@ static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, vo display_result: isst_display_result(id, outf, "perf-profile", "set_tdp_level", ret); - if (force_online_offline) { + if (force_online_offline && id->cpu >= 0) { struct isst_pkg_ctdp_level_info ctdp_level; /* Wait for updated base frequencies */ @@ -1547,6 +1550,9 @@ static void set_scaling_min_to_cpuinfo_max(struct isst_id *id) { int i; + if (id->cpu < 0) + return; + for (i = 0; i < get_topo_max_cpus(); ++i) { if (!is_cpu_in_power_domain(i, id)) continue; @@ -1564,6 +1570,9 @@ static void set_scaling_min_to_cpuinfo_min(struct isst_id *id) { int i; + if (id->cpu < 0) + return; + for (i = 0; i < get_topo_max_cpus(); ++i) { if (!is_cpu_in_power_domain(i, id)) continue; @@ -1643,6 +1652,9 @@ static int set_pbf_core_power(struct isst_id *id) struct isst_pkg_ctdp pkg_dev; int ret; + if (id->cpu < 0) + return 0; + ret = isst_get_ctdp_levels(id, &pkg_dev); if (ret) { debug_printf("isst_get_ctdp_levels failed"); @@ -1888,7 +1900,7 @@ static void set_fact_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *a struct isst_pkg_ctdp pkg_dev; ret = isst_get_ctdp_levels(id, &pkg_dev); - if (!ret) + if (!ret && id->cpu >= 0) ret = isst_set_trl(id, fact_trl); if (ret && auto_mode) isst_pm_qos_config(id, 0, 0); diff --git a/tools/power/x86/intel-speed-select/isst-core.c b/tools/power/x86/intel-speed-select/isst-core.c index f0b96d7078d3..f55fef4c13a7 100644 --- a/tools/power/x86/intel-speed-select/isst-core.c +++ b/tools/power/x86/intel-speed-select/isst-core.c @@ -287,6 +287,9 @@ int isst_set_trl_from_current_tdp(struct isst_id *id, unsigned long long trl) unsigned long long msr_trl; int ret; + if (id->cpu < 0) + return 0; + if (trl) { msr_trl = trl; } else { -- Gitee From 82b3485d245d7bd20c9eede56584d047f6cd4a62 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 7 Jan 2023 21:45:42 +0800 Subject: [PATCH 18/27] tools/power/x86/intel-speed-select: Fix clos-max display with TPMI I/F ANBZ: #9825 commit 137ba3b13aacf80b64d363dd7cff69c2aed161f0 upstream. Comparing clos_config->clos_max with 255 is broken with TPMI I/F because of different isst_get_disp_freq_multiplier() used. Checking for clos_config->clos_max * isst_get_disp_freq_multiplier() instead. Signed-off-by: Zhang Rui Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index e3573895c8b0..218fb317f7ad 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -606,7 +606,7 @@ void isst_clos_display_information(struct isst_id *id, FILE *outf, int clos, format_and_print(outf, level + 2, header, value); snprintf(header, sizeof(header), "clos-max"); - if (clos_config->clos_max == 0xff) + if ((clos_config->clos_max * isst_get_disp_freq_multiplier()) == 25500) snprintf(value, sizeof(value), "Max Turbo frequency"); else snprintf(value, sizeof(value), "%d MHz", clos_config->clos_max * isst_get_disp_freq_multiplier()); -- Gitee From 3fa7b1d32c551e03e1a923d1cd5c33e6948b8f29 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 22 Feb 2023 03:26:29 -0800 Subject: [PATCH 19/27] tools/power/x86/intel-speed-select: Add missing free cpuset ANBZ: #9825 commit 57797f19d5a78b5a84b7452790f7da22865f6420 upstream. During perf level change cpuset is allocated but not freed. Add free_cpu_set() in success and failure path. Although this is not an issue, as the program will exit after processing of online/offline, but for completeness add the free_cpu_set(). Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-config.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index a04005622b32..a9bd87b4d4ee 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -1271,7 +1271,7 @@ static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, vo ret = isst_get_coremask_info(id, tdp_level, &ctdp_level); if (ret) { isst_display_error_info_message(1, "Can't get coremask, online/offline option is ignored", 0, 0); - return; + goto free_mask; } if (ctdp_level.cpu_count) { int i, max_cpus = get_topo_max_cpus(); @@ -1288,6 +1288,8 @@ static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, vo } } } +free_mask: + free_cpu_set(ctdp_level.core_cpumask); } } -- Gitee From 44b61a1f99228a392409ea56e3a5fad70adc03f5 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 22 Feb 2023 03:42:19 -0800 Subject: [PATCH 20/27] tools/power/x86/intel-speed-select: Use cgroup v2 isolation ANBZ: #9825 commit 997074df658e444e79a5294b685b77b08a3c414c upstream. On supported systems, it is possiible to isolate CPUs instead of CPU online/offline. This is optional and can be specified using -g option when running as daemon or in combination with -o option for SST-PP level change. CPU isolation doesn't isolate IRQs. So IRQs needs to be moved away from isoolated CPUs. This can be done via IRQ sysfs or irqbalance daemon. The IRQ balance daemon is also capable to parse thermal HFI messages to move IRQs away from CPUS, which are supposed be isolated. But this requires version released after July 2022. Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- .../x86/intel-speed-select/isst-config.c | 155 +++++++++++++++++- .../x86/intel-speed-select/isst-daemon.c | 15 +- tools/power/x86/intel-speed-select/isst.h | 5 + 3 files changed, 173 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index a9bd87b4d4ee..c4d00426cb6a 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -44,6 +44,7 @@ static int cmd_help; static int force_online_offline; static int auto_mode; static int fact_enable_fail; +static int cgroupv2; /* clos related */ static int current_clos = -1; @@ -834,7 +835,137 @@ int find_phy_core_num(int logical_cpu) return -EINVAL; } +int use_cgroupv2(void) +{ + return cgroupv2; +} + +int enable_cpuset_controller(void) +{ + int fd, ret; + + fd = open("/sys/fs/cgroup/cgroup.subtree_control", O_RDWR, 0); + if (fd < 0) { + debug_printf("Can't activate cpuset controller\n"); + debug_printf("Either you are not root user or CGroup v2 is not supported\n"); + return fd; + } + + ret = write(fd, " +cpuset", strlen(" +cpuset")); + close(fd); + + if (ret == -1) { + debug_printf("Can't activate cpuset controller: Write failed\n"); + return ret; + } + + return 0; +} + +int isolate_cpus(struct isst_id *id, int mask_size, cpu_set_t *cpu_mask, int level) +{ + int i, first, curr_index, index, ret, fd; + static char str[512], dir_name[64]; + static char cpuset_cpus[128]; + int str_len = sizeof(str); + DIR *dir; + + snprintf(dir_name, sizeof(dir_name), "/sys/fs/cgroup/%d-%d-%d", id->pkg, id->die, id->punit); + dir = opendir(dir_name); + if (!dir) { + ret = mkdir(dir_name, 0744); + if (ret) { + debug_printf("Can't create dir:%s errno:%d\n", dir_name, errno); + return ret; + } + } + closedir(dir); + + if (!level) { + sprintf(cpuset_cpus, "%s/cpuset.cpus.partition", dir_name); + + fd = open(cpuset_cpus, O_RDWR, 0); + if (fd < 0) { + return fd; + } + + ret = write(fd, "member", strlen("member")); + if (ret == -1) { + printf("Can't update to member\n"); + return ret; + } + + return 0; + } + + if (!CPU_COUNT_S(mask_size, cpu_mask)) { + return -1; + } + curr_index = 0; + first = 1; + str[0] = '\0'; + for (i = 0; i < get_topo_max_cpus(); ++i) { + if (!is_cpu_in_power_domain(i, id)) + continue; + + if (CPU_ISSET_S(i, mask_size, cpu_mask)) + continue; + + if (!first) { + index = snprintf(&str[curr_index], + str_len - curr_index, ","); + curr_index += index; + if (curr_index >= str_len) + break; + } + index = snprintf(&str[curr_index], str_len - curr_index, "%d", + i); + curr_index += index; + if (curr_index >= str_len) + break; + first = 0; + } + + debug_printf("isolated CPUs list: package:%d curr_index:%d [%s]\n", id->pkg, curr_index ,str); + + snprintf(cpuset_cpus, sizeof(cpuset_cpus), "%s/cpuset.cpus", dir_name); + + fd = open(cpuset_cpus, O_RDWR, 0); + if (fd < 0) { + return fd; + } + + ret = write(fd, str, strlen(str)); + close(fd); + + if (ret == -1) { + debug_printf("Can't activate cpuset controller: Write failed\n"); + return ret; + } + + snprintf(cpuset_cpus, sizeof(cpuset_cpus), "%s/cpuset.cpus.partition", dir_name); + + fd = open(cpuset_cpus, O_RDWR, 0); + if (fd < 0) { + return fd; + } + + ret = write(fd, "isolated", strlen("isolated")); + if (ret == -1) { + debug_printf("Can't update to isolated\n"); + ret = write(fd, "root", strlen("root")); + if (ret == -1) + debug_printf("Can't update to root\n"); + } + + close(fd); + + if (ret < 0) + return ret; + + return 0; +} static int isst_fill_platform_info(void) { @@ -1273,6 +1404,23 @@ static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, vo isst_display_error_info_message(1, "Can't get coremask, online/offline option is ignored", 0, 0); goto free_mask; } + + if (use_cgroupv2()) { + int ret; + + fprintf(stderr, "Using cgroup v2 in lieu of online/offline\n"); + ret = enable_cpuset_controller(); + if (ret) + goto use_offline; + + ret = isolate_cpus(id, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask, tdp_level); + if (ret) + goto use_offline; + + goto free_mask; + } + +use_offline: if (ctdp_level.cpu_count) { int i, max_cpus = get_topo_max_cpus(); for (i = 0; i < max_cpus; ++i) { @@ -2787,6 +2935,7 @@ static void usage(void) printf("\t[-b|--oob : Start a daemon to process HFI events for perf profile change from Out of Band agent.\n"); printf("\t[-n|--no-daemon : Don't run as daemon. By default --oob will turn on daemon mode\n"); printf("\t[-w|--delay : Delay for reading config level state change in OOB poll mode.\n"); + printf("\t[-g|--cgroupv2 : Try to use cgroup v2 CPU isolation instead of CPU online/offline.\n"); printf("\nResult format\n"); printf("\tResult display uses a common format for each command:\n"); printf("\tResults are formatted in text/JSON with\n"); @@ -2839,6 +2988,7 @@ static void cmdline(int argc, char **argv) { "oob", no_argument, 0, 'b' }, { "no-daemon", no_argument, 0, 'n' }, { "poll-interval", required_argument, 0, 'w' }, + { "cgroupv2", required_argument, 0, 'g' }, { 0, 0, 0, 0 } }; @@ -2869,7 +3019,7 @@ static void cmdline(int argc, char **argv) goto out; progname = argv[0]; - while ((opt = getopt_long_only(argc, argv, "+c:df:hio:vabw:n", long_options, + while ((opt = getopt_long_only(argc, argv, "+c:df:hio:vabw:ng", long_options, &option_index)) != -1) { switch (opt) { case 'a': @@ -2928,6 +3078,9 @@ static void cmdline(int argc, char **argv) } poll_interval = ret; break; + case 'g': + cgroupv2 = 1; + break; default: usage(); } diff --git a/tools/power/x86/intel-speed-select/isst-daemon.c b/tools/power/x86/intel-speed-select/isst-daemon.c index 6fa2942b5e12..12053fa43542 100644 --- a/tools/power/x86/intel-speed-select/isst-daemon.c +++ b/tools/power/x86/intel-speed-select/isst-daemon.c @@ -83,6 +83,19 @@ void process_level_change(struct isst_id *id) return; } + if (use_cgroupv2()) { + int ret; + + ret = enable_cpuset_controller(); + if (ret) + goto use_offline; + + isolate_cpus(id, ctdp_level.core_cpumask_size, ctdp_level.core_cpumask, pkg_dev.current_level); + + goto free_mask; + } + +use_offline: if (ctdp_level.cpu_count) { int i, max_cpus = get_topo_max_cpus(); for (i = 0; i < max_cpus; ++i) { @@ -97,7 +110,7 @@ void process_level_change(struct isst_id *id) } } } - +free_mask: free_cpu_set(ctdp_level.core_cpumask); } diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 1984cc564fa9..6a37c26b1ef7 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -315,4 +315,9 @@ extern void hfi_exit(void); extern struct isst_platform_ops *mbox_get_platform_ops(void); extern struct isst_platform_ops *tpmi_get_platform_ops(void); +/* Cgroup related interface */ +extern int enable_cpuset_controller(void); +extern int isolate_cpus(struct isst_id *id, int mask_size, cpu_set_t *cpu_mask, int level); +extern int use_cgroupv2(void); + #endif -- Gitee From 0dc4e7e6bf0ed66dd98bd25c5449c5c9b16754cb Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 23 Feb 2023 05:59:24 -0800 Subject: [PATCH 21/27] tools/power/x86/intel-speed-select: Display AMX base frequency ANBZ: #9825 commit a835ff56dd9ce2dfc53526085ba8efc2807b9bcb upstream. AMX frequency is present in non TPMI platforms also. When platform supports, the value is non zero. So, display AMX base frequency when non zero, irrespective of platform API version. Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-core-mbox.c | 5 +++-- tools/power/x86/intel-speed-select/isst-display.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 6eafef925d1a..6951a9c31dc5 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -383,10 +383,11 @@ static void _get_p1_info(struct isst_id *id, int config_index, 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; + ctdp_level->amx_p1 = (resp & GENMASK(31, 24)) >> 24; debug_printf( - "cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d\n", + "cpu:%d ctdp:%d CONFIG_TDP_GET_P1_INFO resp:%x sse_p1:%d avx2_p1:%d avx512_p1:%d amx_p1:%d\n", id->cpu, config_index, resp, ctdp_level->sse_p1, - ctdp_level->avx2_p1, ctdp_level->avx512_p1); + ctdp_level->avx2_p1, ctdp_level->avx512_p1, ctdp_level->amx_p1); } static void _get_uncore_mem_freq(struct isst_id *id, int config_index, diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 218fb317f7ad..0e364b35f093 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -424,7 +424,7 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level format_and_print(outf, level + 2, header, value); } - if (api_version() > 1 && ctdp_level->amx_p1) { + if (ctdp_level->amx_p1) { snprintf(header, sizeof(header), "base-frequency-amx(MHz)"); snprintf(value, sizeof(value), "%d", ctdp_level->amx_p1 * isst_get_disp_freq_multiplier()); -- Gitee From 3b79a53ffd884d7a9f660eab954ab6c374d7c70c Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Wed, 22 Feb 2023 22:53:02 -0800 Subject: [PATCH 22/27] tools/power/x86/intel-speed-select: Identify Emerald Rapids ANBZ: #9825 commit 1d54b139f43482a5d394f26ce47aa9949dec6e76 upstream. There are some differences compared to Sapphire Rapids. So, add a separate API. Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-config.c | 11 ++++++++++- tools/power/x86/intel-speed-select/isst-core-mbox.c | 2 +- tools/power/x86/intel-speed-select/isst.h | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index c4d00426cb6a..2ad8726edc06 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -114,12 +114,21 @@ int is_skx_based_platform(void) int is_spr_platform(void) { - if (cpu_model == 0x8F || cpu_model == 0xCF) + if (cpu_model == 0x8F) return 1; return 0; } +int is_emr_platform(void) +{ + if (cpu_model == 0xCF) + return 1; + + return 0; +} + + int is_icx_platform(void) { if (cpu_model == 0x6A || cpu_model == 0x6C) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index 6951a9c31dc5..c860be30fe5e 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -404,7 +404,7 @@ static void _get_uncore_mem_freq(struct isst_id *id, int config_index, } ctdp_level->mem_freq = resp & GENMASK(7, 0); - if (is_spr_platform()) { + if (is_spr_platform() || is_emr_platform()) { ctdp_level->mem_freq *= 200; } else if (is_icx_platform()) { if (ctdp_level->mem_freq < 7) { diff --git a/tools/power/x86/intel-speed-select/isst.h b/tools/power/x86/intel-speed-select/isst.h index 6a37c26b1ef7..54fc21575d56 100644 --- a/tools/power/x86/intel-speed-select/isst.h +++ b/tools/power/x86/intel-speed-select/isst.h @@ -298,6 +298,7 @@ extern int isst_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap); extern void isst_display_error_info_message(int error, char *msg, int arg_valid, int arg); extern int is_skx_based_platform(void); extern int is_spr_platform(void); +extern int is_emr_platform(void); extern int is_icx_platform(void); extern void isst_trl_display_information(struct isst_id *id, FILE *outf, unsigned long long trl); -- Gitee From d1164762e6d06d5893a776d84cc810cb3bd6db4e Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 23 Feb 2023 06:36:46 -0800 Subject: [PATCH 23/27] tools/power/x86/intel-speed-select: Change TRL display for Emerald Rapids ANBZ: #9825 commit 2c00056f54299983009c13a8790fa004e5337d16 upstream. Emerald Rapids doesn't specify TRL (Turbo Ratio Limits) based instruction types. Instead it specifies 5 TRL levels, which can be anyone of the instruction types. Increase TRL levels to 5 for Emerald Rapids. Also change display to show by level number. Show only non zero level values. Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- .../power/x86/intel-speed-select/isst-core-mbox.c | 15 +++++++++++++++ tools/power/x86/intel-speed-select/isst-display.c | 9 ++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-core-mbox.c b/tools/power/x86/intel-speed-select/isst-core-mbox.c index c860be30fe5e..24bea57f4ff5 100644 --- a/tools/power/x86/intel-speed-select/isst-core-mbox.c +++ b/tools/power/x86/intel-speed-select/isst-core-mbox.c @@ -8,6 +8,8 @@ static int mbox_delay; static int mbox_retries = 3; +#define MAX_TRL_LEVELS_EMR 5 + static int mbox_get_disp_freq_multiplier(void) { return DISP_FREQ_MULTIPLIER; @@ -15,11 +17,24 @@ static int mbox_get_disp_freq_multiplier(void) static int mbox_get_trl_max_levels(void) { + if (is_emr_platform()) + return MAX_TRL_LEVELS_EMR; + return 3; } static char *mbox_get_trl_level_name(int level) { + if (is_emr_platform()) { + static char level_str[18]; + + if (level >= MAX_TRL_LEVELS_EMR) + return NULL; + + snprintf(level_str, sizeof(level_str), "level-%d", level); + return level_str; + } + switch (level) { case 0: return "sse"; diff --git a/tools/power/x86/intel-speed-select/isst-display.c b/tools/power/x86/intel-speed-select/isst-display.c index 0e364b35f093..0403d42ab1ba 100644 --- a/tools/power/x86/intel-speed-select/isst-display.c +++ b/tools/power/x86/intel-speed-select/isst-display.c @@ -283,9 +283,9 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l bucket_info[j].hp_cores); format_and_print(outf, base_level + 2, header, value); for (i = 0; i < trl_max_levels; i++) { - if (fact_avx != 0xFF && !(fact_avx & (1 << i))) + if (!bucket_info[j].hp_ratios[i] || (fact_avx != 0xFF && !(fact_avx & (1 << i)))) continue; - if (i == 0 && api_version() == 1) + if (i == 0 && api_version() == 1 && !is_emr_platform()) snprintf(header, sizeof(header), "high-priority-max-frequency(MHz)"); else @@ -301,8 +301,11 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l format_and_print(outf, base_level + 1, header, NULL); for (j = 0; j < trl_max_levels; j++) { + if (!fact_info->lp_ratios[j]) + continue; + /* No AVX level name for SSE to be consistent with previous formatting */ - if (j == 0 && api_version() == 1) + if (j == 0 && api_version() == 1 && !is_emr_platform()) snprintf(header, sizeof(header), "low-priority-max-frequency(MHz)"); else snprintf(header, sizeof(header), "low-priority-max-%s-frequency(MHz)", -- Gitee From 2d73a22a39df798de2cf0f8f796ca6a68c612fc5 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 17 Oct 2022 19:34:14 +0800 Subject: [PATCH 24/27] tools/power/x86/intel-speed-select: Update version ANBZ: #9825 commit 19799d3ae2edec99435b792cfe76b1cba74665fe upstream. Update tool and supported API version. This is the first version which supports newer Xeon platforms with TPMI support. Signed-off-by: Zhang Rui [srinivas.pandruvada@linux.intel.com: subject and changelog edits] Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 2ad8726edc06..2ca0cedd418f 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -15,9 +15,9 @@ struct process_cmd_struct { int arg; }; -static const char *version_str = "v1.14"; +static const char *version_str = "v1.15"; -static const int supported_api_ver = 1; +static const int supported_api_ver = 2; static struct isst_if_platform_info isst_platform_info; static char *progname; static int debug_flag; -- Gitee From e401dfab0bfeac7ae627d238c35b65897e993297 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 18 May 2023 09:49:35 -0700 Subject: [PATCH 25/27] tools/power/x86/intel-speed-select: Adjust scope of core-power config ANBZ: #9825 commit 4ebde55b7de1a25a9e20ae91e42157798ef8e958 upstream. When core-power configuration or enabled is modified, this is only done for compute dies. But the config must also be set to cores with no CPUs. Without this the configuration is not affective. On displaying config information, allow display for non compute dies also. Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- .../x86/intel-speed-select/isst-config.c | 3 -- .../x86/intel-speed-select/isst-core-tpmi.c | 43 +++++++++++++++---- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 2ca0cedd418f..5f8905a788a8 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -2261,9 +2261,6 @@ static void dump_clos_config_for_cpu(struct isst_id *id, void *arg1, void *arg2, struct isst_clos_config clos_config; int ret; - if (id->cpu < 0) - return; - ret = isst_pm_get_clos(id, current_clos, &clos_config); if (ret) isst_display_error_info_message(1, "isst_pm_get_clos failed", 0, 0); diff --git a/tools/power/x86/intel-speed-select/isst-core-tpmi.c b/tools/power/x86/intel-speed-select/isst-core-tpmi.c index 19caa9c78d41..3458768562e5 100644 --- a/tools/power/x86/intel-speed-select/isst-core-tpmi.c +++ b/tools/power/x86/intel-speed-select/isst-core-tpmi.c @@ -641,16 +641,30 @@ static int tpmi_pm_qos_config(struct isst_id *id, int enable_clos, int priority_type) { struct isst_core_power info; - int ret; + int i, ret, saved_punit; info.get_set = 1; info.socket_id = id->pkg; info.power_domain_id = id->punit; info.enable = enable_clos; info.priority_type = priority_type; - ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info); - if (ret == -1) - return ret; + + saved_punit = id->punit; + + /* Set for all other dies also. This is per package setting */ + for (i = 0; i < MAX_PUNIT_PER_DIE; i++) { + id->punit = i; + if (isst_is_punit_valid(id)) { + info.power_domain_id = i; + ret = tpmi_process_ioctl(ISST_IF_CORE_POWER_STATE, &info); + if (ret == -1) { + id->punit = saved_punit; + return ret; + } + } + } + + id->punit = saved_punit; return 0; } @@ -686,7 +700,7 @@ int tpmi_set_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_config) { struct isst_clos_param info; - int ret; + int i, ret, saved_punit; info.get_set = 1; info.socket_id = id->pkg; @@ -702,9 +716,22 @@ int tpmi_set_clos(struct isst_id *id, int clos, if (info.max_freq_mhz <= 0xff) info.max_freq_mhz *= 100; - ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info); - if (ret == -1) - return ret; + saved_punit = id->punit; + + /* Set for all other dies also. This is per package setting */ + for (i = 0; i < MAX_PUNIT_PER_DIE; i++) { + id->punit = i; + if (isst_is_punit_valid(id)) { + info.power_domain_id = i; + ret = tpmi_process_ioctl(ISST_IF_CLOS_PARAM, &info); + if (ret == -1) { + id->punit = saved_punit; + return ret; + } + } + } + + id->punit = saved_punit; debug_printf("set cpu:%d clos:%d min:%d max:%d\n", id->cpu, clos, clos_config->clos_min, clos_config->clos_max); -- Gitee From bb4101288f5d0b944686b4a2c48d038b8b070021 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 22 May 2023 12:55:24 -0700 Subject: [PATCH 26/27] tools/power/x86/intel-speed-select: Fix json formatting issue ANBZ: #9825 commit fcf127839e6a37bfb0f3ac102c8bc7988f627df2 upstream. Fix two issues related to JSON formatting: 1. intel-speed-select -f json -o cp.out -c 1 core-power assoc -c 1 Intel(R) Speed Select Technology Executing on CPU model:143[0x8f] [root@spr-bkc bin]# cat cp.out | jq . "package-0:die-0:cpu-1" 2. intel-speed-select -f json -o tf.out turbo-freq enable -a Intel(R) Speed Select Technology Executing on CPU model:143[0x8f] [root@spr-bkc bin]# cat tf.out | jq . { "package-0:die-0:cpu-0": { "turbo-freq": { "enable": "success" } }, "package-1:die-0:cpu-48": { "turbo-freq": { "enable": "success" } } } "turbo-freq --auto" parse error: Expected string key before ':' at line 17, column 24 Both of these issues needed proper closing "}" for JSON. Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-config.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index 5f8905a788a8..b3c205c4511d 100644 --- a/tools/power/x86/intel-speed-select/isst-config.c +++ b/tools/power/x86/intel-speed-select/isst-config.c @@ -2113,7 +2113,6 @@ static void set_fact_enable(int arg) else for_each_online_power_domain_in_set(set_fact_for_cpu, NULL, NULL, NULL, &enable); - isst_ctdp_display_information_end(outf); if (!fact_enable_fail && enable && auto_mode) { /* @@ -2192,10 +2191,13 @@ static void set_fact_enable(int arg) isst_display_result(&id, outf, "turbo-freq --auto", "enable", 0); } + isst_ctdp_display_information_end(outf); + return; error_disp: isst_display_result(&id, outf, "turbo-freq --auto", "enable", ret); + isst_ctdp_display_information_end(outf); } @@ -2434,12 +2436,16 @@ static void set_clos_assoc(int arg) isst_display_error_info_message(1, "Invalid clos id\n", 0, 0); exit(0); } + + isst_ctdp_display_information_start(outf); + if (max_target_cpus) for_each_online_target_cpu_in_set(set_clos_assoc_for_cpu, NULL, NULL, NULL, NULL); else { isst_display_error_info_message(1, "Invalid target cpu. Specify with [-c|--cpu]", 0, 0); } + isst_ctdp_display_information_end(outf); } static void get_clos_assoc_for_cpu(struct isst_id *id, void *arg1, void *arg2, void *arg3, -- Gitee From 49c4bd6555f46402d27f6e9bf7d31d66ad12e071 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Mon, 12 Jun 2023 16:10:37 -0700 Subject: [PATCH 27/27] tools/power/x86/intel-speed-select: v1.16 release ANBZ: #9825 commit 7244720ac137e3193db11b009fc33c0dd4e999c9 upstream. This version addresses issues with core power configuration for non CPU dies. Also address issue with JSON formatting of output. Signed-off-by: Srinivas Pandruvada Signed-off-by: Xuchun Shang --- tools/power/x86/intel-speed-select/isst-config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/power/x86/intel-speed-select/isst-config.c b/tools/power/x86/intel-speed-select/isst-config.c index b3c205c4511d..a73346e854b8 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.15"; +static const char *version_str = "v1.16"; static const int supported_api_ver = 2; static struct isst_if_platform_info isst_platform_info; -- Gitee