mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 17:23:36 +00:00
turbostat version 2024.11.30
since 2024.07.26: assorted minor bug fixes assorted platform specific tweaks initial RAPL PSYS (SysWatt) support -----BEGIN PGP SIGNATURE----- iQJIBAABCgAyFiEE67dNfPFP+XUaA73mB9BFOha3NhcFAmdLiKMUHGxlbi5icm93 bkBpbnRlbC5jb20ACgkQB9BFOha3NhdqRw//cZDec7umy7p8khekoclm5GWHZruh lvhvpgYzHMEbNs6WrKp81ddOTidNEiuIXuuphn/2Z6K+fYmiLGA6fiAmk+Enbm0t d34vuViZAqujVzSdMOpn0J+RDhAb2Kys86IgOmyR0gQVv5SZ0HSDhWaSWpj8Rkeh afniQcNK3f093GypaQJwsuWyGD/CoEV2NZcxqrEWNkYx6iPv6KBSJwxpi/qnbW1w 1GJ+ukFAg+GrbDqhxrNGWHlCB/rOf6/+AdGCjlWYLjN3mKBw9Aa2xze+ucthRJnV 82LrB7td/0DtpzO76zUC3EgTEueiJUK3X8wGnVlaJ9pc+25QHZldewbyREuVbjL9 0sxwUfrAfXyUxWHwm5nbOHPnMCzkpOgIRLz+Ru6fImXkdn0mC8fA+187VT85Hgio tRiekwkhsR4IAvQA/dn1021lWCFaYz0hRSayeq81sI9DE6E32WL/BSFbKpEtC++0 xg7IcHZhq2j7gxBJRO8v7dBD/Ixox1mAS12vqm6TamI+qTWuO2zuTbAV9+ETtzhL 6WeYlT0o0dBWJCHyCQU2deew+M5eyEGsDz9PunCMGpNEIe4IY1WKteDfWRAGYsvl cUwvDvgv+3eSioOlG6vYsCeK5cLKpP24I0pMZZKpZ4RH0Aa4zyaD0T2RzOBuVsyQ bUZu5yIAiwr6MLY= =znZc -----END PGP SIGNATURE----- Merge tag 'turbostat-2024.11.30' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux Pull turbostat updates from Len Brown: - assorted minor bug fixes - assorted platform specific tweaks - initial RAPL PSYS (SysWatt) support * tag 'turbostat-2024.11.30' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux: tools/power turbostat: 2024.11.30 tools/power turbostat: Add RAPL psys as a built-in counter tools/power turbostat: Fix child's argument forwarding tools/power turbostat: Force --no-perf in --dump mode tools/power turbostat: Add support for /sys/class/drm/card1 tools/power turbostat: Cache graphics sysfs file descriptors during probe tools/power turbostat: Consolidate graphics sysfs access tools/power turbostat: Remove unnecessary fflush() call tools/power turbostat: Enhance platform divergence description tools/power turbostat: Add initial support for GraniteRapids-D tools/power turbostat: Remove PC3 support on Lunarlake tools/power turbostat: Rename arl_features to lnl_features tools/power turbostat: Add back PC8 support on Arrowlake tools/power turbostat: Remove PC7/PC9 support on MTL tools/power turbostat: Honor --show CPU, even when even when num_cpus=1 tools/power turbostat: Fix trailing '\n' parsing tools/power turbostat: Allow using cpu device in perf counters on hybrid platforms tools/power turbostat: Fix column printing for PMT xtal_time counters tools/power turbostat: fix GCC9 build regression
This commit is contained in:
commit
bcc8eda6d3
@ -33,6 +33,9 @@ name as necessary to disambiguate it from others is necessary. Note that option
|
|||||||
msr0xXXX is a hex offset, eg. msr0x10
|
msr0xXXX is a hex offset, eg. msr0x10
|
||||||
/sys/path... is an absolute path to a sysfs attribute
|
/sys/path... is an absolute path to a sysfs attribute
|
||||||
<device> is a perf device from /sys/bus/event_source/devices/<device> eg. cstate_core
|
<device> is a perf device from /sys/bus/event_source/devices/<device> eg. cstate_core
|
||||||
|
On Intel hybrid platforms, instead of one "cpu" perf device there are two, "cpu_core" and "cpu_atom" devices for P and E cores respectively.
|
||||||
|
Turbostat, in this case, allow user to use "cpu" device and will automatically detect the type of a CPU and translate it to "cpu_core" and "cpu_atom" accordingly.
|
||||||
|
For a complete example see "ADD PERF COUNTER EXAMPLE #2 (using virtual "cpu" device)".
|
||||||
<event> is a perf event for given device from /sys/bus/event_source/devices/<device>/events/<event> eg. c1-residency
|
<event> is a perf event for given device from /sys/bus/event_source/devices/<device>/events/<event> eg. c1-residency
|
||||||
perf/cstate_core/c1-residency would then use /sys/bus/event_source/devices/cstate_core/events/c1-residency
|
perf/cstate_core/c1-residency would then use /sys/bus/event_source/devices/cstate_core/events/c1-residency
|
||||||
|
|
||||||
@ -187,6 +190,8 @@ The system configuration dump (if --quiet is not used) is followed by statistics
|
|||||||
.PP
|
.PP
|
||||||
\fBRAMWatt\fP Watts consumed by the DRAM DIMMS -- available only on server processors.
|
\fBRAMWatt\fP Watts consumed by the DRAM DIMMS -- available only on server processors.
|
||||||
.PP
|
.PP
|
||||||
|
\fBSysWatt\fP Watts consumed by the whole platform (RAPL PSYS). Disabled by default. Enable with --enable SysWatt.
|
||||||
|
.PP
|
||||||
\fBPKG_%\fP percent of the interval that RAPL throttling was active on the Package. Note that the system summary is the sum of the package throttling time, and thus may be higher than 100% on a multi-package system. Note that the meaning of this field is model specific. For example, some hardware increments this counter when RAPL responds to thermal limits, but does not increment this counter when RAPL responds to power limits. Comparing PkgWatt and PkgTmp to system limits is necessary.
|
\fBPKG_%\fP percent of the interval that RAPL throttling was active on the Package. Note that the system summary is the sum of the package throttling time, and thus may be higher than 100% on a multi-package system. Note that the meaning of this field is model specific. For example, some hardware increments this counter when RAPL responds to thermal limits, but does not increment this counter when RAPL responds to power limits. Comparing PkgWatt and PkgTmp to system limits is necessary.
|
||||||
.PP
|
.PP
|
||||||
\fBRAM_%\fP percent of the interval that RAPL throttling was active on DRAM.
|
\fBRAM_%\fP percent of the interval that RAPL throttling was active on DRAM.
|
||||||
@ -387,6 +392,28 @@ CPU pCPU%c1 CPU%c1
|
|||||||
|
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
|
.SH ADD PERF COUNTER EXAMPLE #2 (using virtual cpu device)
|
||||||
|
Here we run on hybrid, Raptor Lake platform.
|
||||||
|
We limit turbostat to show output for just cpu0 (pcore) and cpu12 (ecore).
|
||||||
|
We add a counter showing number of L3 cache misses, using virtual "cpu" device,
|
||||||
|
labeling it with the column header, "VCMISS".
|
||||||
|
We add a counter showing number of L3 cache misses, using virtual "cpu_core" device,
|
||||||
|
labeling it with the column header, "PCMISS". This will fail on ecore cpu12.
|
||||||
|
We add a counter showing number of L3 cache misses, using virtual "cpu_atom" device,
|
||||||
|
labeling it with the column header, "ECMISS". This will fail on pcore cpu0.
|
||||||
|
We display it only once, after the conclusion of 0.1 second sleep.
|
||||||
|
.nf
|
||||||
|
sudo ./turbostat --quiet --cpu 0,12 --show CPU --add perf/cpu/cache-misses,cpu,delta,raw,VCMISS --add perf/cpu_core/cache-misses,cpu,delta,raw,PCMISS --add perf/cpu_atom/cache-misses,cpu,delta,raw,ECMISS sleep .1
|
||||||
|
turbostat: added_perf_counters_init_: perf/cpu_atom/cache-misses: failed to open counter on cpu0
|
||||||
|
turbostat: added_perf_counters_init_: perf/cpu_core/cache-misses: failed to open counter on cpu12
|
||||||
|
0.104630 sec
|
||||||
|
CPU ECMISS PCMISS VCMISS
|
||||||
|
- 0x0000000000000000 0x0000000000000000 0x0000000000000000
|
||||||
|
0 0x0000000000000000 0x0000000000007951 0x0000000000007796
|
||||||
|
12 0x000000000001137a 0x0000000000000000 0x0000000000011392
|
||||||
|
|
||||||
|
.fi
|
||||||
|
|
||||||
.SH ADD PMT COUNTER EXAMPLE
|
.SH ADD PMT COUNTER EXAMPLE
|
||||||
Here we limit turbostat to showing just the CPU number 0.
|
Here we limit turbostat to showing just the CPU number 0.
|
||||||
We add two counters, showing crystal clock count and the DC6 residency.
|
We add two counters, showing crystal clock count and the DC6 residency.
|
||||||
|
@ -31,6 +31,9 @@
|
|||||||
)
|
)
|
||||||
// end copied section
|
// end copied section
|
||||||
|
|
||||||
|
#define CPUID_LEAF_MODEL_ID 0x1A
|
||||||
|
#define CPUID_LEAF_MODEL_ID_CORE_TYPE_SHIFT 24
|
||||||
|
|
||||||
#define X86_VENDOR_INTEL 0
|
#define X86_VENDOR_INTEL 0
|
||||||
|
|
||||||
#include INTEL_FAMILY_HEADER
|
#include INTEL_FAMILY_HEADER
|
||||||
@ -89,6 +92,9 @@
|
|||||||
#define PERF_DEV_NAME_BYTES 32
|
#define PERF_DEV_NAME_BYTES 32
|
||||||
#define PERF_EVT_NAME_BYTES 32
|
#define PERF_EVT_NAME_BYTES 32
|
||||||
|
|
||||||
|
#define INTEL_ECORE_TYPE 0x20
|
||||||
|
#define INTEL_PCORE_TYPE 0x40
|
||||||
|
|
||||||
enum counter_scope { SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE };
|
enum counter_scope { SCOPE_CPU, SCOPE_CORE, SCOPE_PACKAGE };
|
||||||
enum counter_type { COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC, COUNTER_K2M };
|
enum counter_type { COUNTER_ITEMS, COUNTER_CYCLES, COUNTER_SECONDS, COUNTER_USEC, COUNTER_K2M };
|
||||||
enum counter_format { FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT, FORMAT_AVERAGE };
|
enum counter_format { FORMAT_RAW, FORMAT_DELTA, FORMAT_PERCENT, FORMAT_AVERAGE };
|
||||||
@ -194,6 +200,8 @@ struct msr_counter bic[] = {
|
|||||||
{ 0x0, "SAMMHz", NULL, 0, 0, 0, NULL, 0 },
|
{ 0x0, "SAMMHz", NULL, 0, 0, 0, NULL, 0 },
|
||||||
{ 0x0, "SAMAMHz", NULL, 0, 0, 0, NULL, 0 },
|
{ 0x0, "SAMAMHz", NULL, 0, 0, 0, NULL, 0 },
|
||||||
{ 0x0, "Die%c6", NULL, 0, 0, 0, NULL, 0 },
|
{ 0x0, "Die%c6", NULL, 0, 0, 0, NULL, 0 },
|
||||||
|
{ 0x0, "SysWatt", NULL, 0, 0, 0, NULL, 0 },
|
||||||
|
{ 0x0, "Sys_J", NULL, 0, 0, 0, NULL, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
|
#define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
|
||||||
@ -256,6 +264,8 @@ struct msr_counter bic[] = {
|
|||||||
#define BIC_SAMMHz (1ULL << 56)
|
#define BIC_SAMMHz (1ULL << 56)
|
||||||
#define BIC_SAMACTMHz (1ULL << 57)
|
#define BIC_SAMACTMHz (1ULL << 57)
|
||||||
#define BIC_Diec6 (1ULL << 58)
|
#define BIC_Diec6 (1ULL << 58)
|
||||||
|
#define BIC_SysWatt (1ULL << 59)
|
||||||
|
#define BIC_Sys_J (1ULL << 60)
|
||||||
|
|
||||||
#define BIC_TOPOLOGY (BIC_Package | BIC_Node | BIC_CoreCnt | BIC_PkgCnt | BIC_Core | BIC_CPU | BIC_Die )
|
#define BIC_TOPOLOGY (BIC_Package | BIC_Node | BIC_CoreCnt | BIC_PkgCnt | BIC_Core | BIC_CPU | BIC_Die )
|
||||||
#define BIC_THERMAL_PWR ( BIC_CoreTmp | BIC_PkgTmp | BIC_PkgWatt | BIC_CorWatt | BIC_GFXWatt | BIC_RAMWatt | BIC_PKG__ | BIC_RAM__)
|
#define BIC_THERMAL_PWR ( BIC_CoreTmp | BIC_PkgTmp | BIC_PkgWatt | BIC_CorWatt | BIC_GFXWatt | BIC_RAMWatt | BIC_PKG__ | BIC_RAM__)
|
||||||
@ -263,7 +273,7 @@ struct msr_counter bic[] = {
|
|||||||
#define BIC_IDLE (BIC_sysfs | BIC_CPU_c1 | BIC_CPU_c3 | BIC_CPU_c6 | BIC_CPU_c7 | BIC_GFX_rc6 | BIC_Pkgpc2 | BIC_Pkgpc3 | BIC_Pkgpc6 | BIC_Pkgpc7 | BIC_Pkgpc8 | BIC_Pkgpc9 | BIC_Pkgpc10 | BIC_CPU_LPI | BIC_SYS_LPI | BIC_Mod_c6 | BIC_Totl_c0 | BIC_Any_c0 | BIC_GFX_c0 | BIC_CPUGFX | BIC_SAM_mc6 | BIC_Diec6)
|
#define BIC_IDLE (BIC_sysfs | BIC_CPU_c1 | BIC_CPU_c3 | BIC_CPU_c6 | BIC_CPU_c7 | BIC_GFX_rc6 | BIC_Pkgpc2 | BIC_Pkgpc3 | BIC_Pkgpc6 | BIC_Pkgpc7 | BIC_Pkgpc8 | BIC_Pkgpc9 | BIC_Pkgpc10 | BIC_CPU_LPI | BIC_SYS_LPI | BIC_Mod_c6 | BIC_Totl_c0 | BIC_Any_c0 | BIC_GFX_c0 | BIC_CPUGFX | BIC_SAM_mc6 | BIC_Diec6)
|
||||||
#define BIC_OTHER ( BIC_IRQ | BIC_SMI | BIC_ThreadC | BIC_CoreTmp | BIC_IPC)
|
#define BIC_OTHER ( BIC_IRQ | BIC_SMI | BIC_ThreadC | BIC_CoreTmp | BIC_IPC)
|
||||||
|
|
||||||
#define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC)
|
#define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC | BIC_SysWatt | BIC_Sys_J)
|
||||||
|
|
||||||
unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT);
|
unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT);
|
||||||
unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC;
|
unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC;
|
||||||
@ -370,7 +380,6 @@ enum gfx_sysfs_idx {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct gfx_sysfs_info {
|
struct gfx_sysfs_info {
|
||||||
const char *path;
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
unsigned long long val_ull;
|
unsigned long long val_ull;
|
||||||
@ -502,12 +511,15 @@ enum rapl_msrs {
|
|||||||
RAPL_AMD_PWR_UNIT = BIT(14), /* 0xc0010299 MSR_AMD_RAPL_POWER_UNIT */
|
RAPL_AMD_PWR_UNIT = BIT(14), /* 0xc0010299 MSR_AMD_RAPL_POWER_UNIT */
|
||||||
RAPL_AMD_CORE_ENERGY_STAT = BIT(15), /* 0xc001029a MSR_AMD_CORE_ENERGY_STATUS */
|
RAPL_AMD_CORE_ENERGY_STAT = BIT(15), /* 0xc001029a MSR_AMD_CORE_ENERGY_STATUS */
|
||||||
RAPL_AMD_PKG_ENERGY_STAT = BIT(16), /* 0xc001029b MSR_AMD_PKG_ENERGY_STATUS */
|
RAPL_AMD_PKG_ENERGY_STAT = BIT(16), /* 0xc001029b MSR_AMD_PKG_ENERGY_STATUS */
|
||||||
|
RAPL_PLATFORM_ENERGY_LIMIT = BIT(17), /* 0x64c MSR_PLATFORM_ENERGY_LIMIT */
|
||||||
|
RAPL_PLATFORM_ENERGY_STATUS = BIT(18), /* 0x64d MSR_PLATFORM_ENERGY_STATUS */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RAPL_PKG (RAPL_PKG_ENERGY_STATUS | RAPL_PKG_POWER_LIMIT)
|
#define RAPL_PKG (RAPL_PKG_ENERGY_STATUS | RAPL_PKG_POWER_LIMIT)
|
||||||
#define RAPL_DRAM (RAPL_DRAM_ENERGY_STATUS | RAPL_DRAM_POWER_LIMIT)
|
#define RAPL_DRAM (RAPL_DRAM_ENERGY_STATUS | RAPL_DRAM_POWER_LIMIT)
|
||||||
#define RAPL_CORE (RAPL_CORE_ENERGY_STATUS | RAPL_CORE_POWER_LIMIT)
|
#define RAPL_CORE (RAPL_CORE_ENERGY_STATUS | RAPL_CORE_POWER_LIMIT)
|
||||||
#define RAPL_GFX (RAPL_GFX_POWER_LIMIT | RAPL_GFX_ENERGY_STATUS)
|
#define RAPL_GFX (RAPL_GFX_POWER_LIMIT | RAPL_GFX_ENERGY_STATUS)
|
||||||
|
#define RAPL_PSYS (RAPL_PLATFORM_ENERGY_STATUS | RAPL_PLATFORM_ENERGY_LIMIT)
|
||||||
|
|
||||||
#define RAPL_PKG_ALL (RAPL_PKG | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO)
|
#define RAPL_PKG_ALL (RAPL_PKG | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO)
|
||||||
#define RAPL_DRAM_ALL (RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_DRAM_POWER_INFO)
|
#define RAPL_DRAM_ALL (RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_DRAM_POWER_INFO)
|
||||||
@ -708,7 +720,7 @@ static const struct platform_features skl_features = {
|
|||||||
.has_ext_cst_msrs = 1,
|
.has_ext_cst_msrs = 1,
|
||||||
.trl_msrs = TRL_BASE,
|
.trl_msrs = TRL_BASE,
|
||||||
.tcc_offset_bits = 6,
|
.tcc_offset_bits = 6,
|
||||||
.rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX,
|
.rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX | RAPL_PSYS,
|
||||||
.enable_tsc_tweak = 1,
|
.enable_tsc_tweak = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -725,42 +737,44 @@ static const struct platform_features cnl_features = {
|
|||||||
.has_ext_cst_msrs = 1,
|
.has_ext_cst_msrs = 1,
|
||||||
.trl_msrs = TRL_BASE,
|
.trl_msrs = TRL_BASE,
|
||||||
.tcc_offset_bits = 6,
|
.tcc_offset_bits = 6,
|
||||||
.rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX,
|
.rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX | RAPL_PSYS,
|
||||||
.enable_tsc_tweak = 1,
|
.enable_tsc_tweak = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Copied from cnl_features, with PC7/PC9 removed */
|
||||||
static const struct platform_features adl_features = {
|
static const struct platform_features adl_features = {
|
||||||
.has_msr_misc_feature_control = 1,
|
.has_msr_misc_feature_control = cnl_features.has_msr_misc_feature_control,
|
||||||
.has_msr_misc_pwr_mgmt = 1,
|
.has_msr_misc_pwr_mgmt = cnl_features.has_msr_misc_pwr_mgmt,
|
||||||
.has_nhm_msrs = 1,
|
.has_nhm_msrs = cnl_features.has_nhm_msrs,
|
||||||
.has_config_tdp = 1,
|
.has_config_tdp = cnl_features.has_config_tdp,
|
||||||
.bclk_freq = BCLK_100MHZ,
|
.bclk_freq = cnl_features.bclk_freq,
|
||||||
.supported_cstates = CC1 | CC6 | CC7 | PC2 | PC3 | PC6 | PC8 | PC10,
|
.supported_cstates = CC1 | CC6 | CC7 | PC2 | PC3 | PC6 | PC8 | PC10,
|
||||||
.cst_limit = CST_LIMIT_HSW,
|
.cst_limit = cnl_features.cst_limit,
|
||||||
.has_irtl_msrs = 1,
|
.has_irtl_msrs = cnl_features.has_irtl_msrs,
|
||||||
.has_msr_core_c1_res = 1,
|
.has_msr_core_c1_res = cnl_features.has_msr_core_c1_res,
|
||||||
.has_ext_cst_msrs = 1,
|
.has_ext_cst_msrs = cnl_features.has_ext_cst_msrs,
|
||||||
.trl_msrs = TRL_BASE,
|
.trl_msrs = cnl_features.trl_msrs,
|
||||||
.tcc_offset_bits = 6,
|
.tcc_offset_bits = cnl_features.tcc_offset_bits,
|
||||||
.rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX,
|
.rapl_msrs = cnl_features.rapl_msrs,
|
||||||
.enable_tsc_tweak = 1,
|
.enable_tsc_tweak = cnl_features.enable_tsc_tweak,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct platform_features arl_features = {
|
/* Copied from adl_features, with PC3/PC8 removed */
|
||||||
.has_msr_misc_feature_control = 1,
|
static const struct platform_features lnl_features = {
|
||||||
.has_msr_misc_pwr_mgmt = 1,
|
.has_msr_misc_feature_control = adl_features.has_msr_misc_feature_control,
|
||||||
.has_nhm_msrs = 1,
|
.has_msr_misc_pwr_mgmt = adl_features.has_msr_misc_pwr_mgmt,
|
||||||
.has_config_tdp = 1,
|
.has_nhm_msrs = adl_features.has_nhm_msrs,
|
||||||
.bclk_freq = BCLK_100MHZ,
|
.has_config_tdp = adl_features.has_config_tdp,
|
||||||
.supported_cstates = CC1 | CC6 | CC7 | PC2 | PC3 | PC6 | PC10,
|
.bclk_freq = adl_features.bclk_freq,
|
||||||
.cst_limit = CST_LIMIT_HSW,
|
.supported_cstates = CC1 | CC6 | CC7 | PC2 | PC6 | PC10,
|
||||||
.has_irtl_msrs = 1,
|
.cst_limit = adl_features.cst_limit,
|
||||||
.has_msr_core_c1_res = 1,
|
.has_irtl_msrs = adl_features.has_irtl_msrs,
|
||||||
.has_ext_cst_msrs = 1,
|
.has_msr_core_c1_res = adl_features.has_msr_core_c1_res,
|
||||||
.trl_msrs = TRL_BASE,
|
.has_ext_cst_msrs = adl_features.has_ext_cst_msrs,
|
||||||
.tcc_offset_bits = 6,
|
.trl_msrs = adl_features.trl_msrs,
|
||||||
.rapl_msrs = RAPL_PKG_ALL | RAPL_CORE_ALL | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_GFX,
|
.tcc_offset_bits = adl_features.tcc_offset_bits,
|
||||||
.enable_tsc_tweak = 1,
|
.rapl_msrs = adl_features.rapl_msrs,
|
||||||
|
.enable_tsc_tweak = adl_features.enable_tsc_tweak,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct platform_features skx_features = {
|
static const struct platform_features skx_features = {
|
||||||
@ -790,7 +804,7 @@ static const struct platform_features icx_features = {
|
|||||||
.has_irtl_msrs = 1,
|
.has_irtl_msrs = 1,
|
||||||
.has_cst_prewake_bit = 1,
|
.has_cst_prewake_bit = 1,
|
||||||
.trl_msrs = TRL_BASE | TRL_CORECOUNT,
|
.trl_msrs = TRL_BASE | TRL_CORECOUNT,
|
||||||
.rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
|
.rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_PSYS,
|
||||||
.has_fixed_rapl_unit = 1,
|
.has_fixed_rapl_unit = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -806,7 +820,7 @@ static const struct platform_features spr_features = {
|
|||||||
.has_irtl_msrs = 1,
|
.has_irtl_msrs = 1,
|
||||||
.has_cst_prewake_bit = 1,
|
.has_cst_prewake_bit = 1,
|
||||||
.trl_msrs = TRL_BASE | TRL_CORECOUNT,
|
.trl_msrs = TRL_BASE | TRL_CORECOUNT,
|
||||||
.rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
|
.rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_PSYS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct platform_features srf_features = {
|
static const struct platform_features srf_features = {
|
||||||
@ -822,7 +836,7 @@ static const struct platform_features srf_features = {
|
|||||||
.has_irtl_msrs = 1,
|
.has_irtl_msrs = 1,
|
||||||
.has_cst_prewake_bit = 1,
|
.has_cst_prewake_bit = 1,
|
||||||
.trl_msrs = TRL_BASE | TRL_CORECOUNT,
|
.trl_msrs = TRL_BASE | TRL_CORECOUNT,
|
||||||
.rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
|
.rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_PSYS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct platform_features grr_features = {
|
static const struct platform_features grr_features = {
|
||||||
@ -838,7 +852,7 @@ static const struct platform_features grr_features = {
|
|||||||
.has_irtl_msrs = 1,
|
.has_irtl_msrs = 1,
|
||||||
.has_cst_prewake_bit = 1,
|
.has_cst_prewake_bit = 1,
|
||||||
.trl_msrs = TRL_BASE | TRL_CORECOUNT,
|
.trl_msrs = TRL_BASE | TRL_CORECOUNT,
|
||||||
.rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL,
|
.rapl_msrs = RAPL_PKG_ALL | RAPL_DRAM_ALL | RAPL_PSYS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct platform_features slv_features = {
|
static const struct platform_features slv_features = {
|
||||||
@ -997,18 +1011,19 @@ static const struct platform_data turbostat_pdata[] = {
|
|||||||
{ INTEL_SAPPHIRERAPIDS_X, &spr_features },
|
{ INTEL_SAPPHIRERAPIDS_X, &spr_features },
|
||||||
{ INTEL_EMERALDRAPIDS_X, &spr_features },
|
{ INTEL_EMERALDRAPIDS_X, &spr_features },
|
||||||
{ INTEL_GRANITERAPIDS_X, &spr_features },
|
{ INTEL_GRANITERAPIDS_X, &spr_features },
|
||||||
|
{ INTEL_GRANITERAPIDS_D, &spr_features },
|
||||||
{ INTEL_LAKEFIELD, &cnl_features },
|
{ INTEL_LAKEFIELD, &cnl_features },
|
||||||
{ INTEL_ALDERLAKE, &adl_features },
|
{ INTEL_ALDERLAKE, &adl_features },
|
||||||
{ INTEL_ALDERLAKE_L, &adl_features },
|
{ INTEL_ALDERLAKE_L, &adl_features },
|
||||||
{ INTEL_RAPTORLAKE, &adl_features },
|
{ INTEL_RAPTORLAKE, &adl_features },
|
||||||
{ INTEL_RAPTORLAKE_P, &adl_features },
|
{ INTEL_RAPTORLAKE_P, &adl_features },
|
||||||
{ INTEL_RAPTORLAKE_S, &adl_features },
|
{ INTEL_RAPTORLAKE_S, &adl_features },
|
||||||
{ INTEL_METEORLAKE, &cnl_features },
|
{ INTEL_METEORLAKE, &adl_features },
|
||||||
{ INTEL_METEORLAKE_L, &cnl_features },
|
{ INTEL_METEORLAKE_L, &adl_features },
|
||||||
{ INTEL_ARROWLAKE_H, &arl_features },
|
{ INTEL_ARROWLAKE_H, &adl_features },
|
||||||
{ INTEL_ARROWLAKE_U, &arl_features },
|
{ INTEL_ARROWLAKE_U, &adl_features },
|
||||||
{ INTEL_ARROWLAKE, &arl_features },
|
{ INTEL_ARROWLAKE, &adl_features },
|
||||||
{ INTEL_LUNARLAKE_M, &arl_features },
|
{ INTEL_LUNARLAKE_M, &lnl_features },
|
||||||
{ INTEL_ATOM_SILVERMONT, &slv_features },
|
{ INTEL_ATOM_SILVERMONT, &slv_features },
|
||||||
{ INTEL_ATOM_SILVERMONT_D, &slvd_features },
|
{ INTEL_ATOM_SILVERMONT_D, &slvd_features },
|
||||||
{ INTEL_ATOM_AIRMONT, &amt_features },
|
{ INTEL_ATOM_AIRMONT, &amt_features },
|
||||||
@ -1100,6 +1115,7 @@ enum rapl_rci_index {
|
|||||||
RAPL_RCI_INDEX_PKG_PERF_STATUS = 4,
|
RAPL_RCI_INDEX_PKG_PERF_STATUS = 4,
|
||||||
RAPL_RCI_INDEX_DRAM_PERF_STATUS = 5,
|
RAPL_RCI_INDEX_DRAM_PERF_STATUS = 5,
|
||||||
RAPL_RCI_INDEX_CORE_ENERGY = 6,
|
RAPL_RCI_INDEX_CORE_ENERGY = 6,
|
||||||
|
RAPL_RCI_INDEX_ENERGY_PLATFORM = 7,
|
||||||
NUM_RAPL_COUNTERS,
|
NUM_RAPL_COUNTERS,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1126,6 +1142,7 @@ struct rapl_counter_info_t {
|
|||||||
struct rapl_counter_info_t *rapl_counter_info_perdomain;
|
struct rapl_counter_info_t *rapl_counter_info_perdomain;
|
||||||
unsigned int rapl_counter_info_perdomain_size;
|
unsigned int rapl_counter_info_perdomain_size;
|
||||||
|
|
||||||
|
#define RAPL_COUNTER_FLAG_PLATFORM_COUNTER (1u << 0)
|
||||||
#define RAPL_COUNTER_FLAG_USE_MSR_SUM (1u << 1)
|
#define RAPL_COUNTER_FLAG_USE_MSR_SUM (1u << 1)
|
||||||
|
|
||||||
struct rapl_counter_arch_info {
|
struct rapl_counter_arch_info {
|
||||||
@ -1247,6 +1264,19 @@ static const struct rapl_counter_arch_info rapl_counter_arch_infos[] = {
|
|||||||
.compat_scale = 1.0,
|
.compat_scale = 1.0,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.feature_mask = RAPL_PSYS,
|
||||||
|
.perf_subsys = "power",
|
||||||
|
.perf_name = "energy-psys",
|
||||||
|
.msr = MSR_PLATFORM_ENERGY_STATUS,
|
||||||
|
.msr_mask = 0x00000000FFFFFFFF,
|
||||||
|
.msr_shift = 0,
|
||||||
|
.platform_rapl_msr_scale = &rapl_energy_units,
|
||||||
|
.rci_index = RAPL_RCI_INDEX_ENERGY_PLATFORM,
|
||||||
|
.bic = BIC_SysWatt | BIC_Sys_J,
|
||||||
|
.compat_scale = 1.0,
|
||||||
|
.flags = RAPL_COUNTER_FLAG_PLATFORM_COUNTER | RAPL_COUNTER_FLAG_USE_MSR_SUM,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rapl_counter {
|
struct rapl_counter {
|
||||||
@ -1674,6 +1704,7 @@ enum {
|
|||||||
IDX_PP1_ENERGY,
|
IDX_PP1_ENERGY,
|
||||||
IDX_PKG_PERF,
|
IDX_PKG_PERF,
|
||||||
IDX_DRAM_PERF,
|
IDX_DRAM_PERF,
|
||||||
|
IDX_PSYS_ENERGY,
|
||||||
IDX_COUNT,
|
IDX_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1718,6 +1749,9 @@ off_t idx_to_offset(int idx)
|
|||||||
case IDX_DRAM_PERF:
|
case IDX_DRAM_PERF:
|
||||||
offset = MSR_DRAM_PERF_STATUS;
|
offset = MSR_DRAM_PERF_STATUS;
|
||||||
break;
|
break;
|
||||||
|
case IDX_PSYS_ENERGY:
|
||||||
|
offset = MSR_PLATFORM_ENERGY_STATUS;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
offset = -1;
|
offset = -1;
|
||||||
}
|
}
|
||||||
@ -1748,6 +1782,9 @@ int offset_to_idx(off_t offset)
|
|||||||
case MSR_DRAM_PERF_STATUS:
|
case MSR_DRAM_PERF_STATUS:
|
||||||
idx = IDX_DRAM_PERF;
|
idx = IDX_DRAM_PERF;
|
||||||
break;
|
break;
|
||||||
|
case MSR_PLATFORM_ENERGY_STATUS:
|
||||||
|
idx = IDX_PSYS_ENERGY;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
idx = -1;
|
idx = -1;
|
||||||
}
|
}
|
||||||
@ -1769,6 +1806,8 @@ int idx_valid(int idx)
|
|||||||
return platform->rapl_msrs & RAPL_PKG_PERF_STATUS;
|
return platform->rapl_msrs & RAPL_PKG_PERF_STATUS;
|
||||||
case IDX_DRAM_PERF:
|
case IDX_DRAM_PERF:
|
||||||
return platform->rapl_msrs & RAPL_DRAM_PERF_STATUS;
|
return platform->rapl_msrs & RAPL_DRAM_PERF_STATUS;
|
||||||
|
case IDX_PSYS_ENERGY:
|
||||||
|
return platform->rapl_msrs & RAPL_PSYS;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1840,6 +1879,10 @@ struct system_summary {
|
|||||||
struct pkg_data packages;
|
struct pkg_data packages;
|
||||||
} average;
|
} average;
|
||||||
|
|
||||||
|
struct platform_counters {
|
||||||
|
struct rapl_counter energy_psys; /* MSR_PLATFORM_ENERGY_STATUS */
|
||||||
|
} platform_counters_odd, platform_counters_even;
|
||||||
|
|
||||||
struct cpu_topology {
|
struct cpu_topology {
|
||||||
int physical_package_id;
|
int physical_package_id;
|
||||||
int die_id;
|
int die_id;
|
||||||
@ -1848,6 +1891,7 @@ struct cpu_topology {
|
|||||||
int logical_node_id; /* 0-based count within the package */
|
int logical_node_id; /* 0-based count within the package */
|
||||||
int physical_core_id;
|
int physical_core_id;
|
||||||
int thread_id;
|
int thread_id;
|
||||||
|
int type;
|
||||||
cpu_set_t *put_ids; /* Processing Unit/Thread IDs */
|
cpu_set_t *put_ids; /* Processing Unit/Thread IDs */
|
||||||
} *cpus;
|
} *cpus;
|
||||||
|
|
||||||
@ -2291,7 +2335,7 @@ void print_header(char *delim)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PMT_TYPE_XTAL_TIME:
|
case PMT_TYPE_XTAL_TIME:
|
||||||
outp += sprintf(outp, "%s%s", delim, ppmt->name);
|
outp += sprintf(outp, "%s%s", (printed++ ? delim : ""), ppmt->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2365,7 +2409,7 @@ void print_header(char *delim)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PMT_TYPE_XTAL_TIME:
|
case PMT_TYPE_XTAL_TIME:
|
||||||
outp += sprintf(outp, "%s%s", delim, ppmt->name);
|
outp += sprintf(outp, "%s%s", (printed++ ? delim : ""), ppmt->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2496,13 +2540,18 @@ void print_header(char *delim)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PMT_TYPE_XTAL_TIME:
|
case PMT_TYPE_XTAL_TIME:
|
||||||
outp += sprintf(outp, "%s%s", delim, ppmt->name);
|
outp += sprintf(outp, "%s%s", (printed++ ? delim : ""), ppmt->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ppmt = ppmt->next;
|
ppmt = ppmt->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DO_BIC(BIC_SysWatt))
|
||||||
|
outp += sprintf(outp, "%sSysWatt", (printed++ ? delim : ""));
|
||||||
|
if (DO_BIC(BIC_Sys_J))
|
||||||
|
outp += sprintf(outp, "%sSys_J", (printed++ ? delim : ""));
|
||||||
|
|
||||||
outp += sprintf(outp, "\n");
|
outp += sprintf(outp, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2510,6 +2559,7 @@ int dump_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct msr_counter *mp;
|
struct msr_counter *mp;
|
||||||
|
struct platform_counters *pplat_cnt = p == package_odd ? &platform_counters_odd : &platform_counters_even;
|
||||||
|
|
||||||
outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p);
|
outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p);
|
||||||
|
|
||||||
@ -2581,6 +2631,7 @@ int dump_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p
|
|||||||
outp += sprintf(outp, "Joules COR: %0llX\n", p->energy_cores.raw_value);
|
outp += sprintf(outp, "Joules COR: %0llX\n", p->energy_cores.raw_value);
|
||||||
outp += sprintf(outp, "Joules GFX: %0llX\n", p->energy_gfx.raw_value);
|
outp += sprintf(outp, "Joules GFX: %0llX\n", p->energy_gfx.raw_value);
|
||||||
outp += sprintf(outp, "Joules RAM: %0llX\n", p->energy_dram.raw_value);
|
outp += sprintf(outp, "Joules RAM: %0llX\n", p->energy_dram.raw_value);
|
||||||
|
outp += sprintf(outp, "Joules PSYS: %0llX\n", pplat_cnt->energy_psys.raw_value);
|
||||||
outp += sprintf(outp, "Throttle PKG: %0llX\n", p->rapl_pkg_perf_status.raw_value);
|
outp += sprintf(outp, "Throttle PKG: %0llX\n", p->rapl_pkg_perf_status.raw_value);
|
||||||
outp += sprintf(outp, "Throttle RAM: %0llX\n", p->rapl_dram_perf_status.raw_value);
|
outp += sprintf(outp, "Throttle RAM: %0llX\n", p->rapl_dram_perf_status.raw_value);
|
||||||
outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c);
|
outp += sprintf(outp, "PTM: %dC\n", p->pkg_temp_c);
|
||||||
@ -2619,6 +2670,9 @@ double rapl_counter_get_value(const struct rapl_counter *c, enum rapl_unit desir
|
|||||||
*/
|
*/
|
||||||
int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
|
int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
|
||||||
{
|
{
|
||||||
|
static int count;
|
||||||
|
|
||||||
|
struct platform_counters *pplat_cnt = NULL;
|
||||||
double interval_float, tsc;
|
double interval_float, tsc;
|
||||||
char *fmt8;
|
char *fmt8;
|
||||||
int i;
|
int i;
|
||||||
@ -2628,6 +2682,11 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data
|
|||||||
char *delim = "\t";
|
char *delim = "\t";
|
||||||
int printed = 0;
|
int printed = 0;
|
||||||
|
|
||||||
|
if (t == &average.threads) {
|
||||||
|
pplat_cnt = count & 1 ? &platform_counters_odd : &platform_counters_even;
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
/* if showing only 1st thread in core and this isn't one, bail out */
|
/* if showing only 1st thread in core and this isn't one, bail out */
|
||||||
if (show_core_only && !is_cpu_first_thread_in_core(t, c, p))
|
if (show_core_only && !is_cpu_first_thread_in_core(t, c, p))
|
||||||
return 0;
|
return 0;
|
||||||
@ -2788,6 +2847,8 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0, ppmt = sys.pmt_tp; ppmt; i++, ppmt = ppmt->next) {
|
for (i = 0, ppmt = sys.pmt_tp; ppmt; i++, ppmt = ppmt->next) {
|
||||||
|
const unsigned long value_raw = t->pmt_counter[i];
|
||||||
|
const double value_converted = 100.0 * value_raw / crystal_hz / interval_float;
|
||||||
switch (ppmt->type) {
|
switch (ppmt->type) {
|
||||||
case PMT_TYPE_RAW:
|
case PMT_TYPE_RAW:
|
||||||
if (pmt_counter_get_width(ppmt) <= 32)
|
if (pmt_counter_get_width(ppmt) <= 32)
|
||||||
@ -2799,9 +2860,6 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PMT_TYPE_XTAL_TIME:
|
case PMT_TYPE_XTAL_TIME:
|
||||||
const unsigned long value_raw = t->pmt_counter[i];
|
|
||||||
const double value_converted = 100.0 * value_raw / crystal_hz / interval_float;
|
|
||||||
|
|
||||||
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
|
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2869,6 +2927,8 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0, ppmt = sys.pmt_cp; ppmt; i++, ppmt = ppmt->next) {
|
for (i = 0, ppmt = sys.pmt_cp; ppmt; i++, ppmt = ppmt->next) {
|
||||||
|
const unsigned long value_raw = c->pmt_counter[i];
|
||||||
|
const double value_converted = 100.0 * value_raw / crystal_hz / interval_float;
|
||||||
switch (ppmt->type) {
|
switch (ppmt->type) {
|
||||||
case PMT_TYPE_RAW:
|
case PMT_TYPE_RAW:
|
||||||
if (pmt_counter_get_width(ppmt) <= 32)
|
if (pmt_counter_get_width(ppmt) <= 32)
|
||||||
@ -2880,9 +2940,6 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PMT_TYPE_XTAL_TIME:
|
case PMT_TYPE_XTAL_TIME:
|
||||||
const unsigned long value_raw = c->pmt_counter[i];
|
|
||||||
const double value_converted = 100.0 * value_raw / crystal_hz / interval_float;
|
|
||||||
|
|
||||||
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
|
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3068,6 +3125,8 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0, ppmt = sys.pmt_pp; ppmt; i++, ppmt = ppmt->next) {
|
for (i = 0, ppmt = sys.pmt_pp; ppmt; i++, ppmt = ppmt->next) {
|
||||||
|
const unsigned long value_raw = p->pmt_counter[i];
|
||||||
|
const double value_converted = 100.0 * value_raw / crystal_hz / interval_float;
|
||||||
switch (ppmt->type) {
|
switch (ppmt->type) {
|
||||||
case PMT_TYPE_RAW:
|
case PMT_TYPE_RAW:
|
||||||
if (pmt_counter_get_width(ppmt) <= 32)
|
if (pmt_counter_get_width(ppmt) <= 32)
|
||||||
@ -3079,14 +3138,18 @@ int format_counters(struct thread_data *t, struct core_data *c, struct pkg_data
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PMT_TYPE_XTAL_TIME:
|
case PMT_TYPE_XTAL_TIME:
|
||||||
const unsigned long value_raw = p->pmt_counter[i];
|
|
||||||
const double value_converted = 100.0 * value_raw / crystal_hz / interval_float;
|
|
||||||
|
|
||||||
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
|
outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DO_BIC(BIC_SysWatt) && (t == &average.threads))
|
||||||
|
outp += sprintf(outp, fmt8, (printed++ ? delim : ""),
|
||||||
|
rapl_counter_get_value(&pplat_cnt->energy_psys, RAPL_UNIT_WATTS, interval_float));
|
||||||
|
if (DO_BIC(BIC_Sys_J) && (t == &average.threads))
|
||||||
|
outp += sprintf(outp, fmt8, (printed++ ? delim : ""),
|
||||||
|
rapl_counter_get_value(&pplat_cnt->energy_psys, RAPL_UNIT_JOULES, interval_float));
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (*(outp - 1) != '\n')
|
if (*(outp - 1) != '\n')
|
||||||
outp += sprintf(outp, "\n");
|
outp += sprintf(outp, "\n");
|
||||||
@ -3394,6 +3457,11 @@ int delta_cpu(struct thread_data *t, struct core_data *c,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void delta_platform(struct platform_counters *new, struct platform_counters *old)
|
||||||
|
{
|
||||||
|
old->energy_psys.raw_value = new->energy_psys.raw_value - old->energy_psys.raw_value;
|
||||||
|
}
|
||||||
|
|
||||||
void rapl_counter_clear(struct rapl_counter *c)
|
void rapl_counter_clear(struct rapl_counter *c)
|
||||||
{
|
{
|
||||||
c->raw_value = 0;
|
c->raw_value = 0;
|
||||||
@ -4123,6 +4191,9 @@ static size_t cstate_counter_info_count_perf(const struct cstate_counter_info_t
|
|||||||
|
|
||||||
void write_rapl_counter(struct rapl_counter *rc, struct rapl_counter_info_t *rci, unsigned int idx)
|
void write_rapl_counter(struct rapl_counter *rc, struct rapl_counter_info_t *rci, unsigned int idx)
|
||||||
{
|
{
|
||||||
|
if (rci->source[idx] == COUNTER_SOURCE_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
rc->raw_value = rci->data[idx];
|
rc->raw_value = rci->data[idx];
|
||||||
rc->unit = rci->unit[idx];
|
rc->unit = rci->unit[idx];
|
||||||
rc->scale = rci->scale[idx];
|
rc->scale = rci->scale[idx];
|
||||||
@ -4130,6 +4201,7 @@ void write_rapl_counter(struct rapl_counter *rc, struct rapl_counter_info_t *rci
|
|||||||
|
|
||||||
int get_rapl_counters(int cpu, unsigned int domain, struct core_data *c, struct pkg_data *p)
|
int get_rapl_counters(int cpu, unsigned int domain, struct core_data *c, struct pkg_data *p)
|
||||||
{
|
{
|
||||||
|
struct platform_counters *pplat_cnt = p == package_odd ? &platform_counters_odd : &platform_counters_even;
|
||||||
unsigned long long perf_data[NUM_RAPL_COUNTERS + 1];
|
unsigned long long perf_data[NUM_RAPL_COUNTERS + 1];
|
||||||
struct rapl_counter_info_t *rci;
|
struct rapl_counter_info_t *rci;
|
||||||
|
|
||||||
@ -4157,6 +4229,7 @@ int get_rapl_counters(int cpu, unsigned int domain, struct core_data *c, struct
|
|||||||
for (unsigned int i = 0, pi = 1; i < NUM_RAPL_COUNTERS; ++i) {
|
for (unsigned int i = 0, pi = 1; i < NUM_RAPL_COUNTERS; ++i) {
|
||||||
switch (rci->source[i]) {
|
switch (rci->source[i]) {
|
||||||
case COUNTER_SOURCE_NONE:
|
case COUNTER_SOURCE_NONE:
|
||||||
|
rci->data[i] = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COUNTER_SOURCE_PERF:
|
case COUNTER_SOURCE_PERF:
|
||||||
@ -4195,7 +4268,7 @@ int get_rapl_counters(int cpu, unsigned int domain, struct core_data *c, struct
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BUILD_BUG_ON(NUM_RAPL_COUNTERS != 7);
|
BUILD_BUG_ON(NUM_RAPL_COUNTERS != 8);
|
||||||
write_rapl_counter(&p->energy_pkg, rci, RAPL_RCI_INDEX_ENERGY_PKG);
|
write_rapl_counter(&p->energy_pkg, rci, RAPL_RCI_INDEX_ENERGY_PKG);
|
||||||
write_rapl_counter(&p->energy_cores, rci, RAPL_RCI_INDEX_ENERGY_CORES);
|
write_rapl_counter(&p->energy_cores, rci, RAPL_RCI_INDEX_ENERGY_CORES);
|
||||||
write_rapl_counter(&p->energy_dram, rci, RAPL_RCI_INDEX_DRAM);
|
write_rapl_counter(&p->energy_dram, rci, RAPL_RCI_INDEX_DRAM);
|
||||||
@ -4203,6 +4276,7 @@ int get_rapl_counters(int cpu, unsigned int domain, struct core_data *c, struct
|
|||||||
write_rapl_counter(&p->rapl_pkg_perf_status, rci, RAPL_RCI_INDEX_PKG_PERF_STATUS);
|
write_rapl_counter(&p->rapl_pkg_perf_status, rci, RAPL_RCI_INDEX_PKG_PERF_STATUS);
|
||||||
write_rapl_counter(&p->rapl_dram_perf_status, rci, RAPL_RCI_INDEX_DRAM_PERF_STATUS);
|
write_rapl_counter(&p->rapl_dram_perf_status, rci, RAPL_RCI_INDEX_DRAM_PERF_STATUS);
|
||||||
write_rapl_counter(&c->core_energy, rci, RAPL_RCI_INDEX_CORE_ENERGY);
|
write_rapl_counter(&c->core_energy, rci, RAPL_RCI_INDEX_CORE_ENERGY);
|
||||||
|
write_rapl_counter(&pplat_cnt->energy_psys, rci, RAPL_RCI_INDEX_ENERGY_PLATFORM);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -5385,6 +5459,9 @@ static int parse_cpu_str(char *cpu_str, cpu_set_t *cpu_set, int cpu_set_size)
|
|||||||
if (*next == '-') /* no negative cpu numbers */
|
if (*next == '-') /* no negative cpu numbers */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
if (*next == '\0' || *next == '\n')
|
||||||
|
break;
|
||||||
|
|
||||||
start = strtoul(next, &next, 10);
|
start = strtoul(next, &next, 10);
|
||||||
|
|
||||||
if (start >= CPU_SUBSET_MAXCPUS)
|
if (start >= CPU_SUBSET_MAXCPUS)
|
||||||
@ -5656,6 +5733,32 @@ int init_thread_id(int cpu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int set_my_cpu_type(void)
|
||||||
|
{
|
||||||
|
unsigned int eax, ebx, ecx, edx;
|
||||||
|
unsigned int max_level;
|
||||||
|
|
||||||
|
__cpuid(0, max_level, ebx, ecx, edx);
|
||||||
|
|
||||||
|
if (max_level < CPUID_LEAF_MODEL_ID)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
__cpuid(CPUID_LEAF_MODEL_ID, eax, ebx, ecx, edx);
|
||||||
|
|
||||||
|
return (eax >> CPUID_LEAF_MODEL_ID_CORE_TYPE_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
int set_cpu_hybrid_type(int cpu)
|
||||||
|
{
|
||||||
|
if (cpu_migrate(cpu))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int type = set_my_cpu_type();
|
||||||
|
|
||||||
|
cpus[cpu].type = type;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* snapshot_proc_interrupts()
|
* snapshot_proc_interrupts()
|
||||||
*
|
*
|
||||||
@ -5728,28 +5831,21 @@ int snapshot_proc_interrupts(void)
|
|||||||
*/
|
*/
|
||||||
int snapshot_graphics(int idx)
|
int snapshot_graphics(int idx)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
|
rewind(gfx_info[idx].fp);
|
||||||
|
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case GFX_rc6:
|
case GFX_rc6:
|
||||||
case SAM_mc6:
|
case SAM_mc6:
|
||||||
fp = fopen_or_die(gfx_info[idx].path, "r");
|
retval = fscanf(gfx_info[idx].fp, "%lld", &gfx_info[idx].val_ull);
|
||||||
retval = fscanf(fp, "%lld", &gfx_info[idx].val_ull);
|
|
||||||
if (retval != 1)
|
if (retval != 1)
|
||||||
err(1, "rc6");
|
err(1, "rc6");
|
||||||
fclose(fp);
|
|
||||||
return 0;
|
return 0;
|
||||||
case GFX_MHz:
|
case GFX_MHz:
|
||||||
case GFX_ACTMHz:
|
case GFX_ACTMHz:
|
||||||
case SAM_MHz:
|
case SAM_MHz:
|
||||||
case SAM_ACTMHz:
|
case SAM_ACTMHz:
|
||||||
if (gfx_info[idx].fp == NULL) {
|
|
||||||
gfx_info[idx].fp = fopen_or_die(gfx_info[idx].path, "r");
|
|
||||||
} else {
|
|
||||||
rewind(gfx_info[idx].fp);
|
|
||||||
fflush(gfx_info[idx].fp);
|
|
||||||
}
|
|
||||||
retval = fscanf(gfx_info[idx].fp, "%d", &gfx_info[idx].val);
|
retval = fscanf(gfx_info[idx].fp, "%d", &gfx_info[idx].val);
|
||||||
if (retval != 1)
|
if (retval != 1)
|
||||||
err(1, "MHz");
|
err(1, "MHz");
|
||||||
@ -6116,6 +6212,7 @@ void turbostat_loop()
|
|||||||
re_initialize();
|
re_initialize();
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
delta_platform(&platform_counters_odd, &platform_counters_even);
|
||||||
compute_average(EVEN_COUNTERS);
|
compute_average(EVEN_COUNTERS);
|
||||||
format_all_counters(EVEN_COUNTERS);
|
format_all_counters(EVEN_COUNTERS);
|
||||||
flush_output_stdout();
|
flush_output_stdout();
|
||||||
@ -6139,6 +6236,7 @@ void turbostat_loop()
|
|||||||
re_initialize();
|
re_initialize();
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
delta_platform(&platform_counters_even, &platform_counters_odd);
|
||||||
compute_average(ODD_COUNTERS);
|
compute_average(ODD_COUNTERS);
|
||||||
format_all_counters(ODD_COUNTERS);
|
format_all_counters(ODD_COUNTERS);
|
||||||
flush_output_stdout();
|
flush_output_stdout();
|
||||||
@ -6442,14 +6540,25 @@ static void probe_intel_uncore_frequency(void)
|
|||||||
probe_intel_uncore_frequency_legacy();
|
probe_intel_uncore_frequency_legacy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_graphics_fp(char *path, int idx)
|
||||||
|
{
|
||||||
|
if (!access(path, R_OK))
|
||||||
|
gfx_info[idx].fp = fopen_or_die(path, "r");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enlarge this if there are /sys/class/drm/card2 ... */
|
||||||
|
#define GFX_MAX_CARDS 2
|
||||||
|
|
||||||
static void probe_graphics(void)
|
static void probe_graphics(void)
|
||||||
{
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
int i;
|
||||||
|
|
||||||
/* Xe graphics sysfs knobs */
|
/* Xe graphics sysfs knobs */
|
||||||
if (!access("/sys/class/drm/card0/device/tile0/gt0/gtidle/idle_residency_ms", R_OK)) {
|
if (!access("/sys/class/drm/card0/device/tile0/gt0/gtidle/idle_residency_ms", R_OK)) {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char buf[8];
|
char buf[8];
|
||||||
bool gt0_is_gt;
|
bool gt0_is_gt;
|
||||||
int idx;
|
|
||||||
|
|
||||||
fp = fopen("/sys/class/drm/card0/device/tile0/gt0/gtidle/name", "r");
|
fp = fopen("/sys/class/drm/card0/device/tile0/gt0/gtidle/name", "r");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
@ -6468,81 +6577,76 @@ static void probe_graphics(void)
|
|||||||
else
|
else
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
idx = gt0_is_gt ? GFX_rc6 : SAM_mc6;
|
set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/gtidle/idle_residency_ms", gt0_is_gt ? GFX_rc6 : SAM_mc6);
|
||||||
gfx_info[idx].path = "/sys/class/drm/card0/device/tile0/gt0/gtidle/idle_residency_ms";
|
|
||||||
|
|
||||||
idx = gt0_is_gt ? GFX_MHz : SAM_MHz;
|
set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/freq0/cur_freq", gt0_is_gt ? GFX_MHz : SAM_MHz);
|
||||||
if (!access("/sys/class/drm/card0/device/tile0/gt0/freq0/cur_freq", R_OK))
|
|
||||||
gfx_info[idx].path = "/sys/class/drm/card0/device/tile0/gt0/freq0/cur_freq";
|
|
||||||
|
|
||||||
idx = gt0_is_gt ? GFX_ACTMHz : SAM_ACTMHz;
|
set_graphics_fp("/sys/class/drm/card0/device/tile0/gt0/freq0/act_freq", gt0_is_gt ? GFX_ACTMHz : SAM_ACTMHz);
|
||||||
if (!access("/sys/class/drm/card0/device/tile0/gt0/freq0/act_freq", R_OK))
|
|
||||||
gfx_info[idx].path = "/sys/class/drm/card0/device/tile0/gt0/freq0/act_freq";
|
|
||||||
|
|
||||||
idx = gt0_is_gt ? SAM_mc6 : GFX_rc6;
|
set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/gtidle/idle_residency_ms", gt0_is_gt ? SAM_mc6 : GFX_rc6);
|
||||||
if (!access("/sys/class/drm/card0/device/tile0/gt1/gtidle/idle_residency_ms", R_OK))
|
|
||||||
gfx_info[idx].path = "/sys/class/drm/card0/device/tile0/gt1/gtidle/idle_residency_ms";
|
|
||||||
|
|
||||||
idx = gt0_is_gt ? SAM_MHz : GFX_MHz;
|
set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/freq0/cur_freq", gt0_is_gt ? SAM_MHz : GFX_MHz);
|
||||||
if (!access("/sys/class/drm/card0/device/tile0/gt1/freq0/cur_freq", R_OK))
|
|
||||||
gfx_info[idx].path = "/sys/class/drm/card0/device/tile0/gt1/freq0/cur_freq";
|
|
||||||
|
|
||||||
idx = gt0_is_gt ? SAM_ACTMHz : GFX_ACTMHz;
|
set_graphics_fp("/sys/class/drm/card0/device/tile0/gt1/freq0/act_freq", gt0_is_gt ? SAM_ACTMHz : GFX_ACTMHz);
|
||||||
if (!access("/sys/class/drm/card0/device/tile0/gt1/freq0/act_freq", R_OK))
|
|
||||||
gfx_info[idx].path = "/sys/class/drm/card0/device/tile0/gt1/freq0/act_freq";
|
|
||||||
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
next:
|
next:
|
||||||
/* New i915 graphics sysfs knobs */
|
/* New i915 graphics sysfs knobs */
|
||||||
if (!access("/sys/class/drm/card0/gt/gt0/rc6_residency_ms", R_OK)) {
|
for (i = 0; i < GFX_MAX_CARDS; i++) {
|
||||||
gfx_info[GFX_rc6].path = "/sys/class/drm/card0/gt/gt0/rc6_residency_ms";
|
snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt0/rc6_residency_ms", i);
|
||||||
|
if (!access(path, R_OK))
|
||||||
if (!access("/sys/class/drm/card0/gt/gt0/rps_cur_freq_mhz", R_OK))
|
break;
|
||||||
gfx_info[GFX_MHz].path = "/sys/class/drm/card0/gt/gt0/rps_cur_freq_mhz";
|
|
||||||
|
|
||||||
if (!access("/sys/class/drm/card0/gt/gt0/rps_act_freq_mhz", R_OK))
|
|
||||||
gfx_info[GFX_ACTMHz].path = "/sys/class/drm/card0/gt/gt0/rps_act_freq_mhz";
|
|
||||||
|
|
||||||
if (!access("/sys/class/drm/card0/gt/gt1/rc6_residency_ms", R_OK))
|
|
||||||
gfx_info[SAM_mc6].path = "/sys/class/drm/card0/gt/gt1/rc6_residency_ms";
|
|
||||||
|
|
||||||
if (!access("/sys/class/drm/card0/gt/gt1/rps_cur_freq_mhz", R_OK))
|
|
||||||
gfx_info[SAM_MHz].path = "/sys/class/drm/card0/gt/gt1/rps_cur_freq_mhz";
|
|
||||||
|
|
||||||
if (!access("/sys/class/drm/card0/gt/gt1/rps_act_freq_mhz", R_OK))
|
|
||||||
gfx_info[SAM_ACTMHz].path = "/sys/class/drm/card0/gt/gt1/rps_act_freq_mhz";
|
|
||||||
|
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i == GFX_MAX_CARDS)
|
||||||
|
goto legacy_i915;
|
||||||
|
|
||||||
|
snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt0/rc6_residency_ms", i);
|
||||||
|
set_graphics_fp(path, GFX_rc6);
|
||||||
|
|
||||||
|
snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt0/rps_cur_freq_mhz", i);
|
||||||
|
set_graphics_fp(path, GFX_MHz);
|
||||||
|
|
||||||
|
snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt0/rps_act_freq_mhz", i);
|
||||||
|
set_graphics_fp(path, GFX_ACTMHz);
|
||||||
|
|
||||||
|
snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt1/rc6_residency_ms", i);
|
||||||
|
set_graphics_fp(path, SAM_mc6);
|
||||||
|
|
||||||
|
snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt1/rps_cur_freq_mhz", i);
|
||||||
|
set_graphics_fp(path, SAM_MHz);
|
||||||
|
|
||||||
|
snprintf(path, PATH_MAX, "/sys/class/drm/card%d/gt/gt1/rps_act_freq_mhz", i);
|
||||||
|
set_graphics_fp(path, SAM_ACTMHz);
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
legacy_i915:
|
||||||
/* Fall back to traditional i915 graphics sysfs knobs */
|
/* Fall back to traditional i915 graphics sysfs knobs */
|
||||||
if (!access("/sys/class/drm/card0/power/rc6_residency_ms", R_OK))
|
set_graphics_fp("/sys/class/drm/card0/power/rc6_residency_ms", GFX_rc6);
|
||||||
gfx_info[GFX_rc6].path = "/sys/class/drm/card0/power/rc6_residency_ms";
|
|
||||||
|
|
||||||
if (!access("/sys/class/drm/card0/gt_cur_freq_mhz", R_OK))
|
set_graphics_fp("/sys/class/drm/card0/gt_cur_freq_mhz", GFX_MHz);
|
||||||
gfx_info[GFX_MHz].path = "/sys/class/drm/card0/gt_cur_freq_mhz";
|
if (!gfx_info[GFX_MHz].fp)
|
||||||
else if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", R_OK))
|
set_graphics_fp("/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz", GFX_MHz);
|
||||||
gfx_info[GFX_MHz].path = "/sys/class/graphics/fb0/device/drm/card0/gt_cur_freq_mhz";
|
|
||||||
|
|
||||||
if (!access("/sys/class/drm/card0/gt_act_freq_mhz", R_OK))
|
set_graphics_fp("/sys/class/drm/card0/gt_act_freq_mhz", GFX_ACTMHz);
|
||||||
gfx_info[GFX_ACTMHz].path = "/sys/class/drm/card0/gt_act_freq_mhz";
|
if (!gfx_info[GFX_ACTMHz].fp)
|
||||||
else if (!access("/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz", R_OK))
|
set_graphics_fp("/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz", GFX_ACTMHz);
|
||||||
gfx_info[GFX_ACTMHz].path = "/sys/class/graphics/fb0/device/drm/card0/gt_act_freq_mhz";
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (gfx_info[GFX_rc6].path)
|
if (gfx_info[GFX_rc6].fp)
|
||||||
BIC_PRESENT(BIC_GFX_rc6);
|
BIC_PRESENT(BIC_GFX_rc6);
|
||||||
if (gfx_info[GFX_MHz].path)
|
if (gfx_info[GFX_MHz].fp)
|
||||||
BIC_PRESENT(BIC_GFXMHz);
|
BIC_PRESENT(BIC_GFXMHz);
|
||||||
if (gfx_info[GFX_ACTMHz].path)
|
if (gfx_info[GFX_ACTMHz].fp)
|
||||||
BIC_PRESENT(BIC_GFXACTMHz);
|
BIC_PRESENT(BIC_GFXACTMHz);
|
||||||
if (gfx_info[SAM_mc6].path)
|
if (gfx_info[SAM_mc6].fp)
|
||||||
BIC_PRESENT(BIC_SAM_mc6);
|
BIC_PRESENT(BIC_SAM_mc6);
|
||||||
if (gfx_info[SAM_MHz].path)
|
if (gfx_info[SAM_MHz].fp)
|
||||||
BIC_PRESENT(BIC_SAMMHz);
|
BIC_PRESENT(BIC_SAMMHz);
|
||||||
if (gfx_info[SAM_ACTMHz].path)
|
if (gfx_info[SAM_ACTMHz].fp)
|
||||||
BIC_PRESENT(BIC_SAMACTMHz);
|
BIC_PRESENT(BIC_SAMACTMHz);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6911,8 +7015,8 @@ void rapl_probe_intel(void)
|
|||||||
unsigned long long msr;
|
unsigned long long msr;
|
||||||
unsigned int time_unit;
|
unsigned int time_unit;
|
||||||
double tdp;
|
double tdp;
|
||||||
const unsigned long long bic_watt_bits = BIC_PkgWatt | BIC_CorWatt | BIC_RAMWatt | BIC_GFXWatt;
|
const unsigned long long bic_watt_bits = BIC_SysWatt | BIC_PkgWatt | BIC_CorWatt | BIC_RAMWatt | BIC_GFXWatt;
|
||||||
const unsigned long long bic_joules_bits = BIC_Pkg_J | BIC_Cor_J | BIC_RAM_J | BIC_GFX_J;
|
const unsigned long long bic_joules_bits = BIC_Sys_J | BIC_Pkg_J | BIC_Cor_J | BIC_RAM_J | BIC_GFX_J;
|
||||||
|
|
||||||
if (rapl_joules)
|
if (rapl_joules)
|
||||||
bic_enabled &= ~bic_watt_bits;
|
bic_enabled &= ~bic_watt_bits;
|
||||||
@ -7572,6 +7676,9 @@ void rapl_perf_init(void)
|
|||||||
|
|
||||||
domain_visited[next_domain] = 1;
|
domain_visited[next_domain] = 1;
|
||||||
|
|
||||||
|
if ((cai->flags & RAPL_COUNTER_FLAG_PLATFORM_COUNTER) && (cpu != base_cpu))
|
||||||
|
continue;
|
||||||
|
|
||||||
struct rapl_counter_info_t *rci = &rapl_counter_info_perdomain[next_domain];
|
struct rapl_counter_info_t *rci = &rapl_counter_info_perdomain[next_domain];
|
||||||
|
|
||||||
/* Check if the counter is enabled and accessible */
|
/* Check if the counter is enabled and accessible */
|
||||||
@ -8196,7 +8303,7 @@ void topology_probe(bool startup)
|
|||||||
set_max_cpu_num();
|
set_max_cpu_num();
|
||||||
topo.num_cpus = 0;
|
topo.num_cpus = 0;
|
||||||
for_all_proc_cpus(count_cpus);
|
for_all_proc_cpus(count_cpus);
|
||||||
if (!summary_only && topo.num_cpus > 1)
|
if (!summary_only)
|
||||||
BIC_PRESENT(BIC_CPU);
|
BIC_PRESENT(BIC_CPU);
|
||||||
|
|
||||||
if (debug > 1)
|
if (debug > 1)
|
||||||
@ -8284,6 +8391,8 @@ void topology_probe(bool startup)
|
|||||||
|
|
||||||
for_all_proc_cpus(init_thread_id);
|
for_all_proc_cpus(init_thread_id);
|
||||||
|
|
||||||
|
for_all_proc_cpus(set_cpu_hybrid_type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For online cpus
|
* For online cpus
|
||||||
* find max_core_id, max_package_id
|
* find max_core_id, max_package_id
|
||||||
@ -8332,7 +8441,7 @@ void topology_probe(bool startup)
|
|||||||
topo.cores_per_node = max_core_id + 1;
|
topo.cores_per_node = max_core_id + 1;
|
||||||
if (debug > 1)
|
if (debug > 1)
|
||||||
fprintf(outf, "max_core_id %d, sizing for %d cores per package\n", max_core_id, topo.cores_per_node);
|
fprintf(outf, "max_core_id %d, sizing for %d cores per package\n", max_core_id, topo.cores_per_node);
|
||||||
if (!summary_only && topo.cores_per_node > 1)
|
if (!summary_only)
|
||||||
BIC_PRESENT(BIC_Core);
|
BIC_PRESENT(BIC_Core);
|
||||||
|
|
||||||
topo.num_die = topo.max_die_id + 1;
|
topo.num_die = topo.max_die_id + 1;
|
||||||
@ -8548,6 +8657,35 @@ void check_perf_access(void)
|
|||||||
bic_enabled &= ~BIC_IPC;
|
bic_enabled &= ~BIC_IPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool perf_has_hybrid_devices(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 0: unknown
|
||||||
|
* 1: has separate perf device for p and e core
|
||||||
|
* -1: doesn't have separate perf device for p and e core
|
||||||
|
*/
|
||||||
|
static int cached;
|
||||||
|
|
||||||
|
if (cached > 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (cached < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (access("/sys/bus/event_source/devices/cpu_core", F_OK)) {
|
||||||
|
cached = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (access("/sys/bus/event_source/devices/cpu_atom", F_OK)) {
|
||||||
|
cached = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cached = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int added_perf_counters_init_(struct perf_counter_info *pinfo)
|
int added_perf_counters_init_(struct perf_counter_info *pinfo)
|
||||||
{
|
{
|
||||||
size_t num_domains = 0;
|
size_t num_domains = 0;
|
||||||
@ -8604,29 +8742,56 @@ int added_perf_counters_init_(struct perf_counter_info *pinfo)
|
|||||||
if (domain_visited[next_domain])
|
if (domain_visited[next_domain])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
perf_type = read_perf_type(pinfo->device);
|
/*
|
||||||
|
* Intel hybrid platforms expose different perf devices for P and E cores.
|
||||||
|
* Instead of one, "/sys/bus/event_source/devices/cpu" device, there are
|
||||||
|
* "/sys/bus/event_source/devices/{cpu_core,cpu_atom}".
|
||||||
|
*
|
||||||
|
* This makes it more complicated to the user, because most of the counters
|
||||||
|
* are available on both and have to be handled manually, otherwise.
|
||||||
|
*
|
||||||
|
* Code below, allow user to use the old "cpu" name, which is translated accordingly.
|
||||||
|
*/
|
||||||
|
const char *perf_device = pinfo->device;
|
||||||
|
|
||||||
|
if (strcmp(perf_device, "cpu") == 0 && perf_has_hybrid_devices()) {
|
||||||
|
switch (cpus[cpu].type) {
|
||||||
|
case INTEL_PCORE_TYPE:
|
||||||
|
perf_device = "cpu_core";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INTEL_ECORE_TYPE:
|
||||||
|
perf_device = "cpu_atom";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* Don't change, we will probably fail and report a problem soon. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
perf_type = read_perf_type(perf_device);
|
||||||
if (perf_type == (unsigned int)-1) {
|
if (perf_type == (unsigned int)-1) {
|
||||||
warnx("%s: perf/%s/%s: failed to read %s",
|
warnx("%s: perf/%s/%s: failed to read %s",
|
||||||
__func__, pinfo->device, pinfo->event, "type");
|
__func__, perf_device, pinfo->event, "type");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
perf_config = read_perf_config(pinfo->device, pinfo->event);
|
perf_config = read_perf_config(perf_device, pinfo->event);
|
||||||
if (perf_config == (unsigned int)-1) {
|
if (perf_config == (unsigned int)-1) {
|
||||||
warnx("%s: perf/%s/%s: failed to read %s",
|
warnx("%s: perf/%s/%s: failed to read %s",
|
||||||
__func__, pinfo->device, pinfo->event, "config");
|
__func__, perf_device, pinfo->event, "config");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scale is not required, some counters just don't have it. */
|
/* Scale is not required, some counters just don't have it. */
|
||||||
perf_scale = read_perf_scale(pinfo->device, pinfo->event);
|
perf_scale = read_perf_scale(perf_device, pinfo->event);
|
||||||
if (perf_scale == 0.0)
|
if (perf_scale == 0.0)
|
||||||
perf_scale = 1.0;
|
perf_scale = 1.0;
|
||||||
|
|
||||||
fd_perf = open_perf_counter(cpu, perf_type, perf_config, -1, 0);
|
fd_perf = open_perf_counter(cpu, perf_type, perf_config, -1, 0);
|
||||||
if (fd_perf == -1) {
|
if (fd_perf == -1) {
|
||||||
warnx("%s: perf/%s/%s: failed to open counter on cpu%d",
|
warnx("%s: perf/%s/%s: failed to open counter on cpu%d",
|
||||||
__func__, pinfo->device, pinfo->event, cpu);
|
__func__, perf_device, pinfo->event, cpu);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8636,7 +8801,7 @@ int added_perf_counters_init_(struct perf_counter_info *pinfo)
|
|||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
fprintf(stderr, "Add perf/%s/%s cpu%d: %d\n",
|
fprintf(stderr, "Add perf/%s/%s cpu%d: %d\n",
|
||||||
pinfo->device, pinfo->event, cpu, pinfo->fd_perf_per_domain[next_domain]);
|
perf_device, pinfo->event, cpu, pinfo->fd_perf_per_domain[next_domain]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pinfo = pinfo->next;
|
pinfo = pinfo->next;
|
||||||
@ -9071,7 +9236,7 @@ int get_and_dump_counters(void)
|
|||||||
|
|
||||||
void print_version()
|
void print_version()
|
||||||
{
|
{
|
||||||
fprintf(outf, "turbostat version 2024.07.26 - Len Brown <lenb@kernel.org>\n");
|
fprintf(outf, "turbostat version 2024.11.30 - Len Brown <lenb@kernel.org>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#define COMMAND_LINE_SIZE 2048
|
#define COMMAND_LINE_SIZE 2048
|
||||||
@ -9781,7 +9946,7 @@ void cmdline(int argc, char **argv)
|
|||||||
* Parse some options early, because they may make other options invalid,
|
* Parse some options early, because they may make other options invalid,
|
||||||
* like adding the MSR counter with --add and at the same time using --no-msr.
|
* like adding the MSR counter with --add and at the same time using --no-msr.
|
||||||
*/
|
*/
|
||||||
while ((opt = getopt_long_only(argc, argv, "MPn:", long_options, &option_index)) != -1) {
|
while ((opt = getopt_long_only(argc, argv, "+MPn:", long_options, &option_index)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'M':
|
case 'M':
|
||||||
no_msr = 1;
|
no_msr = 1;
|
||||||
@ -9805,6 +9970,12 @@ void cmdline(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
dump_only++;
|
dump_only++;
|
||||||
|
/*
|
||||||
|
* Force the no_perf early to prevent using it as a source.
|
||||||
|
* User asks for raw values, but perf returns them relative
|
||||||
|
* to the opening of the file descriptor.
|
||||||
|
*/
|
||||||
|
no_perf = 1;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
/* --enable specified counter */
|
/* --enable specified counter */
|
||||||
|
Loading…
Reference in New Issue
Block a user