@@ -3076,42 +3076,63 @@ ice_vsi_rebuild_set_coalesce(struct ice_vsi *vsi,
3076
3076
}
3077
3077
3078
3078
/**
3079
- * ice_vsi_realloc_stat_arrays - Frees unused stat structures
3079
+ * ice_vsi_realloc_stat_arrays - Frees unused stat structures or alloc new ones
3080
3080
* @vsi: VSI pointer
3081
- * @prev_txq: Number of Tx rings before ring reallocation
3082
- * @prev_rxq: Number of Rx rings before ring reallocation
3083
3081
*/
3084
- static void
3085
- ice_vsi_realloc_stat_arrays (struct ice_vsi * vsi , int prev_txq , int prev_rxq )
3082
+ static int
3083
+ ice_vsi_realloc_stat_arrays (struct ice_vsi * vsi )
3086
3084
{
3085
+ u16 req_txq = vsi -> req_txq ? vsi -> req_txq : vsi -> alloc_txq ;
3086
+ u16 req_rxq = vsi -> req_rxq ? vsi -> req_rxq : vsi -> alloc_rxq ;
3087
+ struct ice_ring_stats * * tx_ring_stats ;
3088
+ struct ice_ring_stats * * rx_ring_stats ;
3087
3089
struct ice_vsi_stats * vsi_stat ;
3088
3090
struct ice_pf * pf = vsi -> back ;
3091
+ u16 prev_txq = vsi -> alloc_txq ;
3092
+ u16 prev_rxq = vsi -> alloc_rxq ;
3089
3093
int i ;
3090
3094
3091
- if (!prev_txq || !prev_rxq )
3092
- return ;
3093
- if (vsi -> type == ICE_VSI_CHNL )
3094
- return ;
3095
-
3096
3095
vsi_stat = pf -> vsi_stats [vsi -> idx ];
3097
3096
3098
- if (vsi -> num_txq < prev_txq ) {
3099
- for (i = vsi -> num_txq ; i < prev_txq ; i ++ ) {
3097
+ if (req_txq < prev_txq ) {
3098
+ for (i = req_txq ; i < prev_txq ; i ++ ) {
3100
3099
if (vsi_stat -> tx_ring_stats [i ]) {
3101
3100
kfree_rcu (vsi_stat -> tx_ring_stats [i ], rcu );
3102
3101
WRITE_ONCE (vsi_stat -> tx_ring_stats [i ], NULL );
3103
3102
}
3104
3103
}
3105
3104
}
3106
3105
3107
- if (vsi -> num_rxq < prev_rxq ) {
3108
- for (i = vsi -> num_rxq ; i < prev_rxq ; i ++ ) {
3106
+ tx_ring_stats = vsi_stat -> rx_ring_stats ;
3107
+ vsi_stat -> tx_ring_stats =
3108
+ krealloc_array (vsi_stat -> tx_ring_stats , req_txq ,
3109
+ sizeof (* vsi_stat -> tx_ring_stats ),
3110
+ GFP_KERNEL | __GFP_ZERO );
3111
+ if (!vsi_stat -> tx_ring_stats ) {
3112
+ vsi_stat -> tx_ring_stats = tx_ring_stats ;
3113
+ return - ENOMEM ;
3114
+ }
3115
+
3116
+ if (req_rxq < prev_rxq ) {
3117
+ for (i = req_rxq ; i < prev_rxq ; i ++ ) {
3109
3118
if (vsi_stat -> rx_ring_stats [i ]) {
3110
3119
kfree_rcu (vsi_stat -> rx_ring_stats [i ], rcu );
3111
3120
WRITE_ONCE (vsi_stat -> rx_ring_stats [i ], NULL );
3112
3121
}
3113
3122
}
3114
3123
}
3124
+
3125
+ rx_ring_stats = vsi_stat -> rx_ring_stats ;
3126
+ vsi_stat -> rx_ring_stats =
3127
+ krealloc_array (vsi_stat -> rx_ring_stats , req_rxq ,
3128
+ sizeof (* vsi_stat -> rx_ring_stats ),
3129
+ GFP_KERNEL | __GFP_ZERO );
3130
+ if (!vsi_stat -> rx_ring_stats ) {
3131
+ vsi_stat -> rx_ring_stats = rx_ring_stats ;
3132
+ return - ENOMEM ;
3133
+ }
3134
+
3135
+ return 0 ;
3115
3136
}
3116
3137
3117
3138
/**
@@ -3128,9 +3149,9 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags)
3128
3149
{
3129
3150
struct ice_vsi_cfg_params params = {};
3130
3151
struct ice_coalesce_stored * coalesce ;
3131
- int ret , prev_txq , prev_rxq ;
3132
3152
int prev_num_q_vectors = 0 ;
3133
3153
struct ice_pf * pf ;
3154
+ int ret ;
3134
3155
3135
3156
if (!vsi )
3136
3157
return - EINVAL ;
@@ -3149,8 +3170,9 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags)
3149
3170
3150
3171
prev_num_q_vectors = ice_vsi_rebuild_get_coalesce (vsi , coalesce );
3151
3172
3152
- prev_txq = vsi -> num_txq ;
3153
- prev_rxq = vsi -> num_rxq ;
3173
+ ret = ice_vsi_realloc_stat_arrays (vsi );
3174
+ if (ret )
3175
+ goto err_vsi_cfg ;
3154
3176
3155
3177
ice_vsi_decfg (vsi );
3156
3178
ret = ice_vsi_cfg_def (vsi , & params );
@@ -3168,8 +3190,6 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags)
3168
3190
return ice_schedule_reset (pf , ICE_RESET_PFR );
3169
3191
}
3170
3192
3171
- ice_vsi_realloc_stat_arrays (vsi , prev_txq , prev_rxq );
3172
-
3173
3193
ice_vsi_rebuild_set_coalesce (vsi , coalesce , prev_num_q_vectors );
3174
3194
kfree (coalesce );
3175
3195
0 commit comments