Skip to content

Commit

Permalink
bnx2x: Change DCB context handling
Browse files Browse the repository at this point in the history
After notification that DCBX configuration has ended arrived to the driver,
the driver configured the FW/HW in sleepless context.
As a result, it was possible to reach a race (mostly with CNIC registration)
in which the configuration will return a timeout, failing to set the DCBX
results correctly.

This patch moves the configuration following the DCBX end into the slowpath
RTNL task (i.e., sleepless context protected by the RTNL lock), allowing the
configuration to cope with such races.

Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Dmitry Kravkov authored and David S. Miller committed Aug 20, 2013
1 parent 9156b30 commit 07b4eb3
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 8 deletions.
2 changes: 2 additions & 0 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,8 @@ enum {
BNX2X_SP_RTNL_VFPF_CHANNEL_DOWN,
BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
BNX2X_SP_RTNL_HYPERVISOR_VLAN,
BNX2X_SP_RTNL_TX_STOP,
BNX2X_SP_RTNL_TX_RESUME,
};

struct bnx2x_prev_path_list {
Expand Down
40 changes: 32 additions & 8 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@
#include "bnx2x_dcb.h"

/* forward declarations of dcbx related functions */
static int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp);
static void bnx2x_pfc_set_pfc(struct bnx2x *bp);
static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp);
static int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp);
static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp,
u32 *set_configuration_ets_pg,
u32 *pri_pg_tbl);
Expand Down Expand Up @@ -425,30 +423,52 @@ static void bnx2x_pfc_set_pfc(struct bnx2x *bp)
bnx2x_pfc_clear(bp);
}

static int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp)
int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp)
{
struct bnx2x_func_state_params func_params = {NULL};
int rc;

func_params.f_obj = &bp->func_obj;
func_params.cmd = BNX2X_F_CMD_TX_STOP;

__set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags);
__set_bit(RAMROD_RETRY, &func_params.ramrod_flags);

DP(BNX2X_MSG_DCB, "STOP TRAFFIC\n");
return bnx2x_func_state_change(bp, &func_params);

rc = bnx2x_func_state_change(bp, &func_params);
if (rc) {
BNX2X_ERR("Unable to hold traffic for HW configuration\n");
bnx2x_panic();
}

return rc;
}

static int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp)
int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp)
{
struct bnx2x_func_state_params func_params = {NULL};
struct bnx2x_func_tx_start_params *tx_params =
&func_params.params.tx_start;
int rc;

func_params.f_obj = &bp->func_obj;
func_params.cmd = BNX2X_F_CMD_TX_START;

__set_bit(RAMROD_COMP_WAIT, &func_params.ramrod_flags);
__set_bit(RAMROD_RETRY, &func_params.ramrod_flags);

bnx2x_dcbx_fw_struct(bp, tx_params);

DP(BNX2X_MSG_DCB, "START TRAFFIC\n");
return bnx2x_func_state_change(bp, &func_params);

rc = bnx2x_func_state_change(bp, &func_params);
if (rc) {
BNX2X_ERR("Unable to resume traffic after HW configuration\n");
bnx2x_panic();
}

return rc;
}

static void bnx2x_dcbx_2cos_limit_update_ets_config(struct bnx2x *bp)
Expand Down Expand Up @@ -744,7 +764,9 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
if (IS_MF(bp))
bnx2x_link_sync_notify(bp);

bnx2x_dcbx_stop_hw_tx(bp);
set_bit(BNX2X_SP_RTNL_TX_STOP, &bp->sp_rtnl_state);

schedule_delayed_work(&bp->sp_rtnl_task, 0);

return;
}
Expand All @@ -757,7 +779,9 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
/* ets may affect cmng configuration: reinit it in hw */
bnx2x_set_local_cmng(bp);

bnx2x_dcbx_resume_hw_tx(bp);
set_bit(BNX2X_SP_RTNL_TX_RESUME, &bp->sp_rtnl_state);

schedule_delayed_work(&bp->sp_rtnl_task, 0);

return;
case BNX2X_DCBX_STATE_TX_RELEASED:
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,7 @@ extern const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops;
int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall);
#endif /* BCM_DCBNL */

int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp);
int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp);

#endif /* BNX2X_DCB_H */
6 changes: 6 additions & 0 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9655,6 +9655,12 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work)
&bp->sp_rtnl_state))
bnx2x_pf_set_vfs_vlan(bp);

if (test_and_clear_bit(BNX2X_SP_RTNL_TX_STOP, &bp->sp_rtnl_state))
bnx2x_dcbx_stop_hw_tx(bp);

if (test_and_clear_bit(BNX2X_SP_RTNL_TX_RESUME, &bp->sp_rtnl_state))
bnx2x_dcbx_resume_hw_tx(bp);

/* work which needs rtnl lock not-taken (as it takes the lock itself and
* can be called from other contexts as well)
*/
Expand Down

0 comments on commit 07b4eb3

Please sign in to comment.