Merge remote-tracking branch 'intel-speed-select/intel-sst' into review-hans

Summary of changes:

Till the commit:
"tools/power/x86/intel-speed-select: Get punit core mapping
information"

All patches just lays foundation for adding new hardware interface
in addition to existing MSR/MMIO interface.

All patches prefixed with "Abstract" just adds individual hardware
callback for functions called from the core processing.

The mailbox processing is abstracted to a new file with callbacks.

In addition some changes to reduce duplicated code for display
of TRL level.

Patch "Introduce Punit ID concept and add related API" add further
abstraction in addition to existing package and die scope.

-----------
tools/power/x86/intel-speed-select: Get punit core mapping information
-Adds a new way to get package/die/punit information for each CPU.
-----------

Introduce TPMI interface support
- Implement all abstracted callbacks above to use TPMI IOCTL interface.
-----------

tools/power/x86/intel-speed-select: Display punit info
- With TPMI the granularity is per punit, which can be multiple in a
package/die.
----------

tools/power/x86/intel-speed-select: Remove cpu mask display for non-cpu
power domain
tools/power/x86/intel-speed-select: Display fact info for non-cpu power
domain
-There are some power domains with no CPUs, the above patches adds CPU
as invalid for these domains
----------

tools/power/x86/intel-speed-select: Use cgroup v2 isolation
- Adds new option to use Cgroup CPU isolation instead of offline of CPUs
----------

tools/power/x86/intel-speed-select: Change TRL display for Emerald Rapids
- Emerald Rapid has multiple TRL levels and moves away from TRL level
based on instruction type
This commit is contained in:
Hans de Goede 2023-03-27 15:03:06 +02:00
commit fd5aadaa21
8 changed files with 2644 additions and 1259 deletions

View File

@ -1 +1 @@
intel-speed-select-y += isst-config.o isst-core.o isst-display.o isst-daemon.o hfi-events.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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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 <linux/isst_if.h>
#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;
}

File diff suppressed because it is too large Load Diff

View File

@ -20,16 +20,17 @@
#include "isst.h"
static int per_package_levels_info[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE];
static time_t per_package_levels_tm[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE];
static int per_package_levels_info[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE][MAX_PUNIT_PER_DIE];
static time_t per_package_levels_tm[MAX_PACKAGE_COUNT][MAX_DIE_PER_PACKAGE][MAX_PUNIT_PER_DIE];
static void init_levels(void)
{
int i, j;
int i, j, k;
for (i = 0; i < MAX_PACKAGE_COUNT; ++i)
for (j = 0; j < MAX_DIE_PER_PACKAGE; ++j)
per_package_levels_info[i][j] = -1;
for (k = 0; k < MAX_PUNIT_PER_DIE; ++k)
per_package_levels_info[i][j][k] = -1;
}
void process_level_change(struct isst_id *id)
@ -39,16 +40,16 @@ void process_level_change(struct isst_id *id)
time_t tm;
int ret;
if (id->pkg < 0 || id->die < 0) {
if (id->pkg < 0 || id->die < 0 || id->punit < 0) {
debug_printf("Invalid package/die info for cpu:%d\n", id->cpu);
return;
}
tm = time(NULL);
if (tm - per_package_levels_tm[id->pkg][id->die] < 2)
if (tm - per_package_levels_tm[id->pkg][id->die][id->punit] < 2)
return;
per_package_levels_tm[id->pkg][id->die] = tm;
per_package_levels_tm[id->pkg][id->die][id->punit] = tm;
ret = isst_get_ctdp_levels(id, &pkg_dev);
if (ret) {
@ -64,14 +65,14 @@ void process_level_change(struct isst_id *id)
return;
}
if (per_package_levels_info[id->pkg][id->die] == pkg_dev.current_level)
if (per_package_levels_info[id->pkg][id->die][id->punit] == pkg_dev.current_level)
return;
debug_printf("**Config level change for cpu:%d pkg:%d die:%d from %d to %d\n",
id->cpu, id->pkg, id->die, per_package_levels_info[id->pkg][id->die],
id->cpu, id->pkg, id->die, per_package_levels_info[id->pkg][id->die][id->punit],
pkg_dev.current_level);
per_package_levels_info[id->pkg][id->die] = pkg_dev.current_level;
per_package_levels_info[id->pkg][id->die][id->punit] = pkg_dev.current_level;
ctdp_level.core_cpumask_size =
alloc_cpu_set(&ctdp_level.core_cpumask);
@ -82,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) {
@ -96,7 +110,7 @@ void process_level_change(struct isst_id *id)
}
}
}
free_mask:
free_cpu_set(ctdp_level.core_cpumask);
}
@ -108,7 +122,7 @@ static void _poll_for_config_change(struct isst_id *id, void *arg1, void *arg2,
static void poll_for_config_change(void)
{
for_each_online_package_in_set(_poll_for_config_change, NULL, NULL,
for_each_online_power_domain_in_set(_poll_for_config_change, NULL, NULL,
NULL, NULL);
}

View File

@ -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()) {
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, 1, header, NULL);
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,
@ -198,7 +207,7 @@ static void _isst_pbf_display_information(struct isst_id *id, FILE *outf, int le
snprintf(header, sizeof(header), "high-priority-base-frequency(MHz)");
snprintf(value, sizeof(value), "%d",
pbf_info->p1_high * DISP_FREQ_MULTIPLIER);
pbf_info->p1_high * isst_get_disp_freq_multiplier());
format_and_print(outf, disp_level + 1, header, value);
snprintf(header, sizeof(header), "high-priority-cpu-mask");
@ -214,7 +223,7 @@ static void _isst_pbf_display_information(struct isst_id *id, FILE *outf, int le
snprintf(header, sizeof(header), "low-priority-base-frequency(MHz)");
snprintf(value, sizeof(value), "%d",
pbf_info->p1_low * DISP_FREQ_MULTIPLIER);
pbf_info->p1_low * isst_get_disp_freq_multiplier());
format_and_print(outf, disp_level + 1, header, value);
if (is_clx_n_platform())
@ -235,6 +244,7 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l
int base_level)
{
struct isst_fact_bucket_info *bucket_info = fact_info->bucket_info;
int trl_max_levels = isst_get_trl_max_levels();
char header[256];
char value[256];
int print = 0, j;
@ -243,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].high_priority_cores_count)
/* core count must be valid for CPU power domain */
if (!bucket_info[j].hp_cores && id->cpu >= 0)
break;
print = 1;
@ -256,10 +267,12 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l
snprintf(header, sizeof(header), "speed-select-turbo-freq-properties");
format_and_print(outf, base_level, header, NULL);
for (j = 0; j < ISST_FACT_MAX_BUCKETS; ++j) {
int i;
if (fact_bucket != 0xff && fact_bucket != j)
continue;
if (!bucket_info[j].high_priority_cores_count)
if (!bucket_info[j].hp_cores)
break;
snprintf(header, sizeof(header), "bucket-%d", j);
@ -267,75 +280,49 @@ static void _isst_fact_display_information(struct isst_id *id, FILE *outf, int l
snprintf(header, sizeof(header), "high-priority-cores-count");
snprintf(value, sizeof(value), "%d",
bucket_info[j].high_priority_cores_count);
bucket_info[j].hp_cores);
format_and_print(outf, base_level + 2, header, value);
if (fact_avx & 0x01) {
for (i = 0; i < trl_max_levels; i++) {
if (!bucket_info[j].hp_ratios[i] || (fact_avx != 0xFF && !(fact_avx & (1 << i))))
continue;
if (i == 0 && api_version() == 1 && !is_emr_platform())
snprintf(header, sizeof(header),
"high-priority-max-frequency(MHz)");
snprintf(value, sizeof(value), "%d",
bucket_info[j].sse_trl * DISP_FREQ_MULTIPLIER);
format_and_print(outf, base_level + 2, header, value);
}
if (fact_avx & 0x02) {
else
snprintf(header, sizeof(header),
"high-priority-max-avx2-frequency(MHz)");
"high-priority-max-%s-frequency(MHz)", isst_get_trl_level_name(i));
snprintf(value, sizeof(value), "%d",
bucket_info[j].avx_trl * DISP_FREQ_MULTIPLIER);
format_and_print(outf, base_level + 2, header, value);
}
if (fact_avx & 0x04) {
snprintf(header, sizeof(header),
"high-priority-max-avx512-frequency(MHz)");
snprintf(value, sizeof(value), "%d",
bucket_info[j].avx512_trl *
DISP_FREQ_MULTIPLIER);
bucket_info[j].hp_ratios[i] * isst_get_disp_freq_multiplier());
format_and_print(outf, base_level + 2, header, value);
}
}
snprintf(header, sizeof(header),
"speed-select-turbo-freq-clip-frequencies");
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 && !is_emr_platform())
snprintf(header, sizeof(header), "low-priority-max-frequency(MHz)");
else
snprintf(header, sizeof(header), "low-priority-max-%s-frequency(MHz)",
isst_get_trl_level_name(j));
snprintf(value, sizeof(value), "%d",
fact_info->lp_clipping_ratio_license_sse *
DISP_FREQ_MULTIPLIER);
format_and_print(outf, base_level + 2, header, value);
snprintf(header, sizeof(header),
"low-priority-max-avx2-frequency(MHz)");
snprintf(value, sizeof(value), "%d",
fact_info->lp_clipping_ratio_license_avx2 *
DISP_FREQ_MULTIPLIER);
format_and_print(outf, base_level + 2, header, value);
snprintf(header, sizeof(header),
"low-priority-max-avx512-frequency(MHz)");
snprintf(value, sizeof(value), "%d",
fact_info->lp_clipping_ratio_license_avx512 *
DISP_FREQ_MULTIPLIER);
fact_info->lp_ratios[j] * isst_get_disp_freq_multiplier());
format_and_print(outf, base_level + 2, header, value);
}
}
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);
@ -354,6 +341,7 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level
char header[256];
char value[512];
static int level;
int trl_max_levels = isst_get_trl_max_levels();
int i;
if (pkg_dev->processed)
@ -361,7 +349,7 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level
for (i = 0; i <= pkg_dev->levels; ++i) {
struct isst_pkg_ctdp_level_info *ctdp_level;
int j;
int j, k;
ctdp_level = &pkg_dev->ctdp_level[i];
if (!ctdp_level->processed)
@ -371,6 +359,7 @@ 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);
if (id->cpu >= 0) {
snprintf(header, sizeof(header), "cpu-count");
j = get_cpu_count(id);
snprintf(value, sizeof(value), "%d", j);
@ -397,6 +386,7 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level
ctdp_level->core_cpumask);
format_and_print(outf, level + 2, header, value);
}
}
snprintf(header, sizeof(header), "thermal-design-power-ratio");
snprintf(value, sizeof(value), "%d", ctdp_level->tdp_ratio);
@ -406,41 +396,48 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level
if (!ctdp_level->sse_p1)
ctdp_level->sse_p1 = ctdp_level->tdp_ratio;
snprintf(value, sizeof(value), "%d",
ctdp_level->sse_p1 * DISP_FREQ_MULTIPLIER);
ctdp_level->sse_p1 * isst_get_disp_freq_multiplier());
format_and_print(outf, level + 2, header, value);
if (ctdp_level->avx2_p1) {
snprintf(header, sizeof(header), "base-frequency-avx2(MHz)");
snprintf(value, sizeof(value), "%d",
ctdp_level->avx2_p1 * DISP_FREQ_MULTIPLIER);
ctdp_level->avx2_p1 * isst_get_disp_freq_multiplier());
format_and_print(outf, level + 2, header, value);
}
if (ctdp_level->avx512_p1) {
snprintf(header, sizeof(header), "base-frequency-avx512(MHz)");
snprintf(value, sizeof(value), "%d",
ctdp_level->avx512_p1 * DISP_FREQ_MULTIPLIER);
ctdp_level->avx512_p1 * isst_get_disp_freq_multiplier());
format_and_print(outf, level + 2, header, value);
}
if (ctdp_level->uncore_pm) {
snprintf(header, sizeof(header), "uncore-frequency-min(MHz)");
snprintf(value, sizeof(value), "%d",
ctdp_level->uncore_pm * DISP_FREQ_MULTIPLIER);
ctdp_level->uncore_pm * isst_get_disp_freq_multiplier());
format_and_print(outf, level + 2, header, value);
}
if (ctdp_level->uncore_p0) {
snprintf(header, sizeof(header), "uncore-frequency-max(MHz)");
snprintf(value, sizeof(value), "%d",
ctdp_level->uncore_p0 * DISP_FREQ_MULTIPLIER);
ctdp_level->uncore_p0 * isst_get_disp_freq_multiplier());
format_and_print(outf, level + 2, header, value);
}
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());
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",
ctdp_level->uncore_p1 * DISP_FREQ_MULTIPLIER);
ctdp_level->uncore_p1 * isst_get_disp_freq_multiplier());
format_and_print(outf, level + 2, header, value);
}
@ -451,6 +448,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) {
@ -505,54 +509,24 @@ void isst_ctdp_display_information(struct isst_id *id, FILE *outf, int tdp_level
format_and_print(outf, level + 2, header, value);
}
snprintf(header, sizeof(header), "turbo-ratio-limits-sse");
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);
for (j = 0; j < 8; ++j) {
snprintf(header, sizeof(header), "bucket-%d", j);
format_and_print(outf, level + 3, header, NULL);
snprintf(header, sizeof(header), "core-count");
snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
format_and_print(outf, level + 4, header, value);
snprintf(header, sizeof(header),
"max-turbo-frequency(MHz)");
snprintf(value, sizeof(value), "%d",
ctdp_level->trl_sse_active_cores[j] *
DISP_FREQ_MULTIPLIER);
format_and_print(outf, level + 4, header, value);
}
if (ctdp_level->trl_avx_active_cores[0]) {
snprintf(header, sizeof(header), "turbo-ratio-limits-avx2");
format_and_print(outf, level + 2, header, NULL);
for (j = 0; j < 8; ++j) {
snprintf(header, sizeof(header), "bucket-%d", j);
format_and_print(outf, level + 3, header, NULL);
snprintf(header, sizeof(header), "core-count");
snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
snprintf(value, sizeof(value), "%llu", (ctdp_level->trl_cores >> (j * 8)) & 0xff);
format_and_print(outf, level + 4, header, value);
snprintf(header, sizeof(header), "max-turbo-frequency(MHz)");
snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_active_cores[j] * DISP_FREQ_MULTIPLIER);
format_and_print(outf, level + 4, header, value);
}
}
if (ctdp_level->trl_avx_512_active_cores[0]) {
snprintf(header, sizeof(header), "turbo-ratio-limits-avx512");
format_and_print(outf, level + 2, header, NULL);
for (j = 0; j < 8; ++j) {
snprintf(header, sizeof(header), "bucket-%d", j);
format_and_print(outf, level + 3, header, NULL);
snprintf(header, sizeof(header), "core-count");
snprintf(value, sizeof(value), "%llu", (ctdp_level->buckets_info >> (j * 8)) & 0xff);
format_and_print(outf, level + 4, header, value);
snprintf(header, sizeof(header), "max-turbo-frequency(MHz)");
snprintf(value, sizeof(value), "%d", ctdp_level->trl_avx_512_active_cores[j] * DISP_FREQ_MULTIPLIER);
snprintf(value, sizeof(value), "%d", ctdp_level->trl_ratios[k][j] * isst_get_disp_freq_multiplier());
format_and_print(outf, level + 4, header, value);
}
}
@ -631,18 +605,18 @@ 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-min");
snprintf(value, sizeof(value), "%d MHz", clos_config->clos_min * DISP_FREQ_MULTIPLIER);
snprintf(value, sizeof(value), "%d MHz", clos_config->clos_min * isst_get_disp_freq_multiplier());
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 * DISP_FREQ_MULTIPLIER);
snprintf(value, sizeof(value), "%d MHz", clos_config->clos_max * isst_get_disp_freq_multiplier());
format_and_print(outf, level + 2, header, value);
snprintf(header, sizeof(header), "clos-desired");
snprintf(value, sizeof(value), "%d MHz", clos_config->clos_desired * DISP_FREQ_MULTIPLIER);
snprintf(value, sizeof(value), "%d MHz", clos_config->clos_desired * isst_get_disp_freq_multiplier());
format_and_print(outf, level + 2, header, value);
format_and_print(outf, level, NULL, NULL);
@ -717,7 +691,6 @@ 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);
snprintf(header, sizeof(header), "%s", feature);

View File

@ -28,6 +28,8 @@
#include <stdarg.h>
#include <sys/ioctl.h>
#include <linux/isst_if.h>
#define BIT(x) (1 << (x))
#define BIT_ULL(nr) (1ULL << (nr))
#define GENMASK(h, l) (((~0UL) << (l)) & (~0UL >> (sizeof(long) * 8 - 1 - (h))))
@ -79,27 +81,27 @@
#define MAX_PACKAGE_COUNT 8
#define MAX_DIE_PER_PACKAGE 2
#define MAX_PUNIT_PER_DIE 8
/* Unified structure to specific a CPU or a Power Domain */
struct isst_id {
int cpu;
int pkg;
int die;
int punit;
};
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;
};
struct isst_fact_bucket_info {
int high_priority_cores_count;
int sse_trl;
int avx_trl;
int avx512_trl;
int hp_cores;
int hp_ratios[TRL_MAX_LEVELS];
};
struct isst_pbf_info {
@ -117,9 +119,7 @@ struct isst_pbf_info {
#define ISST_TRL_MAX_ACTIVE_CORES 8
#define ISST_FACT_MAX_BUCKETS 8
struct isst_fact_info {
int lp_clipping_ratio_license_sse;
int lp_clipping_ratio_license_avx2;
int lp_clipping_ratio_license_avx512;
int lp_ratios[TRL_MAX_LEVELS];
struct isst_fact_bucket_info bucket_info[ISST_FACT_MAX_BUCKETS];
};
@ -143,20 +143,20 @@ 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;
int cpu_count;
unsigned long long buckets_info;
int trl_sse_active_cores[ISST_TRL_MAX_ACTIVE_CORES];
int trl_avx_active_cores[ISST_TRL_MAX_ACTIVE_CORES];
int trl_avx_512_active_cores[ISST_TRL_MAX_ACTIVE_CORES];
unsigned long long trl_cores; /* Buckets info */
int trl_ratios[TRL_MAX_LEVELS][ISST_TRL_MAX_ACTIVE_CORES];
int kobj_bucket_index;
int active_bucket;
int fact_max_index;
@ -178,13 +178,48 @@ struct isst_pkg_ctdp {
struct isst_pkg_ctdp_level_info ctdp_level[ISST_MAX_TDP_LEVELS];
};
enum isst_platform_param {
ISST_PARAM_MBOX_DELAY,
ISST_PARAM_MBOX_RETRIES,
};
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);
int (*get_ctdp_control)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level);
int (*get_tdp_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level);
int (*get_pwr_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level);
int (*get_coremask_info)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level);
int (*get_get_trl)(struct isst_id *id, int level, int avx_level, int *trl);
int (*get_get_trls)(struct isst_id *id, int level, struct isst_pkg_ctdp_level_info *ctdp_level);
int (*get_trl_bucket_info)(struct isst_id *id, int level, unsigned long long *buckets_info);
int (*set_tdp_level)(struct isst_id *id, int tdp_level);
int (*get_pbf_info)(struct isst_id *id, int level, struct isst_pbf_info *pbf_info);
int (*set_pbf_fact_status)(struct isst_id *id, int pbf, int enable);
int (*get_fact_info)(struct isst_id *id, int level, int fact_bucket, struct isst_fact_info *fact_info);
void (*adjust_uncore_freq)(struct isst_id *id, int config_index, struct isst_pkg_ctdp_level_info *ctdp_level);
int (*get_clos_information)(struct isst_id *id, int *enable, int *type);
int (*pm_qos_config)(struct isst_id *id, int enable_clos, int priority_type);
int (*pm_get_clos)(struct isst_id *id, int clos, struct isst_clos_config *clos_config);
int (*set_clos)(struct isst_id *id, int clos, struct isst_clos_config *clos_config);
int (*clos_get_assoc_status)(struct isst_id *id, int *clos_id);
int (*clos_associate)(struct isst_id *id, int clos_id);
};
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);
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);
@ -196,21 +231,22 @@ 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(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);
extern char *isst_get_trl_level_name(int level);
extern int isst_is_punit_valid(struct isst_id *id);
extern int isst_get_ctdp_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev);
extern int isst_get_ctdp_control(struct isst_id *id, int config_index,
struct isst_pkg_ctdp_level_info *ctdp_level);
extern int isst_get_coremask_info(struct isst_id *id, int config_index,
struct isst_pkg_ctdp_level_info *ctdp_level);
extern void isst_get_uncore_p0_p1_info(struct isst_id *id, int config_index,
extern void isst_adjust_uncore_freq(struct isst_id *id, int config_index,
struct isst_pkg_ctdp_level_info *ctdp_level);
extern int isst_get_process_ctdp(struct isst_id *id, int tdp_level,
struct isst_pkg_ctdp *pkg_dev);
@ -228,11 +264,8 @@ extern int isst_set_tdp_level(struct isst_id *id, int tdp_level);
extern int isst_set_pbf_fact_status(struct isst_id *id, int pbf, int enable);
extern int isst_get_pbf_info(struct isst_id *id, int level,
struct isst_pbf_info *pbf_info);
extern void isst_get_pbf_info_complete(struct isst_pbf_info *pbf_info);
extern int isst_get_fact_info(struct isst_id *id, int level, int fact_bucket,
struct isst_fact_info *fact_info);
extern int isst_get_fact_bucket_info(struct isst_id *id, int level,
struct isst_fact_bucket_info *bucket_info);
extern void isst_fact_display_information(struct isst_id *id, FILE *outf, int level,
int fact_bucket, int fact_avx,
struct isst_fact_info *fact_info);
@ -265,11 +298,12 @@ 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);
extern void set_cpu_online_offline(int cpu, int state);
extern void for_each_online_package_in_set(void (*callback)(struct isst_id *, void *, void *,
extern void for_each_online_power_domain_in_set(void (*callback)(struct isst_id *, void *, void *,
void *, void *),
void *arg1, void *arg2, void *arg3,
void *arg4);
@ -277,4 +311,14 @@ extern int isst_daemon(int debug_mode, int poll_interval, int no_daemon);
extern void process_level_change(struct isst_id *id);
extern int hfi_main(void);
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);
/* 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