i40e: reduce stack usage in i40e_set_fc
The functions i40e_aq_get_phy_abilities_resp() and i40e_set_fc() both
have giant structure on the stack, which makes each one use stack frames
larger than 500 bytes.
As clang decides one function into the other, we get a warning for
exceeding the frame size limit on 32-bit architectures:
drivers/net/ethernet/intel/i40e/i40e_common.c:1654:23: error: stack frame size of 1116 bytes in function 'i40e_set_fc' [-Werror,-Wframe-larger-than=]
When building with gcc, the inlining does not happen, but i40e_set_fc()
calls i40e_aq_get_phy_abilities_resp() anyway, so they add up on the
kernel stack just as much.
The parts that actually use large stacks don't overlap, so make sure
each one is a separate function, and mark them as noinline_for_stack to
prevent the compilers from combining them again.
Fixes: 0a862b43ac
("i40e/i40evf: Add module_types and update_link_info")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
c76c992525
commit
33b165684a
@ -1643,25 +1643,15 @@ enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_set_fc
|
||||
* @hw: pointer to the hw struct
|
||||
* @aq_failures: buffer to return AdminQ failure information
|
||||
* @atomic_restart: whether to enable atomic link restart
|
||||
*
|
||||
* Set the requested flow control mode using set_phy_config.
|
||||
**/
|
||||
enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
|
||||
bool atomic_restart)
|
||||
static noinline_for_stack enum i40e_status_code
|
||||
i40e_set_fc_status(struct i40e_hw *hw,
|
||||
struct i40e_aq_get_phy_abilities_resp *abilities,
|
||||
bool atomic_restart)
|
||||
{
|
||||
enum i40e_fc_mode fc_mode = hw->fc.requested_mode;
|
||||
struct i40e_aq_get_phy_abilities_resp abilities;
|
||||
struct i40e_aq_set_phy_config config;
|
||||
enum i40e_status_code status;
|
||||
enum i40e_fc_mode fc_mode = hw->fc.requested_mode;
|
||||
u8 pause_mask = 0x0;
|
||||
|
||||
*aq_failures = 0x0;
|
||||
|
||||
switch (fc_mode) {
|
||||
case I40E_FC_FULL:
|
||||
pause_mask |= I40E_AQ_PHY_FLAG_PAUSE_TX;
|
||||
@ -1677,6 +1667,48 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
|
||||
break;
|
||||
}
|
||||
|
||||
memset(&config, 0, sizeof(struct i40e_aq_set_phy_config));
|
||||
/* clear the old pause settings */
|
||||
config.abilities = abilities->abilities & ~(I40E_AQ_PHY_FLAG_PAUSE_TX) &
|
||||
~(I40E_AQ_PHY_FLAG_PAUSE_RX);
|
||||
/* set the new abilities */
|
||||
config.abilities |= pause_mask;
|
||||
/* If the abilities have changed, then set the new config */
|
||||
if (config.abilities == abilities->abilities)
|
||||
return 0;
|
||||
|
||||
/* Auto restart link so settings take effect */
|
||||
if (atomic_restart)
|
||||
config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
|
||||
/* Copy over all the old settings */
|
||||
config.phy_type = abilities->phy_type;
|
||||
config.phy_type_ext = abilities->phy_type_ext;
|
||||
config.link_speed = abilities->link_speed;
|
||||
config.eee_capability = abilities->eee_capability;
|
||||
config.eeer = abilities->eeer_val;
|
||||
config.low_power_ctrl = abilities->d3_lpan;
|
||||
config.fec_config = abilities->fec_cfg_curr_mod_ext_info &
|
||||
I40E_AQ_PHY_FEC_CONFIG_MASK;
|
||||
|
||||
return i40e_aq_set_phy_config(hw, &config, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_set_fc
|
||||
* @hw: pointer to the hw struct
|
||||
* @aq_failures: buffer to return AdminQ failure information
|
||||
* @atomic_restart: whether to enable atomic link restart
|
||||
*
|
||||
* Set the requested flow control mode using set_phy_config.
|
||||
**/
|
||||
enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
|
||||
bool atomic_restart)
|
||||
{
|
||||
struct i40e_aq_get_phy_abilities_resp abilities;
|
||||
enum i40e_status_code status;
|
||||
|
||||
*aq_failures = 0x0;
|
||||
|
||||
/* Get the current phy config */
|
||||
status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
|
||||
NULL);
|
||||
@ -1685,31 +1717,10 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
|
||||
return status;
|
||||
}
|
||||
|
||||
memset(&config, 0, sizeof(struct i40e_aq_set_phy_config));
|
||||
/* clear the old pause settings */
|
||||
config.abilities = abilities.abilities & ~(I40E_AQ_PHY_FLAG_PAUSE_TX) &
|
||||
~(I40E_AQ_PHY_FLAG_PAUSE_RX);
|
||||
/* set the new abilities */
|
||||
config.abilities |= pause_mask;
|
||||
/* If the abilities have changed, then set the new config */
|
||||
if (config.abilities != abilities.abilities) {
|
||||
/* Auto restart link so settings take effect */
|
||||
if (atomic_restart)
|
||||
config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
|
||||
/* Copy over all the old settings */
|
||||
config.phy_type = abilities.phy_type;
|
||||
config.phy_type_ext = abilities.phy_type_ext;
|
||||
config.link_speed = abilities.link_speed;
|
||||
config.eee_capability = abilities.eee_capability;
|
||||
config.eeer = abilities.eeer_val;
|
||||
config.low_power_ctrl = abilities.d3_lpan;
|
||||
config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
|
||||
I40E_AQ_PHY_FEC_CONFIG_MASK;
|
||||
status = i40e_aq_set_phy_config(hw, &config, NULL);
|
||||
status = i40e_set_fc_status(hw, &abilities, atomic_restart);
|
||||
if (status)
|
||||
*aq_failures |= I40E_SET_FC_AQ_FAIL_SET;
|
||||
|
||||
if (status)
|
||||
*aq_failures |= I40E_SET_FC_AQ_FAIL_SET;
|
||||
}
|
||||
/* Update the link info */
|
||||
status = i40e_update_link_info(hw);
|
||||
if (status) {
|
||||
@ -2537,7 +2548,7 @@ i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
|
||||
* i40e_updatelink_status - update status of the HW network link
|
||||
* @hw: pointer to the hw struct
|
||||
**/
|
||||
i40e_status i40e_update_link_info(struct i40e_hw *hw)
|
||||
noinline_for_stack i40e_status i40e_update_link_info(struct i40e_hw *hw)
|
||||
{
|
||||
struct i40e_aq_get_phy_abilities_resp abilities;
|
||||
i40e_status status = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user