]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/6.6.26/ice-realloc-vsi-stats-arrays.patch
Linux 6.1.85
[thirdparty/kernel/stable-queue.git] / releases / 6.6.26 / ice-realloc-vsi-stats-arrays.patch
1 From 30e9b7a79216ae72326c2f209706e02bf4a55db4 Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Tue, 24 Oct 2023 13:09:26 +0200
4 Subject: ice: realloc VSI stats arrays
5
6 From: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
7
8 [ Upstream commit 5995ef88e3a8c2b014f51256a88be8e336532ce7 ]
9
10 Previously only case when queues amount is lower was covered. Implement
11 realloc for case when queues amount is higher than previous one. Use
12 krealloc() function and zero new allocated elements.
13
14 It has to be done before ice_vsi_def_cfg(), because stats element for
15 ring is set there.
16
17 Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
18 Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
19 Tested-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com>
20 Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
21 Stable-dep-of: 1cb7fdb1dfde ("ice: fix memory corruption bug with suspend and rebuild")
22 Signed-off-by: Sasha Levin <sashal@kernel.org>
23 ---
24 drivers/net/ethernet/intel/ice/ice_lib.c | 58 ++++++++++++++++--------
25 1 file changed, 39 insertions(+), 19 deletions(-)
26
27 diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
28 index 7f4bc110ead44..47298ab675a55 100644
29 --- a/drivers/net/ethernet/intel/ice/ice_lib.c
30 +++ b/drivers/net/ethernet/intel/ice/ice_lib.c
31 @@ -3084,27 +3084,26 @@ ice_vsi_rebuild_set_coalesce(struct ice_vsi *vsi,
32 }
33
34 /**
35 - * ice_vsi_realloc_stat_arrays - Frees unused stat structures
36 + * ice_vsi_realloc_stat_arrays - Frees unused stat structures or alloc new ones
37 * @vsi: VSI pointer
38 - * @prev_txq: Number of Tx rings before ring reallocation
39 - * @prev_rxq: Number of Rx rings before ring reallocation
40 */
41 -static void
42 -ice_vsi_realloc_stat_arrays(struct ice_vsi *vsi, int prev_txq, int prev_rxq)
43 +static int
44 +ice_vsi_realloc_stat_arrays(struct ice_vsi *vsi)
45 {
46 + u16 req_txq = vsi->req_txq ? vsi->req_txq : vsi->alloc_txq;
47 + u16 req_rxq = vsi->req_rxq ? vsi->req_rxq : vsi->alloc_rxq;
48 + struct ice_ring_stats **tx_ring_stats;
49 + struct ice_ring_stats **rx_ring_stats;
50 struct ice_vsi_stats *vsi_stat;
51 struct ice_pf *pf = vsi->back;
52 + u16 prev_txq = vsi->alloc_txq;
53 + u16 prev_rxq = vsi->alloc_rxq;
54 int i;
55
56 - if (!prev_txq || !prev_rxq)
57 - return;
58 - if (vsi->type == ICE_VSI_CHNL)
59 - return;
60 -
61 vsi_stat = pf->vsi_stats[vsi->idx];
62
63 - if (vsi->num_txq < prev_txq) {
64 - for (i = vsi->num_txq; i < prev_txq; i++) {
65 + if (req_txq < prev_txq) {
66 + for (i = req_txq; i < prev_txq; i++) {
67 if (vsi_stat->tx_ring_stats[i]) {
68 kfree_rcu(vsi_stat->tx_ring_stats[i], rcu);
69 WRITE_ONCE(vsi_stat->tx_ring_stats[i], NULL);
70 @@ -3112,14 +3111,36 @@ ice_vsi_realloc_stat_arrays(struct ice_vsi *vsi, int prev_txq, int prev_rxq)
71 }
72 }
73
74 - if (vsi->num_rxq < prev_rxq) {
75 - for (i = vsi->num_rxq; i < prev_rxq; i++) {
76 + tx_ring_stats = vsi_stat->rx_ring_stats;
77 + vsi_stat->tx_ring_stats =
78 + krealloc_array(vsi_stat->tx_ring_stats, req_txq,
79 + sizeof(*vsi_stat->tx_ring_stats),
80 + GFP_KERNEL | __GFP_ZERO);
81 + if (!vsi_stat->tx_ring_stats) {
82 + vsi_stat->tx_ring_stats = tx_ring_stats;
83 + return -ENOMEM;
84 + }
85 +
86 + if (req_rxq < prev_rxq) {
87 + for (i = req_rxq; i < prev_rxq; i++) {
88 if (vsi_stat->rx_ring_stats[i]) {
89 kfree_rcu(vsi_stat->rx_ring_stats[i], rcu);
90 WRITE_ONCE(vsi_stat->rx_ring_stats[i], NULL);
91 }
92 }
93 }
94 +
95 + rx_ring_stats = vsi_stat->rx_ring_stats;
96 + vsi_stat->rx_ring_stats =
97 + krealloc_array(vsi_stat->rx_ring_stats, req_rxq,
98 + sizeof(*vsi_stat->rx_ring_stats),
99 + GFP_KERNEL | __GFP_ZERO);
100 + if (!vsi_stat->rx_ring_stats) {
101 + vsi_stat->rx_ring_stats = rx_ring_stats;
102 + return -ENOMEM;
103 + }
104 +
105 + return 0;
106 }
107
108 /**
109 @@ -3136,9 +3157,9 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags)
110 {
111 struct ice_vsi_cfg_params params = {};
112 struct ice_coalesce_stored *coalesce;
113 - int ret, prev_txq, prev_rxq;
114 int prev_num_q_vectors = 0;
115 struct ice_pf *pf;
116 + int ret;
117
118 if (!vsi)
119 return -EINVAL;
120 @@ -3157,8 +3178,9 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags)
121
122 prev_num_q_vectors = ice_vsi_rebuild_get_coalesce(vsi, coalesce);
123
124 - prev_txq = vsi->num_txq;
125 - prev_rxq = vsi->num_rxq;
126 + ret = ice_vsi_realloc_stat_arrays(vsi);
127 + if (ret)
128 + goto err_vsi_cfg;
129
130 ice_vsi_decfg(vsi);
131 ret = ice_vsi_cfg_def(vsi, &params);
132 @@ -3176,8 +3198,6 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags)
133 return ice_schedule_reset(pf, ICE_RESET_PFR);
134 }
135
136 - ice_vsi_realloc_stat_arrays(vsi, prev_txq, prev_rxq);
137 -
138 ice_vsi_rebuild_set_coalesce(vsi, coalesce, prev_num_q_vectors);
139 kfree(coalesce);
140
141 --
142 2.43.0
143