From 480ba2ae5029b22bf224dca64ae871eed6483079 Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 4 Apr 2025 08:58:49 +0200 Subject: [PATCH 01/10] implement pcicfg device availability check for msr.sys Change-Id: Ic1bd010ff9ed5a21ad1d813aa84b3d964754c030 --- src/pci.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pci.cpp b/src/pci.cpp index 078b6b7f..5b01dd34 100644 --- a/src/pci.cpp +++ b/src/pci.cpp @@ -67,10 +67,11 @@ bool PciHandle::exists(uint32 groupnr_, uint32 bus_, uint32 device_, uint32 func HANDLE tempHandle = openMSRDriver(); if (tempHandle != INVALID_HANDLE_VALUE) { - // TODO: check device availability - CloseHandle(tempHandle); - return true; + + PciHandle tempHandle(groupnr_, bus_, device_, function_); + uint32 value = 0; + return tempHandle.read32(0, &value) == sizeof(uint32); } if (groupnr_ != 0) From ab69d39d453645fad0fd10e5c3578ad1f1dc73e6 Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 4 Apr 2025 09:23:41 +0200 Subject: [PATCH 02/10] rename Granite Rapids-SP -> Granite Rapids Change-Id: I416c01cc64098345fbad1935c160bc19967ba28c --- src/cpucounters.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp index d0bbabdc..361e5289 100644 --- a/src/cpucounters.cpp +++ b/src/cpucounters.cpp @@ -5032,7 +5032,7 @@ const char * PCM::getUArchCodename(const int32 cpu_family_model_param) const case EMR: return "Emerald Rapids-SP"; case GNR: - return "Granite Rapids-SP"; + return "Granite Rapids"; case GNR_D: return "Granite Rapids-D"; case GRR: From e56d67231ecc9e8e2d34873f0deda69f7452293f Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 4 Apr 2025 10:04:48 +0200 Subject: [PATCH 03/10] add IDX membar check quirk for Windows Change-Id: I5e75ead0efe39d0c5277590598dba2bda500bf3e --- src/cpucounters.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp index 361e5289..bba46f31 100644 --- a/src/cpucounters.cpp +++ b/src/cpucounters.cpp @@ -1858,8 +1858,15 @@ bool getIDXDevBAR(std::vector > & socket2bus, uint32 d PciHandleType IDXHandle(s2bus.first, s2bus.second, dev, func); IDXHandle.read64(SPR_IDX_ACCEL_BAR0_OFFSET, &memBar); IDXHandle.read32(SPR_IDX_ACCEL_PCICMD_OFFSET, &pciCmd); - IDXHandle.read32(SPR_IDX_ACCEL_PMCSR_OFFSET, &pmCsr); - if (memBar == 0x0 || (pciCmd & 0x02) == 0x0) //Check BAR0 is valid or NOT. + IDXHandle.read32(SPR_IDX_ACCEL_PMCSR_OFFSET, &pmCsr); + DBG(1, "IDX - BAR0 of B:0x", std::hex, s2bus.second, ",D:0x", std::hex, dev, ",F:0x", std::hex, func, " is (memBar=0x", + std::hex, memBar, ", pciCmd=0x", std::hex, pciCmd, ")", std::dec); + if (memBar == 0x0 +#ifndef _MSC_VER + // on Windows the driver does not set the bit: do not check + || (pciCmd & 0x02) == 0x0 +#endif + ) //Check BAR0 is valid or NOT. { std::cerr << "Warning: IDX - BAR0 of B:0x" << std::hex << s2bus.second << ",D:0x" << std::hex << dev << ",F:0x" << std::hex << func << " is invalid(memBar=0x" << std::hex << memBar << ", pciCmd=0x" << std::hex << pciCmd <<"), skipped." << std::dec << std::endl; From 94d94db213d34c807a3abb52abffc805b84d8b41 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Fri, 11 Apr 2025 08:23:49 +0200 Subject: [PATCH 04/10] install perfmon files --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f8f3ebf..df7e3730 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,6 +138,8 @@ if(UNIX) # APPLE, LINUX, FREE_BSD message(STATUS "CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") message(STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + install(DIRECTORY "perfmon" DESTINATION ${CMAKE_INSTALL_DATADIR}/pcm) + endif(UNIX) if(PCM_FUZZ) From 059c469614468545d12efd27721652f13959e2cc Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Fri, 11 Apr 2025 08:53:40 +0200 Subject: [PATCH 05/10] pcm-raw: lookup event files from the install directory --- src/pcm-raw.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/pcm-raw.cpp b/src/pcm-raw.cpp index 743f8b02..72129721 100644 --- a/src/pcm-raw.cpp +++ b/src/pcm-raw.cpp @@ -217,16 +217,24 @@ bool initPMUEventMap() inited = true; const auto mapfile = "mapfile.csv"; const auto mapfilePath = eventFileLocationPrefix + "/" + mapfile; + const auto mapfilePathAlt = getInstallPathPrefix() + "perfmon/" + mapfile; std::ifstream in(mapfilePath); std::string line, item; if (!in.is_open()) { - cerr << "ERROR: File " << mapfilePath << " can't be open. \n"; - cerr << " Use -ep /perfmon option if you cloned PCM source repository recursively with submodules,\n"; - cerr << " or run 'git clone https://github.com/intel/perfmon' to download the perfmon event repository and use -ep option\n"; - cerr << " or download the file from https://raw.githubusercontent.com/intel/perfmon/main/" << mapfile << " \n"; - return false; + in.open(mapfilePathAlt); + if (!in.is_open()) + { + cerr << "ERROR: File " << mapfilePath << " or " << mapfilePathAlt << " can't be open. \n"; + #ifndef _MSC_VER + cerr << " run 'make install' in the pcm build directory if you cloned PCM source repository recursively with submodules, or\n"; + #endif + cerr << " use -ep /perfmon option if you cloned PCM source repository recursively with submodules,\n"; + cerr << " or run 'git clone https://github.com/intel/perfmon' to download the perfmon event repository and use -ep option\n"; + cerr << " or download the file from https://raw.githubusercontent.com/intel/perfmon/main/" << mapfile << " \n"; + return false; + } } int32 FMSPos = -1; int32 FilenamePos = -1; @@ -300,6 +308,7 @@ bool initPMUEventMap() { const std::string path1 = eventFileLocationPrefix + evfile.second; const std::string path2 = eventFileLocationPrefix + evfile.second.substr(evfile.second.rfind('/')); + const std::string path3 = getInstallPathPrefix() + "perfmon" + evfile.second; if (std::ifstream(path1).good()) { @@ -309,9 +318,13 @@ bool initPMUEventMap() { path = path2; } + else if (std::ifstream(path3).good()) + { + path = path3; + } else { - std::cerr << "ERROR: Can't open event file at location " << path1 << " or " << path2 << "\n"; + std::cerr << "ERROR: Can't open event file at location " << path1 << " or " << path2 << " or " << path3 << "\n"; printError(); return false; } From fd2bfd5f5a2c877424c3c6a11b75a3ef93ee5180 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Fri, 11 Apr 2025 10:07:08 +0200 Subject: [PATCH 06/10] convert to DBG output where needed --- src/pcm-raw.cpp | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/src/pcm-raw.cpp b/src/pcm-raw.cpp index 72129721..5f881465 100644 --- a/src/pcm-raw.cpp +++ b/src/pcm-raw.cpp @@ -461,8 +461,8 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven cerr << "ERROR: PMU Event map can not be initialized\n"; return AddEventStatus::Failed; } - // cerr << "Parsing event " << fullEventStr << "\n"; - // cerr << "size: " << fullEventStr.size() << "\n"; + DBG(2, "Parsing event " , fullEventStr); + DBG(2, "size: " , fullEventStr.size()); while (fullEventStr.empty() == false && fullEventStr.back() == ' ') { fullEventStr.resize(fullEventStr.size() - 1); // remove trailing spaces @@ -482,7 +482,7 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven const auto eventStr = EventTokens[0]; - // cerr << "size: " << eventStr.size() << "\n"; + DBG(2, "size: " , eventStr.size()); PCM::RawEventConfig config = { {0,0,0,0,0}, "" }; std::string pmuName; @@ -636,7 +636,7 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven { std::string unit = EventMap::getField(eventStr, "Unit"); lowerCase(unit); - // std::cout << eventStr << " is uncore event for unit " << unit << "\n"; + DBG(2, eventStr , " is uncore event for unit " , unit); pmuName = (pmuNameMap.find(unit) == pmuNameMap.end()) ? unit : pmuNameMap[unit]; } @@ -644,9 +644,9 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven if (1) { - // cerr << "pmuName: " << pmuName << " full event "<< fullEventStr << " \n"; + DBG(2, "pmuName: " , pmuName , " full event ", fullEventStr); std::string CounterStr = EventMap::getField(eventStr, "Counter"); - // cout << "Counter: " << CounterStr << "\n"; + DBG(2, "Counter: " , CounterStr); int fixedCounter = -1; fixed = (pcm_sscanf(CounterStr) >> s_expect("Fixed counter ") >> fixedCounter) ? true : false; if (!fixed){ @@ -720,15 +720,15 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven }; for (const auto & registerKeyValue : PMUDeclObj) { - // cout << "Setting " << registerKeyValue.key << " : " << registerKeyValue.value << "\n"; + DBG(2, "Setting " , registerKeyValue.key , " : " , registerKeyValue.value); simdjson::dom::object fieldDescriptionObj = registerKeyValue.value; - // cout << " config: " << uint64_t(fieldDescriptionObj["Config"]) << "\n"; - // cout << " Position: " << uint64_t(fieldDescriptionObj["Position"]) << "\n"; + DBG(2, " config: " , uint64_t(fieldDescriptionObj["Config"])); + DBG(2, " Position: " , uint64_t(fieldDescriptionObj["Position"])); const std::string fieldNameStr{ registerKeyValue.key.begin(), registerKeyValue.key.end() }; if (fieldNameStr == "MSRIndex") { string fieldValueStr = EventMap::getField(eventStr, fieldNameStr); - // cout << "MSR field " << fieldNameStr << " value is " << fieldValueStr << " (" << read_number(fieldValueStr.c_str()) << ") offcore=" << offcore << "\n"; + DBG(2, "MSR field " , fieldNameStr , " value is " , fieldValueStr , " (" , read_number(fieldValueStr.c_str()) , ") offcore=" , offcore);; lowerCase(fieldValueStr); if (fieldValueStr == "0" || fieldValueStr == "0x00") { @@ -745,7 +745,7 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven } MSRIndexStr = MSRIndexes[offcoreEventIndex]; } - // cout << " MSR field " << fieldNameStr << " value is " << MSRIndexStr << " (" << read_number(MSRIndexStr.c_str()) << ") offcore=" << offcore << "\n"; + DBG(2, " MSR field " , fieldNameStr , " value is " , MSRIndexStr , " (" , read_number(MSRIndexStr.c_str()) , ") offcore=" , offcore); MSRObject = registerKeyValue.value[MSRIndexStr]; const string msrValueStr = EventMap::getField(eventStr, "MSRValue"); setMSRValue(msrValueStr); @@ -758,7 +758,7 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven } if (!EventMap::isField(eventStr, fieldNameStr)) { - // cerr << fieldNameStr << " not found\n"; + DBG(2, fieldNameStr , " not found"); if (fieldDescriptionObj["DefaultValue"].error() == NO_SUCH_FIELD) { cerr << "ERROR: DefaultValue not provided for field \"" << fieldNameStr << "\" in " << path << "\n"; @@ -786,7 +786,7 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven } fieldValueStr = offcoreCodes[offcoreEventIndex]; } - // cout << " field " << fieldNameStr << " value is " << fieldValueStr << " (" << read_number(fieldValueStr.c_str()) << ") offcore=" << offcore << "\n"; + DBG(2, " field " , fieldNameStr , " value is " , fieldValueStr , " (" , read_number(fieldValueStr.c_str()) , ") offcore=" , offcore); setConfig(config, fieldDescriptionObj, read_number(fieldValueStr.c_str()), position); } } @@ -934,13 +934,6 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven } } - /* - for (const auto& keyValue : eventObj) - { - cout << keyValue.key << " : " << keyValue.value << "\n"; - } - */ - printEvent(pmuName, fixed, config); return AddEventStatus::OK; @@ -2749,9 +2742,6 @@ int mainThrows(int argc, char * argv[]) } m->globalUnfreezeUncoreCounters(); - //cout << "Time elapsed: " << dec << fixed << AfterTime - BeforeTime << " ms\n"; - //cout << "Called sleep function for " << dec << fixed << delay_ms << " ms\n"; - printAll(group, m, SysBeforeState, SysAfterState, BeforeState, AfterState, BeforeUncoreState, AfterUncoreState, BeforeSocketState, AfterSocketState, PMUConfigs, groupNr == nGroups); if (nGroups == 1) { From ce64f6676af81c3cfdccfc178c91bd92d056940f Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Fri, 11 Apr 2025 10:28:09 +0200 Subject: [PATCH 07/10] pcm-raw: implement -? option to print all event dscriptions --- src/pcm-raw.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/pcm-raw.cpp b/src/pcm-raw.cpp index 5f881465..945816db 100644 --- a/src/pcm-raw.cpp +++ b/src/pcm-raw.cpp @@ -65,6 +65,7 @@ void print_usage(const string & progname) cout << " -e cha/config=0,name=UNC_CHA_CLOCKTICKS/ -e imc/fixed,name=DRAM_CLOCKS/\n"; #ifdef PCM_SIMDJSON_AVAILABLE cout << " -e NAME where the NAME is an event from https://github.com/intel/perfmon event lists\n"; + cout << " -? | /? => print all events that can be monitored on the host platform along with a description\n"; cout << " -ep path | /ep path => path to event list directory (default is the current directory)\n"; #endif cout << " -yc | --yescores | /yc => enable specific cores to output\n"; @@ -364,7 +365,7 @@ bool initPMUEventMap() catch (std::exception& e) { cerr << "Error while opening and/or parsing " << path << " : " << e.what() << "\n"; - printError(); + printError(); return false; } } @@ -431,6 +432,15 @@ class EventMap { return res; } + static void print_event_description(const std::string &eventStr) { + if (PMUEventMapJSON.find(eventStr) != PMUEventMapJSON.end()) { + const auto eventObj = PMUEventMapJSON[eventStr]; + for (const auto & key : {"BriefDescription", "PublicDescription"}) + std::cout << key << " : " << eventObj[key] << "\n"; + return; + } + } + static void print_event(const std::string &eventStr) { if (PMUEventMapJSON.find(eventStr) != PMUEventMapJSON.end()) { const auto eventObj = PMUEventMapJSON[eventStr]; @@ -454,6 +464,21 @@ class EventMap { } }; +void printAllEventDescriptions() +{ + if (initPMUEventMap() == false) + { + cerr << "ERROR: PMU Event map can not be initialized\n"; + return; + } + for (const auto& event : PMUEventMapJSON) + { + std::cout << event.first << "\n"; + EventMap::print_event_description(event.first); + std::cout << "\n"; + } +} + AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEventStr) { if (initPMUEventMap() == false) @@ -2481,6 +2506,13 @@ int mainThrows(int argc, char * argv[]) extendPrintout = true; continue; } +#if PCM_SIMDJSON_AVAILABLE + else if (check_argument_equals(*argv, {"-?", "/?"})) + { + printAllEventDescriptions(); + return 0; + } +#endif else if (check_argument_equals(*argv, {"-single-header", "/single-header"})) { singleHeader = true; From 4fd1ebffbc5bf160c2d2c24aaa4f421f03adc792 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Fri, 11 Apr 2025 10:49:29 +0200 Subject: [PATCH 08/10] pcm-raw: more debug output --- src/pcm-raw.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/pcm-raw.cpp b/src/pcm-raw.cpp index 945816db..9a2df544 100644 --- a/src/pcm-raw.cpp +++ b/src/pcm-raw.cpp @@ -264,12 +264,12 @@ bool initPMUEventMap() cerr << "Can't read first line from " << mapfile << " \n"; return false; } - // cout << FMSPos << " " << FilenamePos << " " << EventTypetPos << "\n"; + DBG(1, FMSPos , " " , FilenamePos , " " , EventTypetPos); assert(FMSPos >= 0); assert(FilenamePos >= 0); assert(EventTypetPos >= 0); const std::string ourFMS = PCM::getInstance()->getCPUFamilyModelString(); - // cout << "Our FMS: " << ourFMS << "\n"; + DBG(1, "Our FMS: " , ourFMS); std::multimap eventFiles; cerr << "Matched event files:\n"; while (std::getline(in, line)) @@ -460,7 +460,25 @@ class EventMap { } } } + } + + static void print_event_debug(const std::string &eventStr, const int debugLevel = 1) { + if (PMUEventMapJSON.find(eventStr) != PMUEventMapJSON.end()) { + const auto eventObj = PMUEventMapJSON[eventStr]; + for (const auto & keyValue : eventObj) + DBG(debugLevel, "JSON " , keyValue.key , " : " , keyValue.value); + } + for (auto &EventMapTSV : PMUEventMapsTSV) { + if (EventMapTSV.find(eventStr) != EventMapTSV.end()) { + const auto &col_names = EventMapTSV["COL_NAMES"]; + const auto event = EventMapTSV[eventStr]; + if (EventMapTSV.find(eventStr) != EventMapTSV.end()) { + for (size_t i = 0 ; i < col_names.size() ; i++) + DBG(debugLevel, "TSV " , col_names[i] , " : " , event[i]); + } + } + } } }; @@ -507,6 +525,8 @@ AddEventStatus addEventFromDB(PCM::RawPMUConfigs& curPMUConfigs, string fullEven const auto eventStr = EventTokens[0]; + EventMap::print_event_debug(eventStr); + DBG(2, "size: " , eventStr.size()); PCM::RawEventConfig config = { {0,0,0,0,0}, "" }; std::string pmuName; From 9303d6f65915b40916db9f416f579fb2938ce79d Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 11 Apr 2025 14:08:52 +0200 Subject: [PATCH 09/10] update dependencies Change-Id: I2a4eea66d59d433645ba3de4336edd7ab1d10533 --- Intel-PMT | 2 +- perfmon | 2 +- src/simdjson | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Intel-PMT b/Intel-PMT index 5e72e20e..134c36d1 160000 --- a/Intel-PMT +++ b/Intel-PMT @@ -1 +1 @@ -Subproject commit 5e72e20ed6eb3b9a5532cf2a063a640b5f7891cf +Subproject commit 134c36d1d4dd344a9893e02e350554f3df507a80 diff --git a/perfmon b/perfmon index 4a897731..2336912d 160000 --- a/perfmon +++ b/perfmon @@ -1 +1 @@ -Subproject commit 4a897731495f4f68ad4a597b557fdf39d24b4601 +Subproject commit 2336912dd4f4f8f5313914dc30e4f1e87429ab5b diff --git a/src/simdjson b/src/simdjson index 078e2c90..7382dc2b 160000 --- a/src/simdjson +++ b/src/simdjson @@ -1 +1 @@ -Subproject commit 078e2c90739a80563fb425d7f7011f3a2c7b7da9 +Subproject commit 7382dc2be88e53fbc35cb50369b831855656f0fd From aeaae3a85ef8b91c90ab156e9feee48bf6ab5248 Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 11 Apr 2025 16:27:16 +0200 Subject: [PATCH 10/10] upgrade freebsd version Change-Id: Ifb60a054707a3075145fd6939171e3f35d9e8b73 --- .github/workflows/freebsd_build.yml | 4 ++-- .github/workflows/freebsd_scan_build.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/freebsd_build.yml b/.github/workflows/freebsd_build.yml index c6826fe4..a2a885aa 100644 --- a/.github/workflows/freebsd_build.yml +++ b/.github/workflows/freebsd_build.yml @@ -25,12 +25,12 @@ jobs: submodules: recursive - name: build in FreeBSD VM id: build - uses: cross-platform-actions/action@cdc9ee69ef84a5f2e59c9058335d9c57bcb4ac86 # v0.25.0 + uses: cross-platform-actions/action with: memory: 2048 shell: sh operating_system: freebsd - version: '14.1' + version: '14.2' run: | sudo mkdir -p /usr/local/etc/pkg/repos sudo sh -c 'echo "FreeBSD: { url: \"https://pkg.FreeBSD.org/\${ABI}/quarterly\", mirror_type: \"srv\", enabled: yes }" > /usr/local/etc/pkg/repos/FreeBSD.conf' diff --git a/.github/workflows/freebsd_scan_build.yml b/.github/workflows/freebsd_scan_build.yml index 53818ea8..4fc3471a 100644 --- a/.github/workflows/freebsd_scan_build.yml +++ b/.github/workflows/freebsd_scan_build.yml @@ -25,12 +25,12 @@ jobs: submodules: recursive - name: clang scan build in FreeBSD VM id: clang-scan-build - uses: cross-platform-actions/action@cdc9ee69ef84a5f2e59c9058335d9c57bcb4ac86 # v0.25.0 + uses: cross-platform-actions/action with: memory: 2048 shell: sh operating_system: freebsd - version: '14.1' + version: '14.2' run: | sudo mkdir -p /usr/local/etc/pkg/repos sudo sh -c 'echo "FreeBSD: { url: \"https://pkg.FreeBSD.org/\${ABI}/quarterly\", mirror_type: \"srv\", enabled: yes }" > /usr/local/etc/pkg/repos/FreeBSD.conf'