sst: Don't always wake idle CPU
Some parts of SST are important (initial discovery, appliedConfig
change) and should use wake-on-PECI to ensure success even if the CPU is
in an idle PkgC state. Other parts are not important enough to justify
increasing the CPU power draw. Add a WakePolicy parameter to the
SSTInterface infrastructure to use a different policy in different
contexts.
Change-Id: I91435cc0357ab60ca4656e1bc51286e046ae3809
Signed-off-by: Jonathan Doman <jonathan.doman@intel.com>
diff --git a/src/speed_select.cpp b/src/speed_select.cpp
index 3ae89b8..d393e4a 100644
--- a/src/speed_select.cpp
+++ b/src/speed_select.cpp
@@ -80,7 +80,8 @@
getProviders().push_back(providerFn);
}
-std::unique_ptr<SSTInterface> getInstance(uint8_t address, CPUModel model)
+std::unique_ptr<SSTInterface> getInstance(uint8_t address, CPUModel model,
+ WakePolicy wakePolicy)
{
DEBUG_PRINT << "Searching for provider for " << address << ", model "
<< std::hex << model << std::dec << '\n';
@@ -88,7 +89,7 @@
{
try
{
- auto interface = provider(address, model);
+ auto interface = provider(address, model, wakePolicy);
DEBUG_PRINT << "returned " << interface << '\n';
if (interface)
{
@@ -161,12 +162,13 @@
}
public:
- CPUConfig(sdbusplus::bus_t& bus_, uint8_t index, CPUModel model) :
+ CPUConfig(sdbusplus::bus_t& bus_, uint8_t index, CPUModel model,
+ unsigned int currentLevel_, bool bfEnabled_) :
BaseCurrentOperatingConfig(bus_, generatePath(index).c_str(),
action::defer_emit),
bus(bus_), peciAddress(index + MIN_CLIENT_ADDR),
- path(generatePath(index)), cpuModel(model), currentLevel(0),
- bfEnabled(false)
+ path(generatePath(index)), cpuModel(model), currentLevel(currentLevel_),
+ bfEnabled(bfEnabled_)
{}
//
@@ -179,7 +181,7 @@
if (hostState != HostState::off)
{
// Otherwise, try to read current state
- auto sst = getInstance(peciAddress, cpuModel);
+ auto sst = getInstance(peciAddress, cpuModel, dontWake);
if (!sst || !sst->ready())
{
std::cerr << __func__
@@ -206,7 +208,7 @@
DEBUG_PRINT << "Reading BaseSpeedPriorityEnabled\n";
if (hostState != HostState::off)
{
- auto sst = getInstance(peciAddress, cpuModel);
+ auto sst = getInstance(peciAddress, cpuModel, dontWake);
if (!sst || !sst->ready())
{
std::cerr << __func__
@@ -247,7 +249,7 @@
InvalidArgument();
}
- auto sst = getInstance(peciAddress, cpuModel);
+ auto sst = getInstance(peciAddress, cpuModel, wakeAllowed);
if (!sst)
{
std::cerr << __func__ << ": Failed to get SST provider instance\n";
@@ -422,7 +424,8 @@
continue;
}
- std::unique_ptr<SSTInterface> sst = getInstance(i, cpuModel);
+ std::unique_ptr<SSTInterface> sst = getInstance(i, cpuModel,
+ wakeAllowed);
if (!sst)
{
@@ -445,8 +448,10 @@
}
// Create the per-CPU configuration object
+ unsigned int currentLevel = sst->currentLevel();
cpuList.emplace_back(
- std::make_unique<CPUConfig>(conn, cpuIndex, cpuModel));
+ std::make_unique<CPUConfig>(conn, cpuIndex, cpuModel, currentLevel,
+ sst->bfEnabled(currentLevel)));
CPUConfig& cpu = *cpuList.back();
bool foundCurrentLevel = false;
@@ -467,13 +472,13 @@
getSingleConfig(*sst, level, cpu.newConfig(level));
- if (level == sst->currentLevel())
+ if (level == currentLevel)
{
foundCurrentLevel = true;
}
}
- DEBUG_PRINT << "current level is " << sst->currentLevel() << '\n';
+ DEBUG_PRINT << "current level is " << currentLevel << '\n';
if (!foundCurrentLevel)
{
diff --git a/src/sst_mailbox.cpp b/src/sst_mailbox.cpp
index 2627894..b086c55 100644
--- a/src/sst_mailbox.cpp
+++ b/src/sst_mailbox.cpp
@@ -38,9 +38,11 @@
bool peciWoken;
CPUModel cpuModel;
uint8_t mbBus;
+ WakePolicy wakePolicy;
- PECIManager(uint8_t address, CPUModel model) :
- peciAddress(address), peciWoken(false), cpuModel(model)
+ PECIManager(uint8_t address, CPUModel model, WakePolicy wakePolicy_) :
+ peciAddress(address), peciWoken(false), cpuModel(model),
+ wakePolicy(wakePolicy_)
{
mbBus = (model == icx) ? mbBusICX : mbBusOther;
}
@@ -120,7 +122,7 @@
void wrMailboxReg(uint16_t regAddress, uint32_t data)
{
uint8_t completionCode;
- bool tryWaking = true;
+ bool tryWaking = (wakePolicy == wakeAllowed);
while (true)
{
EPECIStatus libStatus = peci_WrEndPointPCIConfigLocal(
@@ -152,7 +154,7 @@
{
uint8_t completionCode;
uint32_t outputData;
- bool tryWaking = true;
+ bool tryWaking = (wakePolicy == wakeAllowed);
while (true)
{
EPECIStatus libStatus = peci_RdEndPointConfigPciLocal(
@@ -397,9 +399,9 @@
static constexpr int mhzPerRatio = 100;
public:
- SSTMailbox(uint8_t _address, CPUModel _model) :
+ SSTMailbox(uint8_t _address, CPUModel _model, WakePolicy wakePolicy) :
address(_address), model(_model),
- pm(static_cast<uint8_t>(address), model)
+ pm(static_cast<uint8_t>(address), model, wakePolicy)
{}
~SSTMailbox() {}
@@ -568,8 +570,8 @@
}
};
-static std::unique_ptr<SSTInterface> createMailbox(uint8_t address,
- CPUModel model)
+static std::unique_ptr<SSTInterface>
+ createMailbox(uint8_t address, CPUModel model, WakePolicy wakePolicy)
{
DEBUG_PRINT << "createMailbox\n";
switch (model)
@@ -578,7 +580,7 @@
case icxd:
case spr:
case emr:
- return std::make_unique<SSTMailbox>(address, model);
+ return std::make_unique<SSTMailbox>(address, model, wakePolicy);
default:
return nullptr;
}