summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Stermole <stermole@us.ibm.com>2019-12-04 11:33:19 -0500
committerDaniel M Crowell <dcrowell@us.ibm.com>2020-01-29 15:04:49 -0600
commita69715d78e44ca4d69009bdd829a8ed778bcd845 (patch)
treec64073452836a61f5c17e5a7eaed0cae431e824e
parent5318cf7e4a01aaca4663fbb04c2ef3dd10277bfc (diff)
downloadtalos-hostboot-a69715d78e44ca4d69009bdd829a8ed778bcd845.tar.gz
talos-hostboot-a69715d78e44ca4d69009bdd829a8ed778bcd845.zip
Add p9a_mss_utils_to_throttle
Also move some shared code into gen_throttle.H Change-Id: I74ada8a0ee99db511813e04a58f434d779a90930 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/88093 Reviewed-by: Mark Pizzutillo <mark.pizzutillo@ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Michael D Pardeik <pardeik@us.ibm.com> Reviewed-by: Jennifer A Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/88121 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M Crowell <dcrowell@us.ibm.com>
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C85
-rw-r--r--src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.C117
-rw-r--r--src/import/generic/memory/lib/utils/power_thermal/gen_throttle.H85
3 files changed, 225 insertions, 62 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
index 8efba3f4b..01bd44749 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_utils_to_throttle.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2019 */
+/* Contributors Listed Below - COPYRIGHT 2015,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -72,6 +72,8 @@ extern "C"
///
fapi2::ReturnCode p9_mss_utils_to_throttle( const std::vector< fapi2::Target<TARGET_TYPE_MCS> >& i_targets )
{
+ constexpr uint64_t l_min_util = mss::power_thermal::throttle_traits<mss::mc_type::NIMBUS>::MIN_UTIL;
+
FAPI_INF("Entering p9_mss_utils_to_throttle");
std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCA> > l_exceeded_power;
@@ -88,20 +90,24 @@ extern "C"
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;
+ uint32_t l_calc_util = 0;
uint16_t l_n_port[mss::PORTS_PER_MCS] = {};
uint16_t l_n_slot[mss::PORTS_PER_MCS] = {};
uint32_t l_max_power[mss::PORTS_PER_MCS] = {};
- FAPI_TRY( mss::mrw_mem_m_dram_clocks(l_dram_clocks) );
+ FAPI_TRY(mss::mrw_mem_m_dram_clocks(l_dram_clocks) );
//Util attribute set by OCC
- FAPI_TRY( mss::databus_util(l_mcs, l_input_databus_util) );
- FAPI_TRY( mss::mrw_max_dram_databus_util(l_max_databus_util));
+ FAPI_TRY(mss::databus_util(l_mcs, l_input_databus_util) );
+ FAPI_TRY(mss::mrw_max_dram_databus_util(l_max_databus_util));
+ FAPI_TRY(mss::mrw_safemode_mem_throttled_n_commands_per_port(l_safemode_throttle_per_port));
for( const auto& l_mca : mss::find_targets<TARGET_TYPE_MCA>(l_mcs) )
{
+ fapi2::ReturnCode l_rc;
+ bool l_safemode = false;
+
FAPI_INF("Input databus utilization for %s is %d",
mss::c_str(l_mca),
l_input_databus_util[mss::index(l_mca)]);
@@ -114,58 +120,31 @@ extern "C"
}
// 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;
- }
-
- using TT = mss::power_thermal::throttle_traits<>;
- const uint64_t l_min_util = TT::MIN_UTIL;
- //Make sure MIN_UTIL <= input_utilization <= max_utilization
- const uint32_t l_databus_util = ( l_input_databus_util[l_port_num] >= l_min_util) ?
- std::min(l_input_databus_util[l_port_num], l_max_databus_util)
- : l_min_util;
+ // else make sure we're within our maximum utilization limit
+ FAPI_TRY(mss::power_thermal::calc_utilization<mss::mc_type::NIMBUS>(l_mca,
+ l_input_databus_util[l_port_num],
+ l_dram_clocks,
+ l_safemode_throttle_per_port,
+ l_max_databus_util,
+ l_calc_util,
+ l_util_error,
+ l_safemode));
// 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] < l_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(l_min_util),
- "%s Input utilization (%d) less than minimum utilization allowed (%d)",
- mss::c_str(l_mca), l_input_databus_util[l_port_num], l_min_util);
- l_util_error = true;
- }
-
- //Make a throttle object in order to calculate the port power
- fapi2::ReturnCode l_rc;
-
- mss::power_thermal::throttle<> l_throttle (l_mca, l_rc);
- FAPI_TRY(l_rc, "Error calculating mss::power_thermal::throttle constructor in p9_mss_utils_to_throttles");
+ FAPI_ASSERT_NOEXIT(!l_util_error,
+ fapi2::MSS_MIN_UTILIZATION_ERROR()
+ .set_INPUT_UTIL_VALUE(l_input_databus_util[l_port_num])
+ .set_MIN_UTIL_VALUE(l_min_util),
+ "%s Input utilization (%d) less than minimum utilization allowed (%d)",
+ mss::c_str(l_mca), l_input_databus_util[l_port_num], l_min_util);
- FAPI_INF( "%s MRW dram clock window: %d, databus utilization: %d",
- mss::c_str(l_mca),
- l_dram_clocks,
- l_databus_util);
+ // Make a throttle object in order to calculate the port power
+ mss::power_thermal::throttle<mss::mc_type::NIMBUS> l_throttle (l_mca, l_rc);
+ FAPI_TRY(l_rc, "%s Error calculating mss::power_thermal::throttle constructor in p9_mss_utils_to_throttles",
+ mss::c_str(l_mca));
- FAPI_TRY( l_throttle.calc_slots_and_power(l_databus_util));
+ FAPI_TRY( l_throttle.calc_slots_and_power(l_calc_util));
FAPI_INF( "%s Calculated N commands per port %d, per slot %d, commands per dram clock window %d, maxpower is %d",
mss::c_str(l_mca),
@@ -197,7 +176,7 @@ extern "C"
// 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;
+ fapi2::current_err = fapi2::RC_MSS_MIN_UTILIZATION_ERROR;
}
fapi_try_exit:
diff --git a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.C b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.C
index 0666a8772..7d8afb81f 100644
--- a/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.C
+++ b/src/import/chips/p9a/procedures/hwp/memory/p9a_mss_utils_to_throttle.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -38,10 +38,16 @@
// *HWP Consumed by: FSP:HB
#include <p9a_mss_utils_to_throttle.H>
+#include <lib/shared/exp_defaults.H>
+#include <lib/shared/exp_consts.H>
+#include <mss_explorer_attribute_getters.H>
+#include <lib/power_thermal/exp_throttle.H>
// fapi2
#include <fapi2.H>
+extern "C"
+{
///
/// @brief Determines throttle and power values for a given port databus utilization.
/// @param[in] i_targets vector of OCMB_CHIPs to set throttle and power attributes on
@@ -49,11 +55,106 @@
/// @note ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT will be set to worst case of all slots passed in
/// @note input ATTR_MSS_DATABUS_UTIL and ATTR_MSS_MEM_WATT_TARGET
/// @note output ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_PORT, and ATTR_MSS_PORT_MAXPOWER
-/// @note Does not set runtime throttles or set registers to throttle values`
+/// @note Does not set runtime throttles or set registers to throttle values
///
-fapi2::ReturnCode p9a_mss_utils_to_throttle( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP> >&
- i_targets )
-{
- FAPI_INF("Entering p9a_mss_utils_to_throttle");
- return fapi2::FAPI2_RC_SUCCESS;
-}
+ fapi2::ReturnCode p9a_mss_utils_to_throttle(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>>& i_targets)
+ {
+ constexpr uint64_t l_min_util = mss::power_thermal::throttle_traits<mss::mc_type::EXPLORER>::MIN_UTIL;
+
+ FAPI_INF("Entering p9a_mss_utils_to_throttle");
+
+ std::vector<fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>> l_exceeded_power;
+ bool l_util_error = false;
+
+ for (const auto& l_ocmb : i_targets)
+ {
+ if (mss::count_dimm(l_ocmb) == 0)
+ {
+ FAPI_INF("Skipping %s because it has no DIMM targets", mss::c_str(l_ocmb));
+ continue;
+ }
+
+ uint32_t l_max_databus_util = 0;
+ uint32_t l_dram_clocks = 0;
+ uint32_t l_safemode_util = 0;
+ uint32_t l_safemode_throttle_per_port = 0;
+ uint32_t l_calc_util = 0;
+
+ FAPI_TRY(mss::attr::get_mrw_mem_m_dram_clocks(l_dram_clocks));
+ FAPI_TRY(mss::attr::get_mrw_max_dram_databus_util(l_max_databus_util));
+ FAPI_TRY(mss::attr::get_mrw_safemode_dram_databus_util(l_safemode_util));
+
+ l_safemode_throttle_per_port = mss::power_thermal::calc_n_from_dram_util(
+ (l_safemode_util / mss::power_thermal::throttle_const::PERCENT_CONVERSION),
+ l_dram_clocks);
+
+ for(const auto& l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(l_ocmb))
+ {
+ fapi2::ReturnCode l_rc;
+ uint32_t l_input_databus_util = 0;
+ bool l_safemode = false;
+
+ // Util attribute set by OCC
+ FAPI_TRY( mss::attr::get_databus_util(l_port, l_input_databus_util) );
+
+ FAPI_INF("Input databus utilization for %s is %d",
+ mss::c_str(l_port),
+ l_input_databus_util);
+
+ // If input utilization is zero, use mrw safemode throttle values for utilization
+ // else make sure we're within our maximum utilization limit
+ FAPI_TRY(mss::power_thermal::calc_utilization<mss::mc_type::EXPLORER>(l_port,
+ l_input_databus_util,
+ l_dram_clocks,
+ l_safemode_throttle_per_port,
+ l_max_databus_util,
+ l_calc_util,
+ l_util_error,
+ l_safemode));
+
+ // Error if utilization is less than MIN_UTIL
+ // Don't exit, let HWP finish and return error at end
+ FAPI_ASSERT_NOEXIT( !l_util_error,
+ fapi2::MSS_MIN_UTILIZATION_ERROR()
+ .set_INPUT_UTIL_VALUE(l_input_databus_util)
+ .set_MIN_UTIL_VALUE(l_min_util),
+ "%s Input utilization (%d) less than minimum utilization allowed (%d)",
+ mss::c_str(l_port), l_input_databus_util, l_min_util);
+
+ // Make a throttle object in order to calculate the port power
+ mss::power_thermal::throttle<mss::mc_type::EXPLORER> l_throttle(l_port, l_rc);
+ FAPI_TRY(l_rc, "%s Error calculating mss::power_thermal::throttle constructor in p9a_mss_utils_to_throttles",
+ mss::c_str(l_port));
+
+ FAPI_TRY(l_throttle.calc_slots_and_power(l_calc_util));
+
+ FAPI_INF( "%s Calculated N commands per port %d, per slot %d, commands per dram clock window %d, maxpower is %d",
+ mss::c_str(l_port),
+ l_throttle.iv_n_port,
+ l_throttle.iv_n_slot,
+ l_dram_clocks,
+ l_throttle.iv_calc_port_maxpower);
+
+ FAPI_TRY(mss::attr::set_port_maxpower(l_port, l_throttle.iv_calc_port_maxpower));
+ FAPI_TRY(mss::attr::set_mem_throttled_n_commands_per_slot(l_port,
+ (l_safemode) ? l_safemode_throttle_per_port : l_throttle.iv_n_slot));
+ FAPI_TRY(mss::attr::set_mem_throttled_n_commands_per_port(l_port,
+ (l_safemode) ? l_safemode_throttle_per_port : l_throttle.iv_n_port));
+ } // ports
+ } // ocmbs
+
+ // Equalize throttles to prevent variable performance
+ // Note that we don't do anything with any port 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<mss::mc_type::EXPLORER>(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::RC_MSS_MIN_UTILIZATION_ERROR;
+ }
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+}// extern C
diff --git a/src/import/generic/memory/lib/utils/power_thermal/gen_throttle.H b/src/import/generic/memory/lib/utils/power_thermal/gen_throttle.H
index e8b4f0f61..c65ffb637 100644
--- a/src/import/generic/memory/lib/utils/power_thermal/gen_throttle.H
+++ b/src/import/generic/memory/lib/utils/power_thermal/gen_throttle.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2019 */
+/* Contributors Listed Below - COPYRIGHT 2019,2020 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -69,6 +69,29 @@ enum throttle_const : size_t
};
///
+/// @brief Calculate the N throttle for a given dram data bus utilization value
+///
+/// @tparam T1 template parameter, type of input to be processed
+/// @tparam T2 template parameter, type of input to be processed
+/// @param[in] i_dram_util dram data bus utilization value
+/// @param[in] i_throttle_m M throttle value in N/M throttling
+///
+/// @return int32_t calculated N throttle value
+///
+template<typename T1, typename T2>
+inline uint32_t calc_n_from_dram_util(const T1 i_dram_util, const T2 i_throttle_m)
+{
+ constexpr uint64_t CONVERT_ADDR_UTIL_TO_DATA_UTIL = 4;
+
+ return (static_cast<int>(static_cast<double>(i_dram_util)
+ * (i_throttle_m)
+ / (CONVERT_ADDR_UTIL_TO_DATA_UTIL)
+ / (PERCENT_CONVERSION)
+ )
+ );
+}
+
+///
/// @brief Calculate N (address operations) allowed within a window of M DRAM clocks
/// @param[in] i_databus_util databus utilization percentage (e.g. 5% = 5)
/// @param[in] i_num_dram_clocks window of M DRAM clocks
@@ -1098,6 +1121,66 @@ fapi_try_exit:
///
+/// @brief set the safemode throttle register
+/// @tparam MC mss::mc_type
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT portTraits port traits for the given MC target type
+/// @param[in] i_target the port target
+/// @return fapi2::FAPI2_RC_SUCCESS if ok
+/// @note sets FARB4Q
+/// @note used to set throttle window (N throttles / M clocks)
+///
+template<mss::mc_type MC = DEFAULT_MC_TYPE, fapi2::TargetType T, typename TT = throttle_traits<MC>>
+fapi2::ReturnCode calc_utilization(const fapi2::Target<T>& i_target,
+ const uint32_t i_input_databus_util,
+ const uint32_t i_dram_clocks,
+ const uint16_t i_safemode_throttle_per_port,
+ const uint32_t i_max_databus_util,
+ uint32_t& o_util,
+ bool& o_util_error,
+ bool& o_safemode)
+{
+ constexpr uint64_t l_min_util = TT::MIN_UTIL;
+
+ o_util = i_input_databus_util;
+ o_safemode = false;
+
+ // Use MRW safemode throttle values if input utilization is zero
+ if (i_input_databus_util == 0)
+ {
+ FAPI_TRY(calc_util_from_throttles<MC>(i_safemode_throttle_per_port,
+ i_dram_clocks,
+ o_util),
+ "%s Error calculating utilization from safemode throttle %d and mem clocks %d",
+ mss::c_str(i_target),
+ i_safemode_throttle_per_port,
+ i_dram_clocks);
+ FAPI_INF("%s Safemode throttles being used since input util is zero: Using N=%d, Utilization %f",
+ mss::c_str(i_target),
+ i_safemode_throttle_per_port,
+ o_util);
+ o_safemode = true;
+ }
+ else if (i_input_databus_util < l_min_util)
+ {
+ o_util_error = true;
+ }
+
+ // Make sure MIN_UTIL <= input_utilization <= max_utilization
+ o_util = (o_util >= l_min_util) ? std::min(o_util, i_max_databus_util) : l_min_util;
+
+ FAPI_INF("%s MRW dram clock window: %d, databus utilization: %d",
+ mss::c_str(i_target),
+ i_dram_clocks,
+ o_util);
+
+ return fapi2::FAPI2_RC_SUCCESS;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Equalize the throttles and estimated power at those throttle levels
/// @tparam MC mss::mc_type
/// @tparam T the fapi2 MC target type of the target
OpenPOWER on IntegriCloud