From a69715d78e44ca4d69009bdd829a8ed778bcd845 Mon Sep 17 00:00:00 2001 From: Louis Stermole Date: Wed, 4 Dec 2019 11:33:19 -0500 Subject: 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 Tested-by: FSP CI Jenkins Tested-by: Jenkins Server Tested-by: Hostboot CI Tested-by: HWSV CI Reviewed-by: STEPHEN GLANCY Reviewed-by: Michael D Pardeik Reviewed-by: Jennifer A Stofer Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/88121 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Daniel M Crowell --- .../hwp/memory/p9_mss_utils_to_throttle.C | 85 ++++++--------- .../hwp/memory/p9a_mss_utils_to_throttle.C | 117 +++++++++++++++++++-- 2 files changed, 141 insertions(+), 61 deletions(-) (limited to 'src/import/chips') 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 >& i_targets ) { + constexpr uint64_t l_min_util = mss::power_thermal::throttle_traits::MIN_UTIL; + FAPI_INF("Entering p9_mss_utils_to_throttle"); std::vector< fapi2::Target > 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(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(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 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 +#include +#include +#include +#include // fapi2 #include +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 >& - 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>& i_targets) + { + constexpr uint64_t l_min_util = mss::power_thermal::throttle_traits::MIN_UTIL; + + FAPI_INF("Entering p9a_mss_utils_to_throttle"); + + std::vector> 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(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(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 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(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 -- cgit v1.2.1