Skip to content

Commit 744d197

Browse files
walking-machinekuba-moo
authored andcommitted
ice: add flag to distinguish reset from .ndo_bpf in XDP rings config
Commit 6624e78 ("ice: split ice_vsi_setup into smaller functions") has placed ice_vsi_free_q_vectors() after ice_destroy_xdp_rings() in the rebuild process. The behaviour of the XDP rings config functions is context-dependent, so the change of order has led to ice_destroy_xdp_rings() doing additional work and removing XDP prog, when it was supposed to be preserved. Also, dependency on the PF state reset flags creates an additional, fortunately less common problem: * PFR is requested e.g. by tx_timeout handler * .ndo_bpf() is asked to delete the program, calls ice_destroy_xdp_rings(), but reset flag is set, so rings are destroyed without deleting the program * ice_vsi_rebuild tries to delete non-existent XDP rings, because the program is still on the VSI * system crashes With a similar race, when requested to attach a program, ice_prepare_xdp_rings() can actually skip setting the program in the VSI and nevertheless report success. Instead of reverting to the old order of function calls, add an enum argument to both ice_prepare_xdp_rings() and ice_destroy_xdp_rings() in order to distinguish between calls from rebuild and .ndo_bpf(). Fixes: efc2214 ("ice: Add support for XDP") Reviewed-by: Igor Bagnucki <[email protected]> Signed-off-by: Larysa Zaremba <[email protected]> Reviewed-by: Simon Horman <[email protected]> Tested-by: Chandan Kumar Rout <[email protected]> Signed-off-by: Jacob Keller <[email protected]> Link: https://lore.kernel.org/r/20240603-net-2024-05-30-intel-net-fixes-v2-4-e3563aa89b0c@intel.com Signed-off-by: Jakub Kicinski <[email protected]>
1 parent adbf5a4 commit 744d197

File tree

3 files changed

+24
-14
lines changed

3 files changed

+24
-14
lines changed

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -930,9 +930,16 @@ int ice_down(struct ice_vsi *vsi);
930930
int ice_down_up(struct ice_vsi *vsi);
931931
int ice_vsi_cfg_lan(struct ice_vsi *vsi);
932932
struct ice_vsi *ice_lb_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi);
933+
934+
enum ice_xdp_cfg {
935+
ICE_XDP_CFG_FULL, /* Fully apply new config in .ndo_bpf() */
936+
ICE_XDP_CFG_PART, /* Save/use part of config in VSI rebuild */
937+
};
938+
933939
int ice_vsi_determine_xdp_res(struct ice_vsi *vsi);
934-
int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog);
935-
int ice_destroy_xdp_rings(struct ice_vsi *vsi);
940+
int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
941+
enum ice_xdp_cfg cfg_type);
942+
int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type);
936943
int
937944
ice_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
938945
u32 flags);

drivers/net/ethernet/intel/ice/ice_lib.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2285,7 +2285,8 @@ static int ice_vsi_cfg_def(struct ice_vsi *vsi)
22852285
ret = ice_vsi_determine_xdp_res(vsi);
22862286
if (ret)
22872287
goto unroll_vector_base;
2288-
ret = ice_prepare_xdp_rings(vsi, vsi->xdp_prog);
2288+
ret = ice_prepare_xdp_rings(vsi, vsi->xdp_prog,
2289+
ICE_XDP_CFG_PART);
22892290
if (ret)
22902291
goto unroll_vector_base;
22912292
}
@@ -2429,7 +2430,7 @@ void ice_vsi_decfg(struct ice_vsi *vsi)
24292430
/* return value check can be skipped here, it always returns
24302431
* 0 if reset is in progress
24312432
*/
2432-
ice_destroy_xdp_rings(vsi);
2433+
ice_destroy_xdp_rings(vsi, ICE_XDP_CFG_PART);
24332434

24342435
ice_vsi_clear_rings(vsi);
24352436
ice_vsi_free_q_vectors(vsi);

drivers/net/ethernet/intel/ice/ice_main.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,10 +2711,12 @@ static void ice_vsi_assign_bpf_prog(struct ice_vsi *vsi, struct bpf_prog *prog)
27112711
* ice_prepare_xdp_rings - Allocate, configure and setup Tx rings for XDP
27122712
* @vsi: VSI to bring up Tx rings used by XDP
27132713
* @prog: bpf program that will be assigned to VSI
2714+
* @cfg_type: create from scratch or restore the existing configuration
27142715
*
27152716
* Return 0 on success and negative value on error
27162717
*/
2717-
int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
2718+
int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
2719+
enum ice_xdp_cfg cfg_type)
27182720
{
27192721
u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
27202722
int xdp_rings_rem = vsi->num_xdp_txq;
@@ -2790,7 +2792,7 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
27902792
* taken into account at the end of ice_vsi_rebuild, where
27912793
* ice_cfg_vsi_lan is being called
27922794
*/
2793-
if (ice_is_reset_in_progress(pf->state))
2795+
if (cfg_type == ICE_XDP_CFG_PART)
27942796
return 0;
27952797

27962798
/* tell the Tx scheduler that right now we have
@@ -2842,22 +2844,21 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
28422844
/**
28432845
* ice_destroy_xdp_rings - undo the configuration made by ice_prepare_xdp_rings
28442846
* @vsi: VSI to remove XDP rings
2847+
* @cfg_type: disable XDP permanently or allow it to be restored later
28452848
*
28462849
* Detach XDP rings from irq vectors, clean up the PF bitmap and free
28472850
* resources
28482851
*/
2849-
int ice_destroy_xdp_rings(struct ice_vsi *vsi)
2852+
int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type)
28502853
{
28512854
u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
28522855
struct ice_pf *pf = vsi->back;
28532856
int i, v_idx;
28542857

28552858
/* q_vectors are freed in reset path so there's no point in detaching
2856-
* rings; in case of rebuild being triggered not from reset bits
2857-
* in pf->state won't be set, so additionally check first q_vector
2858-
* against NULL
2859+
* rings
28592860
*/
2860-
if (ice_is_reset_in_progress(pf->state) || !vsi->q_vectors[0])
2861+
if (cfg_type == ICE_XDP_CFG_PART)
28612862
goto free_qmap;
28622863

28632864
ice_for_each_q_vector(vsi, v_idx) {
@@ -2898,7 +2899,7 @@ int ice_destroy_xdp_rings(struct ice_vsi *vsi)
28982899
if (static_key_enabled(&ice_xdp_locking_key))
28992900
static_branch_dec(&ice_xdp_locking_key);
29002901

2901-
if (ice_is_reset_in_progress(pf->state) || !vsi->q_vectors[0])
2902+
if (cfg_type == ICE_XDP_CFG_PART)
29022903
return 0;
29032904

29042905
ice_vsi_assign_bpf_prog(vsi, NULL);
@@ -3009,7 +3010,8 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
30093010
if (xdp_ring_err) {
30103011
NL_SET_ERR_MSG_MOD(extack, "Not enough Tx resources for XDP");
30113012
} else {
3012-
xdp_ring_err = ice_prepare_xdp_rings(vsi, prog);
3013+
xdp_ring_err = ice_prepare_xdp_rings(vsi, prog,
3014+
ICE_XDP_CFG_FULL);
30133015
if (xdp_ring_err)
30143016
NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed");
30153017
}
@@ -3020,7 +3022,7 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
30203022
NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Rx resources failed");
30213023
} else if (ice_is_xdp_ena_vsi(vsi) && !prog) {
30223024
xdp_features_clear_redirect_target(vsi->netdev);
3023-
xdp_ring_err = ice_destroy_xdp_rings(vsi);
3025+
xdp_ring_err = ice_destroy_xdp_rings(vsi, ICE_XDP_CFG_FULL);
30243026
if (xdp_ring_err)
30253027
NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Tx resources failed");
30263028
/* reallocate Rx queues that were used for zero-copy */

0 commit comments

Comments
 (0)