Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
9fb51a2
Move lspci.h to lspci.cpp
ogbrugge-work Apr 14, 2025
4f27c76
Temporarily move lspci.h to lspci.h.tmp to be able to merge the split…
ogbrugge-work Apr 14, 2025
9f968bd
Merge branch 'split-lspci.h' into add_pci_counters_to_pcm-sensor-serv…
ogbrugge-work Apr 14, 2025
3bc7216
Move lspci.h.tmp back to lspci.h
ogbrugge-work Apr 14, 2025
a4e757e
Move pcm-iio.cpp to pcm-iio-pmu.cpp
ogbrugge-work Apr 14, 2025
3ccb78f
Temporarily move pcm-iio.cpp to pcm-iio.cpp.tmp to be able to merge s…
ogbrugge-work Apr 14, 2025
f29f301
Merge branch 'split-pcm-iio.cpp' into add_pci_counters_to_pcm-sensor-…
ogbrugge-work Apr 14, 2025
dcb9e38
Move pcm-iio.cpp.tmp back to pcm-iio.cpp
ogbrugge-work Apr 14, 2025
4477736
Move pcm-iio-pmu.cpp to pcm-iio-pmu.h
ogbrugge-work Apr 14, 2025
a370bec
Temporarily move pcm-iio-pmu.cpp to pcm-iio-pmu.cpp.tmp
ogbrugge-work Apr 14, 2025
fbeb274
Merge branch 'split-pcm-iio-pmu.cpp' into add_pci_counters_to_pcm-sen…
ogbrugge-work Apr 14, 2025
dbd8ad4
Move pcm-iio-pmu.tmp back to pcm-iio-pmu.cpp
ogbrugge-work Apr 14, 2025
191abb2
Deduplicate to reorganize the code but keep blame history
ogbrugge-work Apr 14, 2025
7d41d55
Fix some typos and add some whitespace
ogbrugge-work Apr 14, 2025
6352553
Cosmetic changes
Apr 15, 2025
001ffe1
Fix issue on GNR with skipping IAX
Apr 15, 2025
73b4207
Add isIntelDeviceById() wrapper to pci structure
Apr 15, 2025
bce0fbb
more debug output
rdementi Apr 15, 2025
400f490
update windows documentation
rdementi Apr 15, 2025
44d42c1
perfmon DB install in rpm
rdementi Apr 12, 2025
889549d
fully implement getOCREventNr for Atom/E-cores to support the second …
rdementi Apr 15, 2025
4bc899a
refactor
rdementi Apr 15, 2025
c4d5882
refactor (II)
rdementi Apr 15, 2025
2fa165c
implement a warning
rdementi Apr 15, 2025
789854b
pcm-raw: support second OCR counter on Atom/E-core
rdementi Apr 15, 2025
fe41f0d
use appropriate return code (AddEventStatus::FailedTooManyEvents)
rdementi Apr 15, 2025
e4dfbfb
report adjusted max size for the OCR event
rdementi Apr 15, 2025
5f1557d
upgrade runners to ubuntu-24.04
rdementi Apr 16, 2025
9e68351
address cppcheck error
rdementi Apr 16, 2025
3cad50f
address cppcheck warnings
rdementi Apr 16, 2025
a2449a6
Convert commented out debug output to instead use the DBG macro
ogbrugge-work Apr 16, 2025
a545f63
Merge pull request #747 from intel-innersource/add_pci_counters_to_pc…
rdementi Apr 16, 2025
de8f9b0
fix OCR events on GNR-D
rdementi Apr 16, 2025
e2ccfdc
update windows documentation
rdementi Apr 17, 2025
ec6d83b
Merge remote-tracking branch 'opcm-github/master'
rdementi Apr 21, 2025
f5012b8
update docs
rdementi Apr 22, 2025
856f21e
Merge pull request #769 from intel-innersource/rdementi-2025-04-22
rdementi Apr 22, 2025
d93cd52
update perfmon
rdementi Apr 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/PCM_RAW_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,12 @@ Sample csv output (date,time,event_name,milliseconds_between_samples,TSC_cycles_
```
The unit can be logical core, memory channel, CHA, etc, depending on the event type.


Show events available for the processor on the system:
```
pcm-raw -?
```

--------------------------------------------------------------------------------
Low-level access to Intel PMT telemetry data
--------------------------------------------------------------------------------
Expand Down
9 changes: 5 additions & 4 deletions doc/WINDOWS_HOWTO.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ _For support of systems with more than _**_64_**_ logical cores you need to comp

## Command-line utility

1. Follow [Compile the windows MSR driver](#compile-the-windows-msr-driver) to compile the windows MSR driver (msr.sys). For Windows 7 and later versions you have to sign the msr.sys driver additionally ([http://msdn.microsoft.com/en-us/library/ms537361(VS.85).aspx](http://msdn.microsoft.com/en-us/library/ms537361(VS.85).aspx)). To enable loading test signed drivers on the system: in administrator cmd console run `bcdedit /set testsigning on` and reboot.
1. Follow [Compile the Windows MSR driver](#compile-the-windows-msr-driver) to compile the Windows MSR driver (msr.sys). For Windows 7 and later versions you have to sign the msr.sys driver additionally ([http://msdn.microsoft.com/en-us/library/ms537361(VS.85).aspx](http://msdn.microsoft.com/en-us/library/ms537361(VS.85).aspx)). To enable loading test-signed drivers on the system: in administrator cmd console run `bcdedit /set testsigning on` and reboot.

2. Build the *pcm.exe* utility:
```
Expand All @@ -17,7 +17,7 @@ _For support of systems with more than _**_64_**_ logical cores you need to comp
4. As Administrator copy the msr.sys driver and pcm.exe into the PCM directory
5. Run pcm.exe utility from the PCM directory as Administrator

For Windows 7+ and Windows Server 2008+ R2 the PCM utilities need to be run as administrator:
For Windows 7+ and Windows Server 2008+ R2 the PCM utilities need to be run as Administrator:

Alternatively you can achieve the same using the “Properties” Windows menu of the executable (“Privilege level” setting in the “Compatibility” tab): Right mouse click -> Properties -> Compatibility -> Privilege level -> Set “Run this program as an administrator”.

Expand Down Expand Up @@ -47,13 +47,14 @@ Unhandled Exception: System.NotSupportedException: This method implicitly uses C

8. Start perfmon and find new PCM\* counters

If you do not want or cannot compile the msr.sys driver you might use a third-party open source WinRing0 driver instead. Instructions:
If you do not want or cannot compile the msr.sys driver you might use a third-party open source WinRing0 driver instead (experimental only, for testing environments only).
Instructions:

1. Download the free RealTemp utility package from [http://www.techpowerup.com/realtemp/](http://www.techpowerup.com/realtemp/) or any other free utility that uses the open-source WinRing0 driver (like OpenHardwareMonitor [http://code.google.com/p/open-hardware-monitor/downloads/list](http://code.google.com/p/open-hardware-monitor/downloads/list)).
2. Copy WinRing0.dll, WinRing0.sys, WinRing0x64.dll, WinRing0x64.sys files from there into the PCM.exe binary location, into the PCM-Service.exe location and into c:\windows\system32
3. Run the PCM.exe tool and/or go to step 6 (perfmon utility).

## Compile the windows MSR driver
## Compile the Windows MSR driver

1. Download Visual Studio ([Visual Studio download](https://visualstudio.microsoft.com/downloads/)).
When you install Visual Studio, also install related packages:
Expand Down
2 changes: 1 addition & 1 deletion perfmon
10 changes: 5 additions & 5 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ set(PROJECT_NAMES pcm pcm-numa pcm-latency pcm-power pcm-msr pcm-memory pcm-tsx

set(MINIMUM_OPENSSL_VERSION 1.1.1)

file(GLOB COMMON_SOURCES pcm-accel-common.cpp msr.cpp cpucounters.cpp pci.cpp mmio.cpp tpmi.cpp pmt.cpp bw.cpp utils.cpp topology.cpp debug.cpp threadpool.cpp uncore_pmu_discovery.cpp ${PCM_PUGIXML_CPP})
file(GLOB COMMON_SOURCES pcm-accel-common.cpp msr.cpp cpucounters.cpp pci.cpp mmio.cpp tpmi.cpp pmt.cpp bw.cpp utils.cpp topology.cpp debug.cpp threadpool.cpp uncore_pmu_discovery.cpp pcm-iio-pmu.cpp lspci.cpp ${PCM_PUGIXML_CPP})

if (APPLE)
file(GLOB UNUX_SOURCES dashboard.cpp)
file(GLOB UNIX_SOURCES dashboard.cpp)
else()
file(GLOB UNUX_SOURCES dashboard.cpp resctrl.cpp)
file(GLOB UNIX_SOURCES dashboard.cpp resctrl.cpp)
endif()

if (LINUX)
Expand Down Expand Up @@ -49,11 +49,11 @@ if(UNIX) # LINUX, FREE_BSD, APPLE
list(APPEND PROJECT_NAMES pcm-sensor)

# libpcm.a
add_library(PCM_STATIC STATIC ${COMMON_SOURCES} ${UNUX_SOURCES})
add_library(PCM_STATIC STATIC ${COMMON_SOURCES} ${UNIX_SOURCES})
set_target_properties(PCM_STATIC PROPERTIES OUTPUT_NAME pcm)

# libpcm.a with -DPCM_SILENT for Release*
add_library(PCM_STATIC_SILENT STATIC ${COMMON_SOURCES} ${UNUX_SOURCES})
add_library(PCM_STATIC_SILENT STATIC ${COMMON_SOURCES} ${UNIX_SOURCES})
target_compile_definitions(PCM_STATIC_SILENT PRIVATE
$<$<CONFIG:Release>:PCM_SILENT>
$<$<CONFIG:MinSizeRel>:PCM_SILENT>
Expand Down
22 changes: 20 additions & 2 deletions src/cpucounters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2652,7 +2652,7 @@ void PCM::initUncorePMUsDirect()
std::vector<std::pair<uint32, uint32> > socket2QATbus;
std::map<int, int> rootbusMap;

//Enumurate IDX devices by PCIe bus scan
//Enumerate IDX devices by PCIe bus scan
initSocket2Bus(socket2IAAbus, SPR_IDX_IAA_REGISTER_DEV_ADDR, SPR_IDX_IAA_REGISTER_FUNC_ADDR, IAA_DEV_IDS, (uint32)sizeof(IAA_DEV_IDS) / sizeof(IAA_DEV_IDS[0]));
initSocket2Bus(socket2DSAbus, SPR_IDX_DSA_REGISTER_DEV_ADDR, SPR_IDX_DSA_REGISTER_FUNC_ADDR, DSA_DEV_IDS, (uint32)sizeof(DSA_DEV_IDS) / sizeof(DSA_DEV_IDS[0]));
initSocket2Bus(socket2QATbus, SPR_IDX_QAT_REGISTER_DEV_ADDR, SPR_IDX_QAT_REGISTER_FUNC_ADDR, QAT_DEV_IDS, (uint32)sizeof(QAT_DEV_IDS) / sizeof(QAT_DEV_IDS[0]));
Expand Down Expand Up @@ -4192,10 +4192,18 @@ PCM::ErrorCode PCM::programCoreCounters(const int i /* core */,

if (EXT_CUSTOM_CORE_EVENTS == mode_ && pExtDesc)
{
if (pExtDesc->OffcoreResponseMsrValue[0]) // still need to do also if perf API is used due to a bug in perf
if (pExtDesc->OffcoreResponseMsrValue[0]) // still need to do also if perf API is used due to a bug in perf in some kernels
{
DBG(3, "programming offcore response 0x", std::hex , pExtDesc->OffcoreResponseMsrValue[0] ,
" into MSR 0x" , MSR_OFFCORE_RSP0 , std::dec , " for core ", i);
MSR[i]->write(MSR_OFFCORE_RSP0, pExtDesc->OffcoreResponseMsrValue[0]);
}
if (pExtDesc->OffcoreResponseMsrValue[1])
{
DBG(3, "programming offcore response 0x", std::hex , pExtDesc->OffcoreResponseMsrValue[1] ,
" into MSR 0x" , MSR_OFFCORE_RSP1 , std::dec , " for core ", i);
MSR[i]->write(MSR_OFFCORE_RSP1, pExtDesc->OffcoreResponseMsrValue[1]);
}

if (pExtDesc->LoadLatencyMsrValue != ExtendedCustomCoreEventDescription::invalidMsrValue())
{
Expand Down Expand Up @@ -4268,9 +4276,19 @@ PCM::ErrorCode PCM::programCoreCounters(const int i /* core */,
if (pExtDesc != nullptr)
{
if (event_select_reg.fields.event_select == getOCREventNr(0, i).first && event_select_reg.fields.umask == getOCREventNr(0, i).second)
{
DBG(3, "writing offcore response 0x", std::hex , pExtDesc->OffcoreResponseMsrValue[0] ,
" into perf config1 for core ", std::dec , i, std::hex ," event 0x", event_select_reg.fields.event_select, " umask 0x", event_select_reg.fields.umask ,
" on counter ", std::dec , j);
e.config1 = pExtDesc->OffcoreResponseMsrValue[0];
}
if (event_select_reg.fields.event_select == getOCREventNr(1, i).first && event_select_reg.fields.umask == getOCREventNr(1, i).second)
{
DBG(3, "writing offcore response 0x", std::hex , pExtDesc->OffcoreResponseMsrValue[1] ,
" into perf config1 for core ", std::dec , i, std::hex , " event 0x", event_select_reg.fields.event_select, " umask 0x", event_select_reg.fields.umask ,
" on counter ", std::dec , j);
e.config1 = pExtDesc->OffcoreResponseMsrValue[1];
}

if (event_select_reg.fields.event_select == LOAD_LATENCY_EVTNR && event_select_reg.fields.umask == LOAD_LATENCY_UMASK)
{
Expand Down
20 changes: 19 additions & 1 deletion src/cpucounters.h
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,7 @@ class PCM_API PCM
std::pair<unsigned, unsigned> getOCREventNr(const int event, const unsigned coreID) const
{
assert (coreID < topology.size());
const auto eCoreOCREvent = std::make_pair(OFFCORE_RESPONSE_0_EVTNR, event + 1);
if (hybrid)
{
switch (cpu_family_model)
Expand All @@ -1677,7 +1678,7 @@ class PCM_API PCM
case ARL:
if (topology[coreID].core_type == TopologyEntry::Atom)
{
return std::make_pair(OFFCORE_RESPONSE_0_EVTNR, event + 1);
return eCoreOCREvent;
}
break;
}
Expand All @@ -1688,13 +1689,30 @@ class PCM_API PCM
case SPR:
case EMR:
case GNR:
case GNR_D:
case ADL: // ADL big core (GLC)
case RPL:
case MTL:
case LNL:
case ARL:
useGLCOCREvent = true;
break;

case ATOM:
case ATOM_2:
case CENTERTON:
case BAYTRAIL:
case AVOTON:
case CHERRYTRAIL:
case APOLLO_LAKE:
case GEMINI_LAKE:
case DENVERTON:
case SNOWRIDGE:
case ELKHART_LAKE:
case JASPER_LAKE:
case SRF:
case GRR:
return eCoreOCREvent;
}
switch (event)
{
Expand Down
167 changes: 167 additions & 0 deletions src/lspci.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
#include "lspci.h"

namespace pcm {

const ccr_config ccr::skx_ccrs(44, 0xFFULL);
const ccr_config ccr::icx_ccrs(48, 0xFFFULL);

bool operator<(const iio_stack& lh, const iio_stack& rh)
{
return lh.iio_unit_id < rh.iio_unit_id;
}

bool operator<(const bdf &l, const bdf &r) {
if (l.domainno < r.domainno)
return true;
if (l.domainno > r.domainno)
return false;
if (l.busno < r.busno)
return true;
if (l.busno > r.busno)
return false;
if (l.devno < r.devno)
return true;
if (l.devno > r.devno)
return false;
if (l.funcno < r.funcno)
return true;
if (l.funcno > r.funcno)
return false;

return false; // bdf == bdf
}

void probe_capability_pci_express(struct pci *p, uint32_t cap_ptr)
{
struct cap {
union {
struct {
uint8_t id;
union {
uint8_t next;
uint8_t cap_ptr;
};
uint16_t junk;
};
uint32 dw0;
};
} cap;
uint32 value;
PciHandleType h(0, p->bdf.busno, p->bdf.devno, p->bdf.funcno);
h.read32(cap_ptr, &value); //Capability pointer
cap.dw0 = value;
if (cap.id != 0x10 && cap.next != 0x00) {
probe_capability_pci_express(p, cap.cap_ptr);
} else {
if (cap.id == 0x10) { // We're in PCI express capability structure
h.read32(cap_ptr+0x10, &value);
p->link_info = value;
} else { /*Finish recursive searching but cannot find PCI express capability structure*/ }
}
}

bool probe_pci(struct pci *p)
{
uint32 value;
p->exist = false;
struct bdf *bdf = &p->bdf;
if (PciHandleType::exists(bdf->domainno, bdf->busno, bdf->devno, bdf->funcno)) {
PciHandleType h(bdf->domainno, bdf->busno, bdf->devno, bdf->funcno);
// VID:DID
h.read32(0x0, &value);
// Invalid VID::DID
if (value != (std::numeric_limits<unsigned int>::max)()) {
p->offset_0 = value;
h.read32(0xc, &value);
p->header_type = (value >> 16) & 0x7f;
if (p->header_type == 0) {
// Status register
h.read32(0x4, &value);
// Capability list == true
if (value & 0x100000) {
// Capability pointer
h.read32(0x34, &value);
probe_capability_pci_express(p, value);
}
} else if (p->header_type == 1) {
h.read32(0x18, &value);
p->offset_18 = value;
}
p->exist = true;
}
}

return p->exist;
}

void print_pci(struct pci p, const PCIDB & pciDB)
{
printf("Parent bridge info:");
printf("%x:%x.%d [%04x:%04x] %s %s %d P:%x S:%x S:%x ",
p.bdf.busno, p.bdf.devno, p.bdf.funcno,
p.vendor_id, p.device_id,
(pciDB.first.count(p.vendor_id) > 0)?pciDB.first.at(p.vendor_id).c_str():"unknown vendor",
(pciDB.second.count(p.vendor_id) > 0 && pciDB.second.at(p.vendor_id).count(p.device_id) > 0)?pciDB.second.at(p.vendor_id).at(p.device_id).c_str():"unknown device",
p.header_type,
p.primary_bus_number, p.secondary_bus_number, p.subordinate_bus_number);
printf("Device info:");
printf("%x:%x.%d [%04x:%04x] %s %s %d Gen%d x%d\n",
p.bdf.busno, p.bdf.devno, p.bdf.funcno,
p.vendor_id, p.device_id,
(pciDB.first.count(p.vendor_id) > 0)?pciDB.first.at(p.vendor_id).c_str():"unknown vendor",
(pciDB.second.count(p.vendor_id) > 0 && pciDB.second.at(p.vendor_id).count(p.device_id) > 0)?pciDB.second.at(p.vendor_id).at(p.device_id).c_str():"unknown device",
p.header_type,
p.link_speed, p.link_width);
}

void load_PCIDB(PCIDB & pciDB)
{
std::ifstream in(PCI_IDS_PATH);
std::string line, item;

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");
}

if (!in.is_open())
{
#endif
std::cerr << PCI_IDS_NOT_FOUND << "\n";
return;
}

int vendorID = -1;

while (std::getline(in, line)) {
// Ignore any line starting with #
if (line.size() == 0 || line[0] == '#')
continue;

if (line[0] == '\t' && line[1] == '\t')
{
// subvendor subdevice subsystem_name
continue;
}
if (line[0] == '\t')
{
int deviceID = stoi(line.substr(1,4),0,16);
//std::cout << vendorID << ";" << vendorName << ";" << deviceID << ";" << line.substr(7) << "\n";
pciDB.second[vendorID][deviceID] = line.substr(7);
continue;
}
// vendor
vendorID = stoi(line.substr(0,4),0,16);
pciDB.first[vendorID] = line.substr(6);
}
}

} // Namespace pcm
Loading
Loading