@@ -447,6 +447,49 @@ static irqreturn_t ice_eswitch_msix_clean_rings(int __always_unused irq, void *d
447
447
return IRQ_HANDLED ;
448
448
}
449
449
450
+ /**
451
+ * ice_vsi_alloc_stat_arrays - Allocate statistics arrays
452
+ * @vsi: VSI pointer
453
+ */
454
+ static int ice_vsi_alloc_stat_arrays (struct ice_vsi * vsi )
455
+ {
456
+ struct ice_vsi_stats * vsi_stat ;
457
+ struct ice_pf * pf = vsi -> back ;
458
+
459
+ if (vsi -> type == ICE_VSI_CHNL )
460
+ return 0 ;
461
+ if (!pf -> vsi_stats )
462
+ return - ENOENT ;
463
+
464
+ vsi_stat = kzalloc (sizeof (* vsi_stat ), GFP_KERNEL );
465
+ if (!vsi_stat )
466
+ return - ENOMEM ;
467
+
468
+ vsi_stat -> tx_ring_stats =
469
+ kcalloc (vsi -> alloc_txq , sizeof (* vsi_stat -> tx_ring_stats ),
470
+ GFP_KERNEL );
471
+ if (!vsi_stat -> tx_ring_stats )
472
+ goto err_alloc_tx ;
473
+
474
+ vsi_stat -> rx_ring_stats =
475
+ kcalloc (vsi -> alloc_rxq , sizeof (* vsi_stat -> rx_ring_stats ),
476
+ GFP_KERNEL );
477
+ if (!vsi_stat -> rx_ring_stats )
478
+ goto err_alloc_rx ;
479
+
480
+ pf -> vsi_stats [vsi -> idx ] = vsi_stat ;
481
+
482
+ return 0 ;
483
+
484
+ err_alloc_rx :
485
+ kfree (vsi_stat -> rx_ring_stats );
486
+ err_alloc_tx :
487
+ kfree (vsi_stat -> tx_ring_stats );
488
+ kfree (vsi_stat );
489
+ pf -> vsi_stats [vsi -> idx ] = NULL ;
490
+ return - ENOMEM ;
491
+ }
492
+
450
493
/**
451
494
* ice_vsi_alloc - Allocates the next available struct VSI in the PF
452
495
* @pf: board private structure
@@ -560,6 +603,11 @@ ice_vsi_alloc(struct ice_pf *pf, enum ice_vsi_type vsi_type,
560
603
561
604
if (vsi -> type == ICE_VSI_CTRL && vf )
562
605
vf -> ctrl_vsi_idx = vsi -> idx ;
606
+
607
+ /* allocate memory for Tx/Rx ring stat pointers */
608
+ if (ice_vsi_alloc_stat_arrays (vsi ))
609
+ goto err_rings ;
610
+
563
611
goto unlock_pf ;
564
612
565
613
err_rings :
@@ -1535,6 +1583,106 @@ static int ice_vsi_alloc_rings(struct ice_vsi *vsi)
1535
1583
return - ENOMEM ;
1536
1584
}
1537
1585
1586
+ /**
1587
+ * ice_vsi_free_stats - Free the ring statistics structures
1588
+ * @vsi: VSI pointer
1589
+ */
1590
+ static void ice_vsi_free_stats (struct ice_vsi * vsi )
1591
+ {
1592
+ struct ice_vsi_stats * vsi_stat ;
1593
+ struct ice_pf * pf = vsi -> back ;
1594
+ int i ;
1595
+
1596
+ if (vsi -> type == ICE_VSI_CHNL )
1597
+ return ;
1598
+ if (!pf -> vsi_stats )
1599
+ return ;
1600
+
1601
+ vsi_stat = pf -> vsi_stats [vsi -> idx ];
1602
+ if (!vsi_stat )
1603
+ return ;
1604
+
1605
+ ice_for_each_alloc_txq (vsi , i ) {
1606
+ if (vsi_stat -> tx_ring_stats [i ]) {
1607
+ kfree_rcu (vsi_stat -> tx_ring_stats [i ], rcu );
1608
+ WRITE_ONCE (vsi_stat -> tx_ring_stats [i ], NULL );
1609
+ }
1610
+ }
1611
+
1612
+ ice_for_each_alloc_rxq (vsi , i ) {
1613
+ if (vsi_stat -> rx_ring_stats [i ]) {
1614
+ kfree_rcu (vsi_stat -> rx_ring_stats [i ], rcu );
1615
+ WRITE_ONCE (vsi_stat -> rx_ring_stats [i ], NULL );
1616
+ }
1617
+ }
1618
+
1619
+ kfree (vsi_stat -> tx_ring_stats );
1620
+ kfree (vsi_stat -> rx_ring_stats );
1621
+ kfree (vsi_stat );
1622
+ pf -> vsi_stats [vsi -> idx ] = NULL ;
1623
+ }
1624
+
1625
+ /**
1626
+ * ice_vsi_alloc_ring_stats - Allocates Tx and Rx ring stats for the VSI
1627
+ * @vsi: VSI which is having stats allocated
1628
+ */
1629
+ static int ice_vsi_alloc_ring_stats (struct ice_vsi * vsi )
1630
+ {
1631
+ struct ice_ring_stats * * tx_ring_stats ;
1632
+ struct ice_ring_stats * * rx_ring_stats ;
1633
+ struct ice_vsi_stats * vsi_stats ;
1634
+ struct ice_pf * pf = vsi -> back ;
1635
+ u16 i ;
1636
+
1637
+ vsi_stats = pf -> vsi_stats [vsi -> idx ];
1638
+ tx_ring_stats = vsi_stats -> tx_ring_stats ;
1639
+ rx_ring_stats = vsi_stats -> rx_ring_stats ;
1640
+
1641
+ /* Allocate Tx ring stats */
1642
+ ice_for_each_alloc_txq (vsi , i ) {
1643
+ struct ice_ring_stats * ring_stats ;
1644
+ struct ice_tx_ring * ring ;
1645
+
1646
+ ring = vsi -> tx_rings [i ];
1647
+ ring_stats = tx_ring_stats [i ];
1648
+
1649
+ if (!ring_stats ) {
1650
+ ring_stats = kzalloc (sizeof (* ring_stats ), GFP_KERNEL );
1651
+ if (!ring_stats )
1652
+ goto err_out ;
1653
+
1654
+ WRITE_ONCE (tx_ring_stats [i ], ring_stats );
1655
+ }
1656
+
1657
+ ring -> ring_stats = ring_stats ;
1658
+ }
1659
+
1660
+ /* Allocate Rx ring stats */
1661
+ ice_for_each_alloc_rxq (vsi , i ) {
1662
+ struct ice_ring_stats * ring_stats ;
1663
+ struct ice_rx_ring * ring ;
1664
+
1665
+ ring = vsi -> rx_rings [i ];
1666
+ ring_stats = rx_ring_stats [i ];
1667
+
1668
+ if (!ring_stats ) {
1669
+ ring_stats = kzalloc (sizeof (* ring_stats ), GFP_KERNEL );
1670
+ if (!ring_stats )
1671
+ goto err_out ;
1672
+
1673
+ WRITE_ONCE (rx_ring_stats [i ], ring_stats );
1674
+ }
1675
+
1676
+ ring -> ring_stats = ring_stats ;
1677
+ }
1678
+
1679
+ return 0 ;
1680
+
1681
+ err_out :
1682
+ ice_vsi_free_stats (vsi );
1683
+ return - ENOMEM ;
1684
+ }
1685
+
1538
1686
/**
1539
1687
* ice_vsi_manage_rss_lut - disable/enable RSS
1540
1688
* @vsi: the VSI being changed
@@ -2580,6 +2728,10 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
2580
2728
if (ret )
2581
2729
goto unroll_vector_base ;
2582
2730
2731
+ ret = ice_vsi_alloc_ring_stats (vsi );
2732
+ if (ret )
2733
+ goto unroll_vector_base ;
2734
+
2583
2735
ice_vsi_map_rings_to_vectors (vsi );
2584
2736
2585
2737
/* ICE_VSI_CTRL does not need RSS so skip RSS processing */
@@ -2618,6 +2770,9 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
2618
2770
if (ret )
2619
2771
goto unroll_vector_base ;
2620
2772
2773
+ ret = ice_vsi_alloc_ring_stats (vsi );
2774
+ if (ret )
2775
+ goto unroll_vector_base ;
2621
2776
/* Do not exit if configuring RSS had an issue, at least
2622
2777
* receive traffic on first queue. Hence no need to capture
2623
2778
* return value
@@ -2631,6 +2786,11 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
2631
2786
ret = ice_vsi_alloc_rings (vsi );
2632
2787
if (ret )
2633
2788
goto unroll_vsi_init ;
2789
+
2790
+ ret = ice_vsi_alloc_ring_stats (vsi );
2791
+ if (ret )
2792
+ goto unroll_vector_base ;
2793
+
2634
2794
break ;
2635
2795
default :
2636
2796
/* clean up the resources and exit */
@@ -2690,6 +2850,7 @@ ice_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi,
2690
2850
unroll_alloc_q_vector :
2691
2851
ice_vsi_free_q_vectors (vsi );
2692
2852
unroll_vsi_init :
2853
+ ice_vsi_free_stats (vsi );
2693
2854
ice_vsi_delete (vsi );
2694
2855
unroll_get_qs :
2695
2856
ice_vsi_put_qs (vsi );
@@ -3081,7 +3242,7 @@ int ice_vsi_release(struct ice_vsi *vsi)
3081
3242
vsi -> agg_node && vsi -> agg_node -> valid )
3082
3243
vsi -> agg_node -> num_vsis -- ;
3083
3244
ice_vsi_clear_rings (vsi );
3084
-
3245
+ ice_vsi_free_stats ( vsi );
3085
3246
ice_vsi_put_qs (vsi );
3086
3247
3087
3248
/* retain SW VSI data structure since it is needed to unregister and
@@ -3208,6 +3369,47 @@ ice_vsi_rebuild_set_coalesce(struct ice_vsi *vsi,
3208
3369
}
3209
3370
}
3210
3371
3372
+ /**
3373
+ * ice_vsi_realloc_stat_arrays - Frees unused stat structures
3374
+ * @vsi: VSI pointer
3375
+ * @prev_txq: Number of Tx rings before ring reallocation
3376
+ * @prev_rxq: Number of Rx rings before ring reallocation
3377
+ */
3378
+ static int
3379
+ ice_vsi_realloc_stat_arrays (struct ice_vsi * vsi , int prev_txq , int prev_rxq )
3380
+ {
3381
+ struct ice_vsi_stats * vsi_stat ;
3382
+ struct ice_pf * pf = vsi -> back ;
3383
+ int i ;
3384
+
3385
+ if (!prev_txq || !prev_rxq )
3386
+ return 0 ;
3387
+ if (vsi -> type == ICE_VSI_CHNL )
3388
+ return 0 ;
3389
+
3390
+ vsi_stat = pf -> vsi_stats [vsi -> idx ];
3391
+
3392
+ if (vsi -> num_txq < prev_txq ) {
3393
+ for (i = vsi -> num_txq ; i < prev_txq ; i ++ ) {
3394
+ if (vsi_stat -> tx_ring_stats [i ]) {
3395
+ kfree_rcu (vsi_stat -> tx_ring_stats [i ], rcu );
3396
+ WRITE_ONCE (vsi_stat -> tx_ring_stats [i ], NULL );
3397
+ }
3398
+ }
3399
+ }
3400
+
3401
+ if (vsi -> num_rxq < prev_rxq ) {
3402
+ for (i = vsi -> num_rxq ; i < prev_rxq ; i ++ ) {
3403
+ if (vsi_stat -> rx_ring_stats [i ]) {
3404
+ kfree_rcu (vsi_stat -> rx_ring_stats [i ], rcu );
3405
+ WRITE_ONCE (vsi_stat -> rx_ring_stats [i ], NULL );
3406
+ }
3407
+ }
3408
+ }
3409
+
3410
+ return 0 ;
3411
+ }
3412
+
3211
3413
/**
3212
3414
* ice_vsi_rebuild - Rebuild VSI after reset
3213
3415
* @vsi: VSI to be rebuild
@@ -3219,10 +3421,10 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
3219
3421
{
3220
3422
u16 max_txqs [ICE_MAX_TRAFFIC_CLASS ] = { 0 };
3221
3423
struct ice_coalesce_stored * coalesce ;
3424
+ int ret , i , prev_txq , prev_rxq ;
3222
3425
int prev_num_q_vectors = 0 ;
3223
3426
enum ice_vsi_type vtype ;
3224
3427
struct ice_pf * pf ;
3225
- int ret , i ;
3226
3428
3227
3429
if (!vsi )
3228
3430
return - EINVAL ;
@@ -3241,6 +3443,9 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
3241
3443
3242
3444
prev_num_q_vectors = ice_vsi_rebuild_get_coalesce (vsi , coalesce );
3243
3445
3446
+ prev_txq = vsi -> num_txq ;
3447
+ prev_rxq = vsi -> num_rxq ;
3448
+
3244
3449
ice_rm_vsi_lan_cfg (vsi -> port_info , vsi -> idx );
3245
3450
ret = ice_rm_vsi_rdma_cfg (vsi -> port_info , vsi -> idx );
3246
3451
if (ret )
@@ -3307,6 +3512,10 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
3307
3512
if (ret )
3308
3513
goto err_vectors ;
3309
3514
3515
+ ret = ice_vsi_alloc_ring_stats (vsi );
3516
+ if (ret )
3517
+ goto err_vectors ;
3518
+
3310
3519
ice_vsi_map_rings_to_vectors (vsi );
3311
3520
3312
3521
vsi -> stat_offsets_loaded = false;
@@ -3346,6 +3555,10 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
3346
3555
if (ret )
3347
3556
goto err_vectors ;
3348
3557
3558
+ ret = ice_vsi_alloc_ring_stats (vsi );
3559
+ if (ret )
3560
+ goto err_vectors ;
3561
+
3349
3562
vsi -> stat_offsets_loaded = false;
3350
3563
break ;
3351
3564
case ICE_VSI_CHNL :
@@ -3394,6 +3607,10 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, bool init_vsi)
3394
3607
return ice_schedule_reset (pf , ICE_RESET_PFR );
3395
3608
}
3396
3609
}
3610
+
3611
+ if (ice_vsi_realloc_stat_arrays (vsi , prev_txq , prev_rxq ))
3612
+ goto err_vectors ;
3613
+
3397
3614
ice_vsi_rebuild_set_coalesce (vsi , coalesce , prev_num_q_vectors );
3398
3615
kfree (coalesce );
3399
3616
@@ -3735,9 +3952,9 @@ static void ice_update_ring_stats(struct ice_q_stats *stats, u64 pkts, u64 bytes
3735
3952
*/
3736
3953
void ice_update_tx_ring_stats (struct ice_tx_ring * tx_ring , u64 pkts , u64 bytes )
3737
3954
{
3738
- u64_stats_update_begin (& tx_ring -> syncp );
3739
- ice_update_ring_stats (& tx_ring -> stats , pkts , bytes );
3740
- u64_stats_update_end (& tx_ring -> syncp );
3955
+ u64_stats_update_begin (& tx_ring -> ring_stats -> syncp );
3956
+ ice_update_ring_stats (& tx_ring -> ring_stats -> stats , pkts , bytes );
3957
+ u64_stats_update_end (& tx_ring -> ring_stats -> syncp );
3741
3958
}
3742
3959
3743
3960
/**
@@ -3748,9 +3965,9 @@ void ice_update_tx_ring_stats(struct ice_tx_ring *tx_ring, u64 pkts, u64 bytes)
3748
3965
*/
3749
3966
void ice_update_rx_ring_stats (struct ice_rx_ring * rx_ring , u64 pkts , u64 bytes )
3750
3967
{
3751
- u64_stats_update_begin (& rx_ring -> syncp );
3752
- ice_update_ring_stats (& rx_ring -> stats , pkts , bytes );
3753
- u64_stats_update_end (& rx_ring -> syncp );
3968
+ u64_stats_update_begin (& rx_ring -> ring_stats -> syncp );
3969
+ ice_update_ring_stats (& rx_ring -> ring_stats -> stats , pkts , bytes );
3970
+ u64_stats_update_end (& rx_ring -> ring_stats -> syncp );
3754
3971
}
3755
3972
3756
3973
/**
0 commit comments