Skip to content

Commit a005954

Browse files
committed
ice: fix Tx scheduler error handling in XDP callback
jira LE-4694 Rebuild_History Non-Buildable kernel-6.12.0-55.43.1.el10_0 commit-author Michal Kubiak <michal.kubiak@intel.com> commit 0153f36 When the XDP program is loaded, the XDP callback adds new Tx queues. This means that the callback must update the Tx scheduler with the new queue number. In the event of a Tx scheduler failure, the XDP callback should also fail and roll back any changes previously made for XDP preparation. The previous implementation had a bug that not all changes made by the XDP callback were rolled back. This caused the crash with the following call trace: [ +9.549584] ice 0000:ca:00.0: Failed VSI LAN queue config for XDP, error: -5 [ +0.382335] Oops: general protection fault, probably for non-canonical address 0x50a2250a90495525: 0000 [#1] SMP NOPTI [ +0.010710] CPU: 103 UID: 0 PID: 0 Comm: swapper/103 Not tainted 6.14.0-net-next-mar-31+ #14 PREEMPT(voluntary) [ +0.010175] Hardware name: Intel Corporation M50CYP2SBSTD/M50CYP2SBSTD, BIOS SE5C620.86B.01.01.0005.2202160810 02/16/2022 [ +0.010946] RIP: 0010:__ice_update_sample+0x39/0xe0 [ice] [...] [ +0.002715] Call Trace: [ +0.002452] <IRQ> [ +0.002021] ? __die_body.cold+0x19/0x29 [ +0.003922] ? die_addr+0x3c/0x60 [ +0.003319] ? exc_general_protection+0x17c/0x400 [ +0.004707] ? asm_exc_general_protection+0x26/0x30 [ +0.004879] ? __ice_update_sample+0x39/0xe0 [ice] [ +0.004835] ice_napi_poll+0x665/0x680 [ice] [ +0.004320] __napi_poll+0x28/0x190 [ +0.003500] net_rx_action+0x198/0x360 [ +0.003752] ? update_rq_clock+0x39/0x220 [ +0.004013] handle_softirqs+0xf1/0x340 [ +0.003840] ? sched_clock_cpu+0xf/0x1f0 [ +0.003925] __irq_exit_rcu+0xc2/0xe0 [ +0.003665] common_interrupt+0x85/0xa0 [ +0.003839] </IRQ> [ +0.002098] <TASK> [ +0.002106] asm_common_interrupt+0x26/0x40 [ +0.004184] RIP: 0010:cpuidle_enter_state+0xd3/0x690 Fix this by performing the missing unmapping of XDP queues from q_vectors and setting the XDP rings pointer back to NULL after all those queues are released. Also, add an immediate exit from the XDP callback in case of ring preparation failure. Fixes: efc2214 ("ice: Add support for XDP") Reviewed-by: Dawid Osuchowski <dawid.osuchowski@linux.intel.com> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Signed-off-by: Michal Kubiak <michal.kubiak@intel.com> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Reviewed-by: Simon Horman <horms@kernel.org> Tested-by: Jesse Brandeburg <jbrandeburg@cloudflare.com> Tested-by: Saritha Sanigani <sarithax.sanigani@intel.com> (A Contingent Worker at Intel) Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> (cherry picked from commit 0153f36) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent 0fbb7d0 commit a005954

File tree

1 file changed

+33
-14
lines changed

1 file changed

+33
-14
lines changed

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

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2772,6 +2772,27 @@ void ice_map_xdp_rings(struct ice_vsi *vsi)
27722772
}
27732773
}
27742774

2775+
/**
2776+
* ice_unmap_xdp_rings - Unmap XDP rings from interrupt vectors
2777+
* @vsi: the VSI with XDP rings being unmapped
2778+
*/
2779+
static void ice_unmap_xdp_rings(struct ice_vsi *vsi)
2780+
{
2781+
int v_idx;
2782+
2783+
ice_for_each_q_vector(vsi, v_idx) {
2784+
struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];
2785+
struct ice_tx_ring *ring;
2786+
2787+
ice_for_each_tx_ring(ring, q_vector->tx)
2788+
if (!ring->tx_buf || !ice_ring_is_xdp(ring))
2789+
break;
2790+
2791+
/* restore the value of last node prior to XDP setup */
2792+
q_vector->tx.tx_ring = ring;
2793+
}
2794+
}
2795+
27752796
/**
27762797
* ice_prepare_xdp_rings - Allocate, configure and setup Tx rings for XDP
27772798
* @vsi: VSI to bring up Tx rings used by XDP
@@ -2835,7 +2856,7 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
28352856
if (status) {
28362857
dev_err(dev, "Failed VSI LAN queue config for XDP, error: %d\n",
28372858
status);
2838-
goto clear_xdp_rings;
2859+
goto unmap_xdp_rings;
28392860
}
28402861

28412862
/* assign the prog only when it's not already present on VSI;
@@ -2851,6 +2872,8 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
28512872
ice_vsi_assign_bpf_prog(vsi, prog);
28522873

28532874
return 0;
2875+
unmap_xdp_rings:
2876+
ice_unmap_xdp_rings(vsi);
28542877
clear_xdp_rings:
28552878
ice_for_each_xdp_txq(vsi, i)
28562879
if (vsi->xdp_rings[i]) {
@@ -2867,6 +2890,8 @@ int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
28672890
mutex_unlock(&pf->avail_q_mutex);
28682891

28692892
devm_kfree(dev, vsi->xdp_rings);
2893+
vsi->xdp_rings = NULL;
2894+
28702895
return -ENOMEM;
28712896
}
28722897

@@ -2882,25 +2907,15 @@ int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type)
28822907
{
28832908
u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
28842909
struct ice_pf *pf = vsi->back;
2885-
int i, v_idx;
2910+
int i;
28862911

28872912
/* q_vectors are freed in reset path so there's no point in detaching
28882913
* rings
28892914
*/
28902915
if (cfg_type == ICE_XDP_CFG_PART)
28912916
goto free_qmap;
28922917

2893-
ice_for_each_q_vector(vsi, v_idx) {
2894-
struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];
2895-
struct ice_tx_ring *ring;
2896-
2897-
ice_for_each_tx_ring(ring, q_vector->tx)
2898-
if (!ring->tx_buf || !ice_ring_is_xdp(ring))
2899-
break;
2900-
2901-
/* restore the value of last node prior to XDP setup */
2902-
q_vector->tx.tx_ring = ring;
2903-
}
2918+
ice_unmap_xdp_rings(vsi);
29042919

29052920
free_qmap:
29062921
mutex_lock(&pf->avail_q_mutex);
@@ -3045,11 +3060,14 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
30453060
xdp_ring_err = ice_vsi_determine_xdp_res(vsi);
30463061
if (xdp_ring_err) {
30473062
NL_SET_ERR_MSG_MOD(extack, "Not enough Tx resources for XDP");
3063+
goto resume_if;
30483064
} else {
30493065
xdp_ring_err = ice_prepare_xdp_rings(vsi, prog,
30503066
ICE_XDP_CFG_FULL);
3051-
if (xdp_ring_err)
3067+
if (xdp_ring_err) {
30523068
NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed");
3069+
goto resume_if;
3070+
}
30533071
}
30543072
xdp_features_set_redirect_target(vsi->netdev, true);
30553073
/* reallocate Rx queues that are used for zero-copy */
@@ -3067,6 +3085,7 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog,
30673085
NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Rx resources failed");
30683086
}
30693087

3088+
resume_if:
30703089
if (if_running)
30713090
ret = ice_up(vsi);
30723091

0 commit comments

Comments
 (0)