19
19
#include <linux/net_namespace.h>
20
20
#include <linux/mutex.h>
21
21
#include <linux/genalloc.h>
22
+ #include <linux/xarray.h>
22
23
#include <net/netevent.h>
23
24
#include <net/neighbour.h>
24
25
#include <net/arp.h>
@@ -3111,6 +3112,7 @@ struct mlxsw_sp_nexthop_group_info {
3111
3112
is_resilient :1 ,
3112
3113
hw_stats :1 ;
3113
3114
struct list_head list ; /* member in nh_res_grp_list */
3115
+ struct xarray nexthop_counters ;
3114
3116
struct mlxsw_sp_nexthop nexthops [] __counted_by (count );
3115
3117
};
3116
3118
@@ -3156,6 +3158,7 @@ struct mlxsw_sp_nexthop_group {
3156
3158
3157
3159
struct mlxsw_sp_nexthop_counter {
3158
3160
unsigned int counter_index ;
3161
+ refcount_t ref_count ;
3159
3162
};
3160
3163
3161
3164
static struct mlxsw_sp_nexthop_counter *
@@ -3172,6 +3175,7 @@ mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp)
3172
3175
if (err )
3173
3176
goto err_counter_alloc ;
3174
3177
3178
+ refcount_set (& nhct -> ref_count , 1 );
3175
3179
return nhct ;
3176
3180
3177
3181
err_counter_alloc :
@@ -3187,6 +3191,56 @@ mlxsw_sp_nexthop_counter_free(struct mlxsw_sp *mlxsw_sp,
3187
3191
kfree (nhct );
3188
3192
}
3189
3193
3194
+ static struct mlxsw_sp_nexthop_counter *
3195
+ mlxsw_sp_nexthop_sh_counter_get (struct mlxsw_sp * mlxsw_sp ,
3196
+ struct mlxsw_sp_nexthop * nh )
3197
+ {
3198
+ struct mlxsw_sp_nexthop_group * nh_grp = nh -> nhgi -> nh_grp ;
3199
+ struct mlxsw_sp_nexthop_counter * nhct ;
3200
+ void * ptr ;
3201
+ int err ;
3202
+
3203
+ nhct = xa_load (& nh_grp -> nhgi -> nexthop_counters , nh -> id );
3204
+ if (nhct ) {
3205
+ refcount_inc (& nhct -> ref_count );
3206
+ return nhct ;
3207
+ }
3208
+
3209
+ nhct = mlxsw_sp_nexthop_counter_alloc (mlxsw_sp );
3210
+ if (IS_ERR (nhct ))
3211
+ return nhct ;
3212
+
3213
+ ptr = xa_store (& nh_grp -> nhgi -> nexthop_counters , nh -> id , nhct ,
3214
+ GFP_KERNEL );
3215
+ if (IS_ERR (ptr )) {
3216
+ err = PTR_ERR (ptr );
3217
+ goto err_store ;
3218
+ }
3219
+
3220
+ return nhct ;
3221
+
3222
+ err_store :
3223
+ mlxsw_sp_nexthop_counter_free (mlxsw_sp , nhct );
3224
+ return ERR_PTR (err );
3225
+ }
3226
+
3227
+ static void mlxsw_sp_nexthop_sh_counter_put (struct mlxsw_sp * mlxsw_sp ,
3228
+ struct mlxsw_sp_nexthop * nh )
3229
+ {
3230
+ struct mlxsw_sp_nexthop_group * nh_grp = nh -> nhgi -> nh_grp ;
3231
+ struct mlxsw_sp_nexthop_counter * nhct ;
3232
+
3233
+ nhct = xa_load (& nh_grp -> nhgi -> nexthop_counters , nh -> id );
3234
+ if (WARN_ON (!nhct ))
3235
+ return ;
3236
+
3237
+ if (!refcount_dec_and_test (& nhct -> ref_count ))
3238
+ return ;
3239
+
3240
+ xa_erase (& nh_grp -> nhgi -> nexthop_counters , nh -> id );
3241
+ mlxsw_sp_nexthop_counter_free (mlxsw_sp , nhct );
3242
+ }
3243
+
3190
3244
int mlxsw_sp_nexthop_counter_enable (struct mlxsw_sp * mlxsw_sp ,
3191
3245
struct mlxsw_sp_nexthop * nh )
3192
3246
{
@@ -3203,7 +3257,10 @@ int mlxsw_sp_nexthop_counter_enable(struct mlxsw_sp *mlxsw_sp,
3203
3257
if (!(nh -> nhgi -> hw_stats || dpipe_stats ))
3204
3258
return 0 ;
3205
3259
3206
- nhct = mlxsw_sp_nexthop_counter_alloc (mlxsw_sp );
3260
+ if (nh -> id )
3261
+ nhct = mlxsw_sp_nexthop_sh_counter_get (mlxsw_sp , nh );
3262
+ else
3263
+ nhct = mlxsw_sp_nexthop_counter_alloc (mlxsw_sp );
3207
3264
if (IS_ERR (nhct ))
3208
3265
return PTR_ERR (nhct );
3209
3266
@@ -3216,7 +3273,11 @@ void mlxsw_sp_nexthop_counter_disable(struct mlxsw_sp *mlxsw_sp,
3216
3273
{
3217
3274
if (!nh -> counter )
3218
3275
return ;
3219
- mlxsw_sp_nexthop_counter_free (mlxsw_sp , nh -> counter );
3276
+
3277
+ if (nh -> id )
3278
+ mlxsw_sp_nexthop_sh_counter_put (mlxsw_sp , nh );
3279
+ else
3280
+ mlxsw_sp_nexthop_counter_free (mlxsw_sp , nh -> counter );
3220
3281
nh -> counter = NULL ;
3221
3282
}
3222
3283
@@ -5145,6 +5206,9 @@ mlxsw_sp_nexthop_obj_group_info_init(struct mlxsw_sp *mlxsw_sp,
5145
5206
nhgi -> is_resilient = is_resilient ;
5146
5207
nhgi -> count = nhs ;
5147
5208
nhgi -> hw_stats = hw_stats ;
5209
+
5210
+ xa_init_flags (& nhgi -> nexthop_counters , XA_FLAGS_ALLOC1 );
5211
+
5148
5212
for (i = 0 ; i < nhgi -> count ; i ++ ) {
5149
5213
struct nh_notifier_single_info * nh_obj ;
5150
5214
int weight ;
@@ -5227,6 +5291,8 @@ mlxsw_sp_nexthop_obj_group_info_fini(struct mlxsw_sp *mlxsw_sp,
5227
5291
}
5228
5292
mlxsw_sp_nexthop_group_refresh (mlxsw_sp , nh_grp );
5229
5293
WARN_ON_ONCE (nhgi -> adj_index_valid );
5294
+ WARN_ON (!xa_empty (& nhgi -> nexthop_counters ));
5295
+ xa_destroy (& nhgi -> nexthop_counters );
5230
5296
kfree (nhgi );
5231
5297
}
5232
5298
0 commit comments