ice: realloc VSI stats arrays
authorMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Tue, 24 Oct 2023 11:09:26 +0000 (13:09 +0200)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Mon, 13 Nov 2023 19:42:14 +0000 (11:42 -0800)
Previously only case when queues amount is lower was covered. Implement
realloc for case when queues amount is higher than previous one. Use
krealloc() function and zero new allocated elements.

It has to be done before ice_vsi_def_cfg(), because stats element for
ring is set there.

Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Tested-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/ice/ice_lib.c

index 85a8cb28a4893e764a5c2b017034eb372c49aaac..d826b5afa14344d62a5fd12b45dec4601be5e209 100644 (file)
@@ -3076,27 +3076,26 @@ ice_vsi_rebuild_set_coalesce(struct ice_vsi *vsi,
 }
 
 /**
- * ice_vsi_realloc_stat_arrays - Frees unused stat structures
+ * ice_vsi_realloc_stat_arrays - Frees unused stat structures or alloc new ones
  * @vsi: VSI pointer
- * @prev_txq: Number of Tx rings before ring reallocation
- * @prev_rxq: Number of Rx rings before ring reallocation
  */
-static void
-ice_vsi_realloc_stat_arrays(struct ice_vsi *vsi, int prev_txq, int prev_rxq)
+static int
+ice_vsi_realloc_stat_arrays(struct ice_vsi *vsi)
 {
+       u16 req_txq = vsi->req_txq ? vsi->req_txq : vsi->alloc_txq;
+       u16 req_rxq = vsi->req_rxq ? vsi->req_rxq : vsi->alloc_rxq;
+       struct ice_ring_stats **tx_ring_stats;
+       struct ice_ring_stats **rx_ring_stats;
        struct ice_vsi_stats *vsi_stat;
        struct ice_pf *pf = vsi->back;
+       u16 prev_txq = vsi->alloc_txq;
+       u16 prev_rxq = vsi->alloc_rxq;
        int i;
 
-       if (!prev_txq || !prev_rxq)
-               return;
-       if (vsi->type == ICE_VSI_CHNL)
-               return;
-
        vsi_stat = pf->vsi_stats[vsi->idx];
 
-       if (vsi->num_txq < prev_txq) {
-               for (i = vsi->num_txq; i < prev_txq; i++) {
+       if (req_txq < prev_txq) {
+               for (i = req_txq; i < prev_txq; i++) {
                        if (vsi_stat->tx_ring_stats[i]) {
                                kfree_rcu(vsi_stat->tx_ring_stats[i], rcu);
                                WRITE_ONCE(vsi_stat->tx_ring_stats[i], NULL);
@@ -3104,14 +3103,36 @@ ice_vsi_realloc_stat_arrays(struct ice_vsi *vsi, int prev_txq, int prev_rxq)
                }
        }
 
-       if (vsi->num_rxq < prev_rxq) {
-               for (i = vsi->num_rxq; i < prev_rxq; i++) {
+       tx_ring_stats = vsi_stat->rx_ring_stats;
+       vsi_stat->tx_ring_stats =
+               krealloc_array(vsi_stat->tx_ring_stats, req_txq,
+                              sizeof(*vsi_stat->tx_ring_stats),
+                              GFP_KERNEL | __GFP_ZERO);
+       if (!vsi_stat->tx_ring_stats) {
+               vsi_stat->tx_ring_stats = tx_ring_stats;
+               return -ENOMEM;
+       }
+
+       if (req_rxq < prev_rxq) {
+               for (i = req_rxq; i < prev_rxq; i++) {
                        if (vsi_stat->rx_ring_stats[i]) {
                                kfree_rcu(vsi_stat->rx_ring_stats[i], rcu);
                                WRITE_ONCE(vsi_stat->rx_ring_stats[i], NULL);
                        }
                }
        }
+
+       rx_ring_stats = vsi_stat->rx_ring_stats;
+       vsi_stat->rx_ring_stats =
+               krealloc_array(vsi_stat->rx_ring_stats, req_rxq,
+                              sizeof(*vsi_stat->rx_ring_stats),
+                              GFP_KERNEL | __GFP_ZERO);
+       if (!vsi_stat->rx_ring_stats) {
+               vsi_stat->rx_ring_stats = rx_ring_stats;
+               return -ENOMEM;
+       }
+
+       return 0;
 }
 
 /**
@@ -3128,9 +3149,9 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags)
 {
        struct ice_vsi_cfg_params params = {};
        struct ice_coalesce_stored *coalesce;
-       int ret, prev_txq, prev_rxq;
        int prev_num_q_vectors = 0;
        struct ice_pf *pf;
+       int ret;
 
        if (!vsi)
                return -EINVAL;
@@ -3149,8 +3170,9 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags)
 
        prev_num_q_vectors = ice_vsi_rebuild_get_coalesce(vsi, coalesce);
 
-       prev_txq = vsi->num_txq;
-       prev_rxq = vsi->num_rxq;
+       ret = ice_vsi_realloc_stat_arrays(vsi);
+       if (ret)
+               goto err_vsi_cfg;
 
        ice_vsi_decfg(vsi);
        ret = ice_vsi_cfg_def(vsi, &params);
@@ -3168,8 +3190,6 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags)
                return ice_schedule_reset(pf, ICE_RESET_PFR);
        }
 
-       ice_vsi_realloc_stat_arrays(vsi, prev_txq, prev_rxq);
-
        ice_vsi_rebuild_set_coalesce(vsi, coalesce, prev_num_q_vectors);
        kfree(coalesce);