@@ -95,6 +95,8 @@ struct virtnet_sq_stats {
95
95
u64_stats_t xdp_tx_drops ;
96
96
u64_stats_t kicks ;
97
97
u64_stats_t tx_timeouts ;
98
+ u64_stats_t stop ;
99
+ u64_stats_t wake ;
98
100
};
99
101
100
102
struct virtnet_rq_stats {
@@ -145,6 +147,8 @@ static const struct virtnet_stat_desc virtnet_rq_stats_desc[] = {
145
147
static const struct virtnet_stat_desc virtnet_sq_stats_desc_qstat [] = {
146
148
VIRTNET_SQ_STAT_QSTAT ("packets" , packets ),
147
149
VIRTNET_SQ_STAT_QSTAT ("bytes" , bytes ),
150
+ VIRTNET_SQ_STAT_QSTAT ("stop" , stop ),
151
+ VIRTNET_SQ_STAT_QSTAT ("wake" , wake ),
148
152
};
149
153
150
154
static const struct virtnet_stat_desc virtnet_rq_stats_desc_qstat [] = {
@@ -1014,6 +1018,9 @@ static void check_sq_full_and_disable(struct virtnet_info *vi,
1014
1018
*/
1015
1019
if (sq -> vq -> num_free < 2 + MAX_SKB_FRAGS ) {
1016
1020
netif_stop_subqueue (dev , qnum );
1021
+ u64_stats_update_begin (& sq -> stats .syncp );
1022
+ u64_stats_inc (& sq -> stats .stop );
1023
+ u64_stats_update_end (& sq -> stats .syncp );
1017
1024
if (use_napi ) {
1018
1025
if (unlikely (!virtqueue_enable_cb_delayed (sq -> vq )))
1019
1026
virtqueue_napi_schedule (& sq -> napi , sq -> vq );
@@ -1022,6 +1029,9 @@ static void check_sq_full_and_disable(struct virtnet_info *vi,
1022
1029
free_old_xmit (sq , false);
1023
1030
if (sq -> vq -> num_free >= 2 + MAX_SKB_FRAGS ) {
1024
1031
netif_start_subqueue (dev , qnum );
1032
+ u64_stats_update_begin (& sq -> stats .syncp );
1033
+ u64_stats_inc (& sq -> stats .wake );
1034
+ u64_stats_update_end (& sq -> stats .syncp );
1025
1035
virtqueue_disable_cb (sq -> vq );
1026
1036
}
1027
1037
}
@@ -2322,8 +2332,14 @@ static void virtnet_poll_cleantx(struct receive_queue *rq)
2322
2332
free_old_xmit (sq , true);
2323
2333
} while (unlikely (!virtqueue_enable_cb_delayed (sq -> vq )));
2324
2334
2325
- if (sq -> vq -> num_free >= 2 + MAX_SKB_FRAGS )
2335
+ if (sq -> vq -> num_free >= 2 + MAX_SKB_FRAGS ) {
2336
+ if (netif_tx_queue_stopped (txq )) {
2337
+ u64_stats_update_begin (& sq -> stats .syncp );
2338
+ u64_stats_inc (& sq -> stats .wake );
2339
+ u64_stats_update_end (& sq -> stats .syncp );
2340
+ }
2326
2341
netif_tx_wake_queue (txq );
2342
+ }
2327
2343
2328
2344
__netif_tx_unlock (txq );
2329
2345
}
@@ -2473,8 +2489,14 @@ static int virtnet_poll_tx(struct napi_struct *napi, int budget)
2473
2489
virtqueue_disable_cb (sq -> vq );
2474
2490
free_old_xmit (sq , true);
2475
2491
2476
- if (sq -> vq -> num_free >= 2 + MAX_SKB_FRAGS )
2492
+ if (sq -> vq -> num_free >= 2 + MAX_SKB_FRAGS ) {
2493
+ if (netif_tx_queue_stopped (txq )) {
2494
+ u64_stats_update_begin (& sq -> stats .syncp );
2495
+ u64_stats_inc (& sq -> stats .wake );
2496
+ u64_stats_update_end (& sq -> stats .syncp );
2497
+ }
2477
2498
netif_tx_wake_queue (txq );
2499
+ }
2478
2500
2479
2501
opaque = virtqueue_enable_cb_prepare (sq -> vq );
2480
2502
@@ -4789,6 +4811,8 @@ static void virtnet_get_base_stats(struct net_device *dev,
4789
4811
4790
4812
tx -> bytes = 0 ;
4791
4813
tx -> packets = 0 ;
4814
+ tx -> stop = 0 ;
4815
+ tx -> wake = 0 ;
4792
4816
4793
4817
if (vi -> device_stats_cap & VIRTIO_NET_STATS_TYPE_TX_BASIC ) {
4794
4818
tx -> hw_drops = 0 ;
0 commit comments