]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/i40e-fix-vf-may-be-used-uninitialized-in-this-function-warning.patch
4.19-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.19 / i40e-fix-vf-may-be-used-uninitialized-in-this-function-warning.patch
1 From f37c4eac99c258111d414d31b740437e1925b8e8 Mon Sep 17 00:00:00 2001
2 From: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
3 Date: Wed, 13 Mar 2024 10:56:39 +0100
4 Subject: i40e: fix vf may be used uninitialized in this function warning
5
6 From: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
7
8 commit f37c4eac99c258111d414d31b740437e1925b8e8 upstream.
9
10 To fix the regression introduced by commit 52424f974bc5, which causes
11 servers hang in very hard to reproduce conditions with resets races.
12 Using two sources for the information is the root cause.
13 In this function before the fix bumping v didn't mean bumping vf
14 pointer. But the code used this variables interchangeably, so stale vf
15 could point to different/not intended vf.
16
17 Remove redundant "v" variable and iterate via single VF pointer across
18 whole function instead to guarantee VF pointer validity.
19
20 Fixes: 52424f974bc5 ("i40e: Fix VF hang when reset is triggered on another VF")
21 Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
22 Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
23 Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
24 Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
25 Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
26 Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
27 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28 ---
29 drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 34 +++++++++------------
30 1 file changed, 16 insertions(+), 18 deletions(-)
31
32 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
33 +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
34 @@ -1317,8 +1317,8 @@ bool i40e_reset_all_vfs(struct i40e_pf *
35 {
36 struct i40e_hw *hw = &pf->hw;
37 struct i40e_vf *vf;
38 - int i, v;
39 u32 reg;
40 + int i;
41
42 /* If we don't have any VFs, then there is nothing to reset */
43 if (!pf->num_alloc_vfs)
44 @@ -1329,11 +1329,10 @@ bool i40e_reset_all_vfs(struct i40e_pf *
45 return false;
46
47 /* Begin reset on all VFs at once */
48 - for (v = 0; v < pf->num_alloc_vfs; v++) {
49 - vf = &pf->vf[v];
50 + for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
51 /* If VF is being reset no need to trigger reset again */
52 if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
53 - i40e_trigger_vf_reset(&pf->vf[v], flr);
54 + i40e_trigger_vf_reset(vf, flr);
55 }
56
57 /* HW requires some time to make sure it can flush the FIFO for a VF
58 @@ -1342,14 +1341,13 @@ bool i40e_reset_all_vfs(struct i40e_pf *
59 * the VFs using a simple iterator that increments once that VF has
60 * finished resetting.
61 */
62 - for (i = 0, v = 0; i < 10 && v < pf->num_alloc_vfs; i++) {
63 + for (i = 0, vf = &pf->vf[0]; i < 10 && vf < &pf->vf[pf->num_alloc_vfs]; ++i) {
64 usleep_range(10000, 20000);
65
66 /* Check each VF in sequence, beginning with the VF to fail
67 * the previous check.
68 */
69 - while (v < pf->num_alloc_vfs) {
70 - vf = &pf->vf[v];
71 + while (vf < &pf->vf[pf->num_alloc_vfs]) {
72 if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) {
73 reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
74 if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK))
75 @@ -1359,7 +1357,7 @@ bool i40e_reset_all_vfs(struct i40e_pf *
76 /* If the current VF has finished resetting, move on
77 * to the next VF in sequence.
78 */
79 - v++;
80 + ++vf;
81 }
82 }
83
84 @@ -1369,39 +1367,39 @@ bool i40e_reset_all_vfs(struct i40e_pf *
85 /* Display a warning if at least one VF didn't manage to reset in
86 * time, but continue on with the operation.
87 */
88 - if (v < pf->num_alloc_vfs)
89 + if (vf < &pf->vf[pf->num_alloc_vfs])
90 dev_err(&pf->pdev->dev, "VF reset check timeout on VF %d\n",
91 - pf->vf[v].vf_id);
92 + vf->vf_id);
93 usleep_range(10000, 20000);
94
95 /* Begin disabling all the rings associated with VFs, but do not wait
96 * between each VF.
97 */
98 - for (v = 0; v < pf->num_alloc_vfs; v++) {
99 + for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
100 /* On initial reset, we don't have any queues to disable */
101 - if (pf->vf[v].lan_vsi_idx == 0)
102 + if (vf->lan_vsi_idx == 0)
103 continue;
104
105 /* If VF is reset in another thread just continue */
106 if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
107 continue;
108
109 - i40e_vsi_stop_rings_no_wait(pf->vsi[pf->vf[v].lan_vsi_idx]);
110 + i40e_vsi_stop_rings_no_wait(pf->vsi[vf->lan_vsi_idx]);
111 }
112
113 /* Now that we've notified HW to disable all of the VF rings, wait
114 * until they finish.
115 */
116 - for (v = 0; v < pf->num_alloc_vfs; v++) {
117 + for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
118 /* On initial reset, we don't have any queues to disable */
119 - if (pf->vf[v].lan_vsi_idx == 0)
120 + if (vf->lan_vsi_idx == 0)
121 continue;
122
123 /* If VF is reset in another thread just continue */
124 if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
125 continue;
126
127 - i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[v].lan_vsi_idx]);
128 + i40e_vsi_wait_queues_disabled(pf->vsi[vf->lan_vsi_idx]);
129 }
130
131 /* Hw may need up to 50ms to finish disabling the RX queues. We
132 @@ -1410,12 +1408,12 @@ bool i40e_reset_all_vfs(struct i40e_pf *
133 mdelay(50);
134
135 /* Finish the reset on each VF */
136 - for (v = 0; v < pf->num_alloc_vfs; v++) {
137 + for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
138 /* If VF is reset in another thread just continue */
139 if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
140 continue;
141
142 - i40e_cleanup_reset_vf(&pf->vf[v]);
143 + i40e_cleanup_reset_vf(vf);
144 }
145
146 i40e_flush(hw);