diff --git a/Dockerfile b/Dockerfile index 076eafda..906d37a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,7 @@ FROM fedora:40@sha256:5ce8497aeea599bf6b54ab3979133923d82aaa4f6ca5ced1812611b197c79eb0 as builder +# Dockerfile for Intel PCM sensor server +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2020-2024 Intel Corporation RUN dnf -y install gcc-c++ git findutils make cmake openssl openssl-devel libasan libasan-static COPY . /tmp/pcm diff --git a/README.md b/README.md index 7fdb4c83..1a7ebf5b 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Building PCM Tools Clone PCM repository with submodules: ``` -git clone --recursive https://github.com/intel/pcm.git +git clone --recursive https://github.com/intel/pcm ``` or clone the repository first, and then update submodules with: diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp index 68abab4b..50399d51 100644 --- a/src/cpucounters.cpp +++ b/src/cpucounters.cpp @@ -5598,6 +5598,7 @@ PCM::ErrorCode PCM::programServerUncorePowerMetrics(int mc_profile, int pcu_prof { case SPR: case EMR: + case SRF: PCUCntConf[0] = PCU_MSR_PMON_CTL_EVENT(1); // clock ticks break; default: @@ -5616,6 +5617,7 @@ PCM::ErrorCode PCM::programServerUncorePowerMetrics(int mc_profile, int pcu_prof { case SPR: case EMR: + case SRF: PCUCntConf[1] = PCU_MSR_PMON_CTL_EVENT(0x35); // POWER_STATE_OCCUPANCY.C0 PCUCntConf[2] = PCU_MSR_PMON_CTL_EVENT(0x36); // POWER_STATE_OCCUPANCY.C3 PCUCntConf[3] = PCU_MSR_PMON_CTL_EVENT(0x37); // POWER_STATE_OCCUPANCY.C6 @@ -5634,12 +5636,12 @@ PCM::ErrorCode PCM::programServerUncorePowerMetrics(int mc_profile, int pcu_prof case 3: PCUCntConf[1] = PCU_MSR_PMON_CTL_EVENT(0x04); // Thermal frequency limit cycles: FREQ_MAX_LIMIT_THERMAL_CYCLES PCUCntConf[2] = PCU_MSR_PMON_CTL_EVENT(0x05); // Power frequency limit cycles: FREQ_MAX_POWER_CYCLES - PCUCntConf[3] = PCU_MSR_PMON_CTL_EVENT(0x07); // Clipped frequency limit cycles: FREQ_MAX_CURRENT_CYCLES (not supported on SKX,ICX,SNOWRIDGE,SPR,EMR) + PCUCntConf[3] = PCU_MSR_PMON_CTL_EVENT(0x07); // Clipped frequency limit cycles: FREQ_MAX_CURRENT_CYCLES (not supported on SKX,ICX,SNOWRIDGE,SPR,EMR,SRF) break; case 4: // not supported on SKX, ICX, SNOWRIDGE, SPR, EMR PCUCntConf[1] = PCU_MSR_PMON_CTL_EVENT(0x06); // OS frequency limit cycles: FREQ_MAX_OS_CYCLES PCUCntConf[2] = PCU_MSR_PMON_CTL_EVENT(0x05); // Power frequency limit cycles: FREQ_MAX_POWER_CYCLES - PCUCntConf[3] = PCU_MSR_PMON_CTL_EVENT(0x07); // Clipped frequency limit cycles: FREQ_MAX_CURRENT_CYCLES (not supported on SKX and ICX and SNOWRIDGE) + PCUCntConf[3] = PCU_MSR_PMON_CTL_EVENT(0x07); // Clipped frequency limit cycles: FREQ_MAX_CURRENT_CYCLES (not supported on SKX,ICX,SNOWRIDGE,SPR,EMR,SRF) break; case 5: if(JAKETOWN == cpu_model) @@ -5650,8 +5652,17 @@ PCM::ErrorCode PCM::programServerUncorePowerMetrics(int mc_profile, int pcu_prof { PCUCntConf[1] = PCU_MSR_PMON_CTL_EVENT(0x60) + PCU_MSR_PMON_CTL_EDGE_DET ; // number of frequency transitions PCUCntConf[2] = PCU_MSR_PMON_CTL_EVENT(0x60) ; // cycles spent changing frequency: FREQ_TRANS_CYCLES - } else if (HASWELLX == cpu_model || BDX_DE == cpu_model || BDX == cpu_model || SKX == cpu_model - || ICX == cpu_model || SNOWRIDGE == cpu_model || SPR == cpu_model || EMR == cpu_model) + } else if ( + HASWELLX == cpu_model + || BDX_DE == cpu_model + || BDX == cpu_model + || SKX == cpu_model + || ICX == cpu_model + || SNOWRIDGE == cpu_model + || SPR == cpu_model + || EMR == cpu_model + || SRF == cpu_model + ) { PCUCntConf[1] = PCU_MSR_PMON_CTL_EVENT(0x74) + PCU_MSR_PMON_CTL_EDGE_DET ; // number of frequency transitions PCUCntConf[2] = PCU_MSR_PMON_CTL_EVENT(0x74) ; // cycles spent changing frequency: FREQ_TRANS_CYCLES @@ -5670,11 +5681,21 @@ PCM::ErrorCode PCM::programServerUncorePowerMetrics(int mc_profile, int pcu_prof { PCUCntConf[2] = PCU_MSR_PMON_CTL_EVENT(0x2B) + PCU_MSR_PMON_CTL_EDGE_DET ; // PC2 transitions PCUCntConf[3] = PCU_MSR_PMON_CTL_EVENT(0x2D) + PCU_MSR_PMON_CTL_EDGE_DET ; // PC6 transitions - } else if (HASWELLX == cpu_model || BDX_DE == cpu_model || BDX == cpu_model || SKX == cpu_model || ICX == cpu_model || SNOWRIDGE == cpu_model || SPR == cpu_model || EMR == cpu_model) + } else if ( + HASWELLX == cpu_model + || BDX_DE == cpu_model + || BDX == cpu_model + || SKX == cpu_model + || ICX == cpu_model + || SNOWRIDGE == cpu_model + || SPR == cpu_model + || EMR == cpu_model + || SRF == cpu_model + ) { - PCUCntConf[0] = PCU_MSR_PMON_CTL_EVENT(0x4E) ; // PC1e residenicies (not supported on SKX,ICX,SNOWRIDGE,SPR,EMR) - PCUCntConf[1] = PCU_MSR_PMON_CTL_EVENT(0x4E) + PCU_MSR_PMON_CTL_EDGE_DET ; // PC1 transitions (not supported on SKX,ICX,SNOWRIDGE,SPR,EMR) - PCUCntConf[2] = PCU_MSR_PMON_CTL_EVENT(0x2B) + PCU_MSR_PMON_CTL_EDGE_DET ; // PC2 transitions + PCUCntConf[0] = PCU_MSR_PMON_CTL_EVENT(0x4E) ; // PC1e residenicies (not supported on SKX,ICX,SNOWRIDGE,SPR,EMR,SRF) + PCUCntConf[1] = PCU_MSR_PMON_CTL_EVENT(0x4E) + PCU_MSR_PMON_CTL_EDGE_DET ; // PC1 transitions (not supported on SKX,ICX,SNOWRIDGE,SPR,EMR,SRF) + PCUCntConf[2] = PCU_MSR_PMON_CTL_EVENT(0x2B) + PCU_MSR_PMON_CTL_EDGE_DET ; // PC2e transitions PCUCntConf[3] = PCU_MSR_PMON_CTL_EVENT(0x2D) + PCU_MSR_PMON_CTL_EDGE_DET ; // PC6 transitions } else { @@ -9073,9 +9094,25 @@ void ServerUncorePMUs::program_power_metrics(int mc_profile) case PCM::SNOWRIDGE: case PCM::SPR: case PCM::EMR: + case PCM::SRF: UNC_M_POWER_CKE_CYCLES = 0x47; break; } + unsigned int UNC_M_POWER_CHANNEL_PPD_CYCLES = 0x85; + switch (cpu_model) + { + case PCM::SRF: + UNC_M_POWER_CHANNEL_PPD_CYCLES = 0x88; + break; + } + unsigned int UNC_M_SELF_REFRESH_ENTER_SUCCESS_CYCLES_UMASK = 0; + switch (cpu_model) + { + case PCM::SRF: + UNC_M_SELF_REFRESH_ENTER_SUCCESS_CYCLES_UMASK = 0x01; + break; + } + switch(mc_profile) { case 0: // POWER_CKE_CYCLES.RANK0 and POWER_CKE_CYCLES.RANK1 @@ -9103,9 +9140,9 @@ void ServerUncorePMUs::program_power_metrics(int mc_profile) MCCntConfig[3] = MC_CH_PCI_PMON_CTL_EVENT(UNC_M_POWER_CKE_CYCLES) + MC_CH_PCI_PMON_CTL_UMASK(0x80) + MC_CH_PCI_PMON_CTL_THRESH(1) + MC_CH_PCI_PMON_CTL_EDGE_DET; break; case 4: // POWER_SELF_REFRESH - MCCntConfig[0] = MC_CH_PCI_PMON_CTL_EVENT(0x43); - MCCntConfig[1] = MC_CH_PCI_PMON_CTL_EVENT(0x43) + MC_CH_PCI_PMON_CTL_THRESH(1) + MC_CH_PCI_PMON_CTL_EDGE_DET; - MCCntConfig[2] = MC_CH_PCI_PMON_CTL_EVENT(0x85); + MCCntConfig[0] = MC_CH_PCI_PMON_CTL_EVENT(0x43) + MC_CH_PCI_PMON_CTL_UMASK(UNC_M_SELF_REFRESH_ENTER_SUCCESS_CYCLES_UMASK); + MCCntConfig[1] = MC_CH_PCI_PMON_CTL_EVENT(0x43) + MC_CH_PCI_PMON_CTL_UMASK(UNC_M_SELF_REFRESH_ENTER_SUCCESS_CYCLES_UMASK) + MC_CH_PCI_PMON_CTL_THRESH(1) + MC_CH_PCI_PMON_CTL_EDGE_DET; + MCCntConfig[2] = MC_CH_PCI_PMON_CTL_EVENT(UNC_M_POWER_CHANNEL_PPD_CYCLES); break; } diff --git a/src/lspci.h b/src/lspci.h index 0cf09134..0017aac6 100644 --- a/src/lspci.h +++ b/src/lspci.h @@ -17,12 +17,14 @@ " https://raw.githubusercontent.com/pciutils/pciids/master/pci.ids and" \ " copy it to the current directory." #else +// different distributions put it in different places #define PCI_IDS_PATH "/usr/share/hwdata/pci.ids" #define PCI_IDS_NOT_FOUND "/usr/share/hwdata/pci.ids file is not available." \ " Ensure that the \"hwdata\" package is properly installed or download" \ " https://raw.githubusercontent.com/pciutils/pciids/master/pci.ids and" \ " copy it to the current directory." #endif +#define PCI_IDS_PATH2 "/usr/share/misc/pci.ids" namespace pcm { @@ -448,6 +450,12 @@ void load_PCIDB(PCIDB & pciDB) if (!in.is_open()) { #ifndef _MSC_VER + // On Unix, try PCI_IDS_PATH2 + in.open(PCI_IDS_PATH2); + } + + if (!in.is_open()) + { // On Unix, try the current directory if the default path failed in.open("pci.ids"); } diff --git a/src/pcm-power.cpp b/src/pcm-power.cpp index 08a015d8..86923c26 100644 --- a/src/pcm-power.cpp +++ b/src/pcm-power.cpp @@ -474,13 +474,26 @@ int mainThrows(int argc, char * argv[]) printHeader(true); cout << "; Thermal freq limit cycles: " << getNormalizedPCUCounter(u, 1, BeforeState[socket], AfterState[socket]) * 100. << " %" << "; Power freq limit cycles:" << getNormalizedPCUCounter(u, 2, BeforeState[socket], AfterState[socket]) * 100. << " %"; - if(cpu_model != PCM::SKX && cpu_model != PCM::ICX && cpu_model != PCM::SNOWRIDGE && cpu_model != PCM::SPR && cpu_model != PCM::EMR) + if( + cpu_model != PCM::SKX + && cpu_model != PCM::ICX + && cpu_model != PCM::SNOWRIDGE + && cpu_model != PCM::SPR + && cpu_model != PCM::EMR + && cpu_model != PCM::SRF + ) cout << "; Clipped freq limit cycles:" << getNormalizedPCUCounter(u, 3, BeforeState[socket], AfterState[socket]) * 100. << " %"; cout << "\n"; break; case 4: - if (cpu_model == PCM::SKX || cpu_model == PCM::ICX || cpu_model == PCM::SNOWRIDGE || cpu_model == PCM::SPR || cpu_model == PCM::EMR) + if ( cpu_model == PCM::SKX + || cpu_model == PCM::ICX + || cpu_model == PCM::SNOWRIDGE + || cpu_model == PCM::SPR + || cpu_model == PCM::EMR + || cpu_model == PCM::SRF + ) { cout << "This PCU profile is not supported on your processor\n"; break; @@ -517,6 +530,7 @@ int mainThrows(int argc, char * argv[]) case PCM::SNOWRIDGE: case PCM::SPR: case PCM::EMR: + case PCM::SRF: cout << "; PC2 residency: " << getPackageCStateResidency(2, BeforeState[socket], AfterState[socket]) * 100. << " %"; cout << "; PC2 transitions: " << getUncoreCounter(PCM::PCU_PMU_ID, u, 2, BeforeState[socket], AfterState[socket]) << " "; cout << "; PC3 residency: " << getPackageCStateResidency(3, BeforeState[socket], AfterState[socket]) * 100. << " %";