summaryrefslogtreecommitdiffstats
path: root/src/usr/htmgt
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/htmgt')
-rw-r--r--src/usr/htmgt/htmgt.C14
-rw-r--r--src/usr/htmgt/htmgt_memthrottles.C144
2 files changed, 93 insertions, 65 deletions
diff --git a/src/usr/htmgt/htmgt.C b/src/usr/htmgt/htmgt.C
index 50006aaa0..83fcd4e51 100644
--- a/src/usr/htmgt/htmgt.C
+++ b/src/usr/htmgt/htmgt.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2017 */
+/* Contributors Listed Below - COPYRIGHT 2014,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -248,7 +248,7 @@ namespace HTMGT
// Notify HTMGT that an OCC has an error to report
void processOccError(TARGETING::Target * i_procTarget)
{
- TMGT_INF(">>processOccError(0x%p)", i_procTarget);
+ TMGT_INF(">>processOccAttn(0x%p)", i_procTarget);
TARGETING::Target* sys = nullptr;
TARGETING::targetService().getTopLevelTarget(sys);
@@ -271,7 +271,7 @@ namespace HTMGT
{
const uint32_t l_huid =
i_procTarget->getAttr<TARGETING::ATTR_HUID>();
- TMGT_INF("processOccError(HUID=0x%08X) called", l_huid);
+ TMGT_INF("processOccAttn(HUID=0x%08X) called", l_huid);
TARGETING::TargetHandleList pOccs;
getChildChiplets(pOccs, i_procTarget, TARGETING::TYPE_OCC);
@@ -299,13 +299,13 @@ namespace HTMGT
if (OccManager::occNeedsReset())
{
- TMGT_ERR("processOccError(): OCCs need to be reset");
+ TMGT_ERR("processOccAttn(): OCCs need to be reset");
// Don't pass failed target as OCC should have already
// been marked as failed during the poll.
errlHndl_t err = OccManager::resetOccs(nullptr);
if(err)
{
- TMGT_ERR("processOccError(): Error when attempting"
+ TMGT_ERR("processOccAttn(): Error when attempting"
" to reset OCCs");
ERRORLOG::errlCommit(err, HTMGT_COMP_ID);
}
@@ -314,10 +314,10 @@ namespace HTMGT
else
{
// OCC build failed...
- TMGT_ERR("processOccError() called, but unable to find OCCs");
+ TMGT_ERR("processOccAttn() called, but unable to find OCCs");
ERRORLOG::errlCommit(err, HTMGT_COMP_ID);
}
- TMGT_INF("<<processOccError()");
+ TMGT_INF("<<processOccAttn()");
} // end processOccError()
diff --git a/src/usr/htmgt/htmgt_memthrottles.C b/src/usr/htmgt/htmgt_memthrottles.C
index 0168d76cf..a51b7febc 100644
--- a/src/usr/htmgt/htmgt_memthrottles.C
+++ b/src/usr/htmgt/htmgt_memthrottles.C
@@ -59,32 +59,21 @@ namespace HTMGT
* based on the specified utilization
*
* @param[in] i_utilization - Minimum utilization value required (in %)
- * @param[in] i_watt_target - power target required for bulk_pwr_throttles
*/
errlHndl_t call_utils_to_throttle(
std::vector <fapi2::Target<fapi2::TARGET_TYPE_MCS>> i_fapi_target_list,
- const uint32_t i_util,
- const uint32_t i_watt_target = 0)
+ const uint32_t i_util)
{
errlHndl_t err = NULL;
// Convert to 1/100 % units for the HWP
const uint32_t util_hundredth_percent = i_util * 100;
uint32_t utilization[TMGT_MAX_MCA_PER_MCS] = {
util_hundredth_percent, util_hundredth_percent };
- uint32_t l_watt_targets[TMGT_MAX_MCA_PER_MCS][TMGT_MAX_DIMM_PER_MCA] =
- {i_watt_target, i_watt_target, i_watt_target, i_watt_target};
- TMGT_INF("call_utils_to_throttle: utilization: %d, watt_target: %d",
- i_util, i_watt_target);
// Update input attributes for specified targets
for(const auto & l_fapi_target : i_fapi_target_list)
{
FAPI_ATTR_SET(fapi2::ATTR_MSS_DATABUS_UTIL, l_fapi_target, utilization);
- if (i_watt_target)
- {
- FAPI_ATTR_SET(fapi2::ATTR_MSS_MEM_WATT_TARGET,
- l_fapi_target, l_watt_targets);
- }
}
// p9_mss_utils_to_throttle() - Sets number commands allowed within a
@@ -94,7 +83,7 @@ errlHndl_t call_utils_to_throttle(
// ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, and
// ATTR_MSS_PORT_MAXPOWER
TMGT_INF("call_utils_to_throttle: Calling HWP:p9_mss_utils_to_throttle"
- "(POWER) for %d MCS Targets", i_fapi_target_list.size());
+ " with utilization of %d percent", i_util);
{
FAPI_INVOKE_HWP(err, p9_mss_utils_to_throttle, i_fapi_target_list);
}
@@ -116,14 +105,16 @@ errlHndl_t call_utils_to_throttle(
*
* @param[in] i_fapi_target_list - list of FAPI MCS targets
* @param[in] i_utilization - Minimum utilization value required
+ * @param[in] i_efficiency - the regulator efficiency (percent)
*/
errlHndl_t memPowerThrottleOT(
std::vector < fapi2::Target< fapi2::TARGET_TYPE_MCS>> i_fapi_target_list,
- const uint8_t i_utilization)
+ const uint8_t i_utilization,
+ const uint8_t i_efficiency)
{
errlHndl_t err = NULL;
- TMGT_INF("memPowerThrottleOT: Calculating throttles for util: %d",
+ TMGT_INF("memPowerThrottleOT: utilization: %d percent",
i_utilization);
err = call_utils_to_throttle(i_fapi_target_list, i_utilization);
@@ -157,8 +148,15 @@ errlHndl_t memPowerThrottleOT(
occ_instance, mcs_unit, l_slot[0], l_slot[1],
l_power[0], l_power[1]);
}
+
+ if (0 != i_efficiency)
+ {
+ // Upconvert from regulator loss
+ ot_mem_power /= (i_efficiency / 100.0);
+ }
+ // Round up to nearest Watt
TMGT_INF("memPowerThrottleOT: Total Minimum Memory"
- " Power: %dW", ot_mem_power/100);
+ " Power: %dW", (ot_mem_power/100)+1);
}
else
{
@@ -178,35 +176,37 @@ errlHndl_t memPowerThrottleOT(
* to calculate memory throttling numerator values.
*
* @param[in] i_fapi_target_list - list of FAPI MCS targets
- * @param[in] i_wattTarget - the power target for the MCS
- * @param[in] i_utilization - the utilization desired
+ * @param[in] i_watt_target - the power target for the MCS (in cW)
*/
errlHndl_t call_bulk_pwr_throttles(
std::vector < fapi2::Target< fapi2::TARGET_TYPE_MCS>> i_fapi_target_list,
- const uint32_t i_wattTarget,
- const uint8_t i_utilization)
+ const uint32_t i_watt_target)
{
errlHndl_t err = NULL;
+ uint32_t l_watt_targets[TMGT_MAX_MCA_PER_MCS][TMGT_MAX_DIMM_PER_MCA] =
+ {i_watt_target, i_watt_target, i_watt_target, i_watt_target};
- //Set the values the procedures need
- err = call_utils_to_throttle(i_fapi_target_list,
- i_utilization, i_wattTarget);
- if (NULL == err)
+ // Update input attributes for specified targets
+ for(const auto & l_fapi_target : i_fapi_target_list)
{
- TMGT_INF("call_bulk_pwr_throttles: Calling HWP:p9_mss_bulk_pwr_"
- "throttles(POWER) for MCS Targets");
- FAPI_INVOKE_HWP(err, p9_mss_bulk_pwr_throttles, i_fapi_target_list,
- mss::throttle_type::POWER);
- if (NULL != err)
- {
- TMGT_ERR("call_bulk_pwr_throttles: p9_mss_bulk_pwr_throttles "
- "failed with rc=0x%04X", err->reasonCode());
- }
+ FAPI_ATTR_SET(fapi2::ATTR_MSS_MEM_WATT_TARGET,
+ l_fapi_target, l_watt_targets);
}
- else
+
+ TMGT_INF("call_bulk_pwr_throttles: Calling HWP:p9_mss_bulk_pwr_"
+ "throttles(POWER) with target of %dcW", i_watt_target);
+ // p9_mss_bulk_pwr_throttles() - Determines the throttle levels based
+ // off of the port's power curve
+ // inputs: ATTR_MSS_MEM_WATT_TARGET
+ // outputs: ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT,
+ // ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, and
+ // ATTR_MSS_PORT_MAXPOWER
+ FAPI_INVOKE_HWP(err, p9_mss_bulk_pwr_throttles, i_fapi_target_list,
+ mss::throttle_type::POWER);
+ if (NULL != err)
{
- TMGT_ERR("call_bulk_pwr_throttles: call_utils_to_throttle failed with"
- " rc=0x%04X", err->reasonCode());
+ TMGT_ERR("call_bulk_pwr_throttles: p9_mss_bulk_pwr_throttles "
+ "failed with rc=0x%04X", err->reasonCode());
}
return err;
@@ -219,7 +219,7 @@ errlHndl_t call_bulk_pwr_throttles(
*
* @param[in] i_fapi_target_list - list of FAPI MCS targets
* @param[in] i_utilization - Minimum utilization value required
- * @param[in] i_efficiency - the regulator efficiency
+ * @param[in] i_efficiency - the regulator efficiency (percent)
*/
errlHndl_t memPowerThrottleRedPower(
std::vector <fapi2::Target<fapi2::TARGET_TYPE_MCS>> i_fapi_target_list,
@@ -240,7 +240,7 @@ errlHndl_t memPowerThrottleRedPower(
//Account for the regulator efficiency (percentage), if supplied
if (i_efficiency != 0)
{
- power = (power * i_efficiency) / 100;
+ power *= (i_efficiency / 100.0);
}
//Find the Watt target for each present DIMM
@@ -251,13 +251,11 @@ errlHndl_t memPowerThrottleRedPower(
wattTarget = power / dimm_list.size();
}
- TMGT_INF("memPowerThrottleRedPower: N+1 power: %dW / %dcW per DIMM "
- "(%d DIMMs)", power/100, wattTarget, dimm_list.size());
+ TMGT_INF("memPowerThrottleRedPower: N+1 power: %dW (%d DIMMs) -> "
+ "%dcW per DIMM", power/100, dimm_list.size(), wattTarget);
//Calculate the throttles
- err = call_bulk_pwr_throttles(i_fapi_target_list,
- wattTarget,
- i_utilization);
+ err = call_bulk_pwr_throttles(i_fapi_target_list, wattTarget);
if (NULL == err)
{
uint32_t tot_mem_power_cw = 0;
@@ -294,8 +292,8 @@ errlHndl_t memPowerThrottleRedPower(
occ_instance, mcs_unit, l_slot[0], l_slot[1],
l_port[0], l_port[1], l_power[0], l_power[1]);
}
- // Convert memory power to Watts
- G_mem_power_min_throttles = tot_mem_power_cw / 100;
+ // Convert memory power to Watts (and round up)
+ G_mem_power_min_throttles = (tot_mem_power_cw / 100) + 1;
TMGT_INF("memPowerThrottleRedPower: Total Redundant Memory Power: %dW",
G_mem_power_min_throttles);
}
@@ -317,10 +315,12 @@ errlHndl_t memPowerThrottleRedPower(
*
* @param[in] i_fapi_target_list - list of FAPI MCS targets
* @param[in] i_utilization - Minimum utilization value required
+ * @param[in] i_efficiency - the regulator efficiency (percent)
*/
errlHndl_t memPowerThrottlePowercap(
std::vector < fapi2::Target< fapi2::TARGET_TYPE_MCS>> i_fapi_target_list,
- const uint8_t i_utilization)
+ const uint8_t i_utilization,
+ const uint8_t i_efficiency)
{
errlHndl_t err = NULL;
@@ -331,6 +331,8 @@ errlHndl_t memPowerThrottlePowercap(
{
//Calculate the throttles
err = call_utils_to_throttle(i_fapi_target_list, i_utilization);
+ // Power Capping on OpenPower is based on utilizations from MRW
+ // and not dependent on system configuration (no bulk power calculation)
}
if (NULL == err)
{
@@ -368,27 +370,41 @@ errlHndl_t memPowerThrottlePowercap(
mcs_target->tryGetAttr<ATTR_N_PLUS_ONE_N_PER_MBA>(l_slot_redun);
mcs_target->tryGetAttr<ATTR_N_PLUS_ONE_N_PER_CHIP>(l_port_redun);
mcs_target->tryGetAttr<ATTR_N_PLUS_ONE_MEM_POWER>(l_power_redun);
+ ATTR_OT_MIN_N_PER_MBA_type l_slot_oversub = {0};
+ ATTR_OT_MEM_POWER_type l_power_oversub = {0};
+ mcs_target->tryGetAttr<ATTR_OT_MIN_N_PER_MBA>(l_slot_oversub);
+ mcs_target->tryGetAttr<ATTR_OT_MEM_POWER>(l_power_oversub);
unsigned int mca_index;
for (mca_index = 0; mca_index < TMGT_MAX_MCA_PER_MCS; ++mca_index)
{
+ if (l_slot[mca_index] > l_slot_oversub[mca_index])
+ {
+ TMGT_INF("memPowerThrottlePowercap: MCS%d/MCA%d - "
+ "using oversub throttles (since pcap > oversub)",
+ mcs_unit, mca_index);
+ l_slot[mca_index] = l_slot_oversub[mca_index];
+ // no attribute for port, so use slot for both
+ l_port[mca_index] = l_slot_oversub[mca_index];
+ l_power[mca_index] = l_power_oversub[mca_index];
+ }
if (l_slot[mca_index] > l_slot_redun[mca_index])
{
TMGT_INF("memPowerThrottlePowercap: MCS%d/MCA%d - "
- " redun throttle (%d) < pcap throttle (%d)",
- mcs_unit, mca_index,
- l_slot_redun[mca_index], l_slot[mca_index]);
+ "using redundant throttles (since pcap > redun)",
+ mcs_unit, mca_index);
l_slot[mca_index] = l_slot_redun[mca_index];
l_port[mca_index] = l_port_redun[mca_index];
l_power[mca_index] = l_power_redun[mca_index];
}
+
+ // Add total memory power with powercap (maximum throttles)
+ tot_mem_power_cw += l_power[mca_index];
}
// Update MCS data (to be sent to OCC)
mcs_target->setAttr<ATTR_POWERCAP_N_PER_MBA>(l_slot);
mcs_target->setAttr<ATTR_POWERCAP_N_PER_CHIP>(l_port);
mcs_target->setAttr<ATTR_POWERCAP_MEM_POWER>(l_power);
- // Calculate memory power at max throttles
- tot_mem_power_cw += l_power[0] + l_power[1];
// Trace Results
TMGT_INF("memPowerThrottlePowercap: PCAP: OCC%d/MCS%d - "
@@ -396,8 +412,15 @@ errlHndl_t memPowerThrottlePowercap(
occ_instance, mcs_unit, l_slot[0], l_slot[1],
l_port[0], l_port[1], l_power[0], l_power[1]);
}
- // Convert memory power to Watts
- G_mem_power_max_throttles = tot_mem_power_cw / 100;
+
+ if (0 != i_efficiency)
+ {
+ // Upconvert from regulator loss
+ tot_mem_power_cw /= (i_efficiency / 100.0);
+ }
+
+ // Convert memory power to Watts (and round up)
+ G_mem_power_max_throttles = (tot_mem_power_cw / 100) + 1;
TMGT_INF("memPowerThrottlePowercap: Total PowerCap Memory"
" Power: %dW (@max throttles)", G_mem_power_max_throttles);
}
@@ -467,8 +490,8 @@ void calculate_system_power()
const uint16_t mhz_per_watt = sys->getAttr<ATTR_PROC_MHZ_PER_WATT>();
// Drop always calculated from Turbo to Min (not ultra)
uint32_t proc_drop = ((freq_turbo - freq_min) / mhz_per_watt);
- TMGT_INF("calculate_system_power: Processor Power Drop: %dMHz / %dMHz/W"
- " = %dW / proc",
+ TMGT_INF("calculate_system_power: Processor Power Drop: %dMHz (%dMHz/W) "
+ "-> %dW/proc",
freq_turbo - freq_min, mhz_per_watt, proc_drop);
proc_drop *= num_procs;
const uint32_t memory_drop =
@@ -549,12 +572,15 @@ errlHndl_t calcMemThrottles()
do
{
//Calculate Throttle settings for Over Temperature
- err = memPowerThrottleOT(l_fapi_target_list, min_utilization);
+ err = memPowerThrottleOT(l_fapi_target_list,
+ min_utilization,
+ efficiency);
if (NULL != err) break;
//Calculate Throttle settings for Nominal/Turbo
err = memPowerThrottleRedPower(l_fapi_target_list,
- min_utilization, efficiency);
+ min_utilization,
+ efficiency);
if (NULL != err) break;
//Calculate Throttle settings for Power Capping
@@ -564,7 +590,9 @@ errlHndl_t calcMemThrottles()
{
pcap_min_utilization = 0;
}
- err = memPowerThrottlePowercap(l_fapi_target_list,pcap_min_utilization);
+ err = memPowerThrottlePowercap(l_fapi_target_list,
+ pcap_min_utilization,
+ efficiency);
} while(0);
OpenPOWER on IntegriCloud