Skip to content

Commit

Permalink
P9N/P9C util to throttle HWP updates for min util and safemode
Browse files Browse the repository at this point in the history
Changes include:
-- fix for SW408681 (p9n util to throttle min util enforcement)
-- safemode throttle calculation support when input util is 0 (p9n/p9c)
-- fix trace printing for floating point variables (p9n)
-- fix trace printing in equalize throttles (p9n)

Change-Id: I16530b98e29cb0ad32ae77387b92d9d70b50f83c
CQ: SW408681
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/60895
Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/60898
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
  • Loading branch information
pardeik authored and crgeddes committed Jun 21, 2018
1 parent d420d7b commit df43ad6
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
/// and the channel pair power at the given utilization value
//// OCC calls this HWP after setting ATTR_CEN_MSS_DATABUS_UTIL_PER_MBA
//// ATTR_CEN_MSS_DATABUS_UTIL_PER_MBA is a floor or minimum value to meet
//// If input utilization is zero, then safemode values from MRW will be used
///
/// *HWP HWP Owner: Andre Marin <aamaring@us.ibm.com>
/// *HWP HWP Backup: Michael Pardeik <pardeik@us.ibm.com>
Expand Down Expand Up @@ -62,6 +63,11 @@ extern "C" {
double l_channel_power_slope = 0;
double l_channel_power_intercept = 0;
constexpr bool l_utilization_is_a_min_value = true; // set to true
uint8_t l_safemode_util = 0;
uint32_t l_safemode_throttle_n_per_mba = 0;
uint32_t l_safemode_throttle_n_per_chip = 0;
uint32_t l_throttle_d = 0;
bool l_safemode = false;

// If MBA has no DIMMs, return as there is nothing to do
if (mss::count_dimm(i_target_mba) == 0)
Expand All @@ -75,17 +81,116 @@ extern "C" {
i_target_mba, l_data_bus_util));
FAPI_INF("[%s Input Attribute Utilization %d percent]", mss::c_str(i_target_mba), l_data_bus_util);

// If input utilizaiton is zero, then use safemode throttle attributes to calculate utilization
if (l_data_bus_util == 0)
{
FAPI_TRY(p9c_mss_util_to_throttle_safemode(i_target_mba, l_safemode_util));
FAPI_INF("[%s Using Safemode Utilization %d percent]", mss::c_str(i_target_mba), l_safemode_util);
l_data_bus_util = l_safemode_util;
l_safemode = true;
}

// call p9c_mss_bulk_pwr_channel_power to get the channel pair power slope and intercept values to use
FAPI_TRY(p9c_mss_bulk_pwr_channel_pair_power_curve(i_target_mba, l_channel_power_slope, l_channel_power_intercept));

// call p9c_mss_bulk_pwr_util_to_throttle_power to get the memory throttle and channel pair power attributes defined
// This call will return an error if calculated util does not meet input util target (l_data_bus_util)
FAPI_TRY(p9c_mss_bulk_pwr_util_to_throttle_power(i_target_mba,
(static_cast<double>(l_data_bus_util)), l_channel_power_slope,
l_channel_power_intercept, l_utilization_is_a_min_value));

// Set throttle attributes to the safemode throttle attributes if input utilization was zero
// This is done in case the utilization from the mrw safemode throttles is not a whole integer value
// The calculated N throttle values may be different than the mrw safemode throttles, so make sure we end up at the mrw values
if (l_safemode)
{
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MRW_SAFEMODE_MEM_THROTTLE_NUMERATOR_PER_MBA,
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
l_safemode_throttle_n_per_mba));
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MRW_SAFEMODE_MEM_THROTTLE_NUMERATOR_PER_CHIP,
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
l_safemode_throttle_n_per_chip));
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_MRW_MEM_M_DRAM_CLOCKS,
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
l_throttle_d));
FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_CEN_MSS_MEM_THROTTLE_NUMERATOR_PER_MBA,
i_target_mba, l_safemode_throttle_n_per_mba));
FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_CEN_MSS_MEM_THROTTLE_NUMERATOR_PER_CHIP,
i_target_mba, l_safemode_throttle_n_per_chip));
FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_CEN_MSS_MEM_THROTTLE_DENOMINATOR,
i_target_mba, l_throttle_d));
FAPI_INF("[%s Throttle attributes set to safemode values %d/%d/%d]", mss::c_str(i_target_mba),
l_safemode_throttle_n_per_mba, l_safemode_throttle_n_per_chip, l_throttle_d);
}

FAPI_INF("*** p9c_mss_util_to_throttle COMPLETE on %s ***", mss::c_str(i_target_mba));

fapi_try_exit:
return fapi2::current_err;
}

///
/// @brief This function will determine the safemode dram utilization
/// for the MRW safemode throttle values
/// @param[in] i_target_mba: MBA Target
/// @param[out] o_safemode_util: safemode utilization value from MRW attributes
/// @return fapi2::ReturnCode
///
fapi2::ReturnCode p9c_mss_util_to_throttle_safemode(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
uint8_t& o_safemode_util)
{
FAPI_INF("*** Running p9c_mss_util_to_throttle_safemode on %s ***", mss::c_str(i_target_mba));

uint32_t l_safemode_throttle_n_per_mba = 0;
uint32_t l_safemode_throttle_n_per_chip = 0;
uint32_t l_throttle_d = 0;
uint8_t l_custom_dimm = 0;
uint8_t l_throttle_multiplier = 0;
double l_utilization = 0;
double l_util_mba = 0;
double l_util_chip = 0;

FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MRW_SAFEMODE_MEM_THROTTLE_NUMERATOR_PER_MBA,
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
l_safemode_throttle_n_per_mba));
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_MRW_SAFEMODE_MEM_THROTTLE_NUMERATOR_PER_CHIP,
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
l_safemode_throttle_n_per_chip));
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MSS_MRW_MEM_M_DRAM_CLOCKS,
fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
l_throttle_d));
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_CUSTOM_DIMM, i_target_mba, l_custom_dimm));

// Set the throttle multiplier based on how throttles are used
// CDIMMs use per mba and per chip throttles (for l_throttle_n_per_mba and l_throttle_n_per_chip), set to 2
// ISDIMMs use per slot and per mba throttles (for l_throttle_n_per_mba and l_throttle_n_per_chip), set to 1
l_throttle_multiplier = (l_custom_dimm == fapi2::ENUM_ATTR_CEN_EFF_CUSTOM_DIMM_YES) ? 2 : 1;

// Calculate the utilization value from the safemode throttle values
// Throttling is disabled if M (or l_throttle_d) is 0. If that is the case, then set util to MAX_UTIL.
if (l_throttle_d == 0)
{
l_utilization = static_cast<double>(MAX_UTIL) / PERCENT_CONVERSION;
}
else
{
l_util_mba = (static_cast<double>(l_safemode_throttle_n_per_mba) * ADDR_TO_DATA_UTIL_CONVERSION / l_throttle_d *
PERCENT_CONVERSION);
l_util_chip = (static_cast<double>(l_safemode_throttle_n_per_chip) * ADDR_TO_DATA_UTIL_CONVERSION / l_throttle_d /
l_throttle_multiplier * PERCENT_CONVERSION);
l_utilization = ((l_safemode_throttle_n_per_mba * l_throttle_multiplier) <= l_safemode_throttle_n_per_chip) ?
l_util_mba : l_util_chip;
}

// round up if not a whole integer (may end up with a litle more power if not a whole integer which shouldn't be an issue)
o_safemode_util = ceil(l_utilization);

FAPI_INF("%s Safemode Throttles %d/%d/%d, Util %4.2lf/%d percent", mss::c_str(i_target_mba),
l_safemode_throttle_n_per_mba, l_safemode_throttle_n_per_chip, l_throttle_d, l_utilization, o_safemode_util);
FAPI_INF("*** p9c_mss_util_to_throttle_safemode COMPLETE on %s ***", mss::c_str(i_target_mba));

fapi_try_exit:
return fapi2::current_err;
}

} //end extern C
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ extern "C"
///
fapi2::ReturnCode p9c_mss_util_to_throttle(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba);

///
/// @brief This function will determine the safemode dram utilization
/// for the MRW safemode throttle values
/// @param[in] i_target_mba: MBA Target
/// @param[out] o_safemode_util: safemode utilization value from MRW attributes
/// @return fapi2::ReturnCode
///
fapi2::ReturnCode p9c_mss_util_to_throttle_safemode(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
uint8_t& o_safemode_util);

} // extern "C"

#endif // MSS_UTIL_TO_THROTTLE_H_
Original file line number Diff line number Diff line change
Expand Up @@ -907,13 +907,14 @@ fapi2::ReturnCode equalize_throttles (const std::vector< fapi2::Target<fapi2::TA

o_exceeded_power.push_back(l_mca);
}

FAPI_INF("%s Final throttles values for slot %d, for port %d, power value %d",
mss::c_str(l_mca),
l_fin_port[l_pos],
l_fin_slot[l_pos],
l_fin_power[l_pos]);
}

FAPI_INF("%s Final throttles values for slot %d, for port %d, power value %d",
mss::c_str(l_mcs),
l_fin_port,
l_fin_slot,
l_fin_port);
//Even if there's an error, still calculate and set the throttles.
//OCC will set to safemode if there's an error
//Better to set the throttles than leave them 0, and potentially brick the memory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,12 +300,12 @@ fapi2::ReturnCode calc_util_from_throttles(const uint16_t i_n_throttles,
// Check for the minimum
if(o_calc_util < MIN_UTIL)
{
FAPI_INF("Calculated utilization (%lu) is less than the minimum utilization: %lu. Setting to minimum value",
FAPI_INF("Calculated utilization (%f) is less than the minimum utilization: %lu. Setting to minimum value",
o_calc_util, MIN_UTIL);
o_calc_util = MIN_UTIL;
}

FAPI_INF("In calc_util_from_throttles, calculated %d for output utilization", o_calc_util);
FAPI_INF("In calc_util_from_throttles, calculated %f for output utilization", o_calc_util);
return fapi2::FAPI2_RC_SUCCESS;
fapi_try_exit:
return fapi2::current_err;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
/// @file p9_mss_eff_config_thermal.C
/// @brief Perform thermal calculations as part of the effective configuration
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Michael Pardeik <pardeik@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
Expand Down Expand Up @@ -72,6 +72,24 @@ extern "C"

FAPI_INF("Size of vectors are %d %d %d", l_slope.size(), l_intercept.size(), l_thermal_power_limit.size());

// Return error if safemode throttle utilization is less than MIN_UTIL
// This section needs to be in braces otherwise the compile will fail
{
uint16_t l_throttle_per_port = 0;
uint32_t l_throttle_denominator = 0;
FAPI_TRY(mss::mrw_mem_m_dram_clocks(l_throttle_denominator), "Error in p9_mss_eff_config_thermal" );
FAPI_TRY(mss::mrw_safemode_mem_throttled_n_commands_per_port(l_throttle_per_port),
"Error in p9_mss_eff_config_thermal" );
FAPI_ASSERT( (l_throttle_per_port >= (mss::power_thermal::MIN_UTIL * l_throttle_denominator /
mss::power_thermal::DRAM_BUS_UTILS / mss::power_thermal::UTIL_CONVERSION)),
fapi2::MSS_MRW_SAFEMODE_THROTTLE_NOT_SUPPORTED()
.set_MRW_SAFEMODE_N_VALUE(l_throttle_per_port)
.set_MRW_DRAM_CLOCK_THROTTLE_M(l_throttle_denominator)
.set_MIN_UTIL_VALUE(mss::power_thermal::MIN_UTIL),
"MRW safemode attribute (N=%d, M=%d) has less util than the min util allowed (%d centi percent)",
l_throttle_per_port, l_throttle_denominator, mss::power_thermal::MIN_UTIL);
}

//Restore runtime_throttles from safemode setting
//Decode and set power curve attributes at the same time
for (const auto& l_mcs : i_targets )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@

///
/// @file p9_mss_utils_to_throttle.C
/// @brief Sets throttles
/// @brief Sets throttles and power attributes for a given utilization value
/// TMGT will call this procedure to set the N address operations (commands)
/// allowed within a window of M DRAM clocks given the minimum dram data bus utilization.
////If input utilization is zero, then safemode values from MRW will be used
///

// *HWP HWP Owner: Andre A. Marin <aamarin@us.ibm.com>
Expand Down Expand Up @@ -72,6 +73,7 @@ extern "C"
FAPI_INF("Entering p9_mss_utils_to_throttle");

std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCA> > l_exceeded_power;
bool l_util_error = false;

for( const auto& l_mcs : i_targets )
{
Expand All @@ -83,6 +85,8 @@ extern "C"
uint32_t l_input_databus_util [mss::PORTS_PER_MCS] = {};
uint32_t l_max_databus_util = {};
uint32_t l_dram_clocks = 0;
uint16_t l_safemode_throttle_per_port = 0;
double l_calc_util_safemode = 0;

uint16_t l_n_port[mss::PORTS_PER_MCS] = {};
uint16_t l_n_slot[mss::PORTS_PER_MCS] = {};
Expand All @@ -107,11 +111,45 @@ extern "C"
continue;
}

//Make sure 0 < input_utilization <= max_utilization
const uint32_t l_databus_util = ( l_input_databus_util[l_port_num] != 0) ?
// If input utilization is zero, use mrw safemode throttle values for utilization
bool l_safemode = false;

if (l_input_databus_util[l_port_num] == 0)
{
FAPI_TRY(mss::mrw_safemode_mem_throttled_n_commands_per_port(l_safemode_throttle_per_port),
"Error in getting safemode throttles" );
FAPI_TRY( mss::power_thermal::calc_util_from_throttles(l_safemode_throttle_per_port, l_dram_clocks,
l_calc_util_safemode),
"%s Error calculating utilization from safemode throttle %d and mem clocks %d",
mss::c_str(l_mca),
l_safemode_throttle_per_port,
l_dram_clocks);
FAPI_INF( "%s Safemode throttles being used since input util is zero: Using N=%d, Utilization %f",
mss::c_str(l_mca),
l_safemode_throttle_per_port,
l_calc_util_safemode);
l_safemode = true;
l_input_databus_util[l_port_num] = l_calc_util_safemode;
}

//Make sure MIN_UTIL <= input_utilization <= max_utilization
const uint32_t l_databus_util = ( l_input_databus_util[l_port_num] >= mss::power_thermal::MIN_UTIL) ?
std::min(l_input_databus_util[l_port_num], l_max_databus_util)
: mss::power_thermal::MIN_UTIL;

// Error if utilization is less than MIN_UTIL
// Don't exit, let HWP finish and return error at end
if (l_input_databus_util[l_port_num] < mss::power_thermal::MIN_UTIL)
{
FAPI_ASSERT_NOEXIT( false,
fapi2::MSS_MIN_UTILIZATION_ERROR()
.set_INPUT_UTIL_VALUE(l_input_databus_util[l_port_num])
.set_MIN_UTIL_VALUE(mss::power_thermal::MIN_UTIL),
"%s Input utilization (%d) less than minimum utilization allowed (%d)",
mss::c_str(l_mca), l_input_databus_util[l_port_num], mss::power_thermal::MIN_UTIL);
l_util_error = true;
}

//Make a throttle object in order to calculate the port power
fapi2::ReturnCode l_rc;

Expand All @@ -132,8 +170,8 @@ extern "C"
l_dram_clocks,
l_throttle.iv_calc_port_maxpower);

l_n_slot[l_port_num] = l_throttle.iv_n_slot;
l_n_port[l_port_num] = l_throttle.iv_n_port;
l_n_slot[l_port_num] = (l_safemode) ? l_safemode_throttle_per_port : l_throttle.iv_n_slot;
l_n_port[l_port_num] = (l_safemode) ? l_safemode_throttle_per_port : l_throttle.iv_n_port;
l_max_power[l_port_num] = l_throttle.iv_calc_port_maxpower;
}// end for

Expand All @@ -152,6 +190,12 @@ extern "C"
// Note that we don't do anything with any MCA that exceed the power limit here, as we don't have an input power limit to go from
FAPI_TRY( mss::power_thermal::equalize_throttles (i_targets, mss::throttle_type::POWER, l_exceeded_power));

// Return a failing RC code if we had any input utilization values less than MIN_UTIL
if (l_util_error)
{
fapi2::current_err = fapi2::FAPI2_RC_FALSE;
}

fapi_try_exit:
return fapi2::current_err;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* Contributors Listed Below - COPYRIGHT 2015,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand All @@ -30,8 +30,8 @@
/// allowed within a window of M DRAM clocks given the minimum dram data bus utilization.
///

// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre A. Marin <aamarin@us.ibm.com>
// *HWP HWP Owner: Andre A. Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Michael Pardeik <pardeik@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB
Expand Down

0 comments on commit df43ad6

Please sign in to comment.