IntelCPUSensor: support new Linux PECI API
The upstream PECI bus implementation doesn't support any ioctl() or
other means to send and receive PECI messages directly from the
userspace, instead it only provides regular kernel-level abstractions
(just hwmon CPU and DIMM temperature devices for now). It also requires
the userspace to trigger bus rescan after the CPU(s) are powered on.
This patch makes IntelCPUSensor automatically detect and use the new
API.
Change-Id: Icbd568aeeca6428a9fade12416e260741a76213c
Signed-off-by: Paul Fertser <fercerpav@gmail.com>
diff --git a/src/IntelCPUSensorMain.cpp b/src/IntelCPUSensorMain.cpp
index 757ebcf..0e0083a 100644
--- a/src/IntelCPUSensorMain.cpp
+++ b/src/IntelCPUSensorMain.cpp
@@ -86,6 +86,7 @@
static constexpr const char* peciDev = "/dev/peci-";
static constexpr const char* peciDevPath = "/sys/bus/peci/devices/";
+static constexpr const char* rescanPath = "/sys/bus/peci/rescan";
static constexpr const unsigned int rankNumMax = 8;
namespace fs = std::filesystem;
@@ -169,9 +170,10 @@
}
std::vector<fs::path> hwmonNamePaths;
- if (!findFiles(fs::path(peciDevPath),
- R"(peci-\d+/\d+-.+/peci-.+/hwmon/hwmon\d+/name$)",
- hwmonNamePaths, 6))
+ findFiles(fs::path(peciDevPath),
+ R"(peci-\d+/\d+-.+/peci[-_].+/hwmon/hwmon\d+/name$)",
+ hwmonNamePaths, 6);
+ if (hwmonNamePaths.empty())
{
std::cerr << "No CPU sensors in system\n";
return false;
@@ -489,6 +491,45 @@
continue;
}
+ std::fstream rescan{rescanPath, std::ios::out};
+ if (rescan.is_open())
+ {
+ std::vector<fs::path> peciPaths;
+ std::ostringstream searchPath;
+ searchPath << std::hex << "peci-" << config.bus << "/" << config.bus
+ << "-" << config.addr;
+ findFiles(fs::path(peciDevPath + searchPath.str()),
+ R"(peci_cpu.dimmtemp.+/hwmon/hwmon\d+/name$)", peciPaths,
+ 3);
+ if (!peciPaths.empty())
+ {
+ config.state = State::READY;
+ rescanDelaySeconds = 1;
+ }
+ else
+ {
+ findFiles(fs::path(peciDevPath + searchPath.str()),
+ R"(peci_cpu.cputemp.+/hwmon/hwmon\d+/name$)",
+ peciPaths, 3);
+ if (!peciPaths.empty())
+ {
+ config.state = State::ON;
+ rescanDelaySeconds = 3;
+ }
+ else
+ {
+ // https://www.kernel.org/doc/html/latest/admin-guide/abi-testing.html#abi-sys-bus-peci-rescan
+ rescan << "1";
+ }
+ }
+ if (config.state != State::READY)
+ {
+ keepPinging = true;
+ }
+
+ continue;
+ }
+
std::string peciDevPath = peciDev + std::to_string(config.bus);
peci_SetDevName(peciDevPath.data());