@@ -95,6 +95,8 @@ struct virtnet_sq_stats {
9595 u64_stats_t xdp_tx_drops ;
9696 u64_stats_t kicks ;
9797 u64_stats_t tx_timeouts ;
98+ u64_stats_t stop ;
99+ u64_stats_t wake ;
98100};
99101
100102struct virtnet_rq_stats {
@@ -145,6 +147,8 @@ static const struct virtnet_stat_desc virtnet_rq_stats_desc[] = {
145147static const struct virtnet_stat_desc virtnet_sq_stats_desc_qstat [] = {
146148 VIRTNET_SQ_STAT_QSTAT ("packets" , packets ),
147149 VIRTNET_SQ_STAT_QSTAT ("bytes" , bytes ),
150+ VIRTNET_SQ_STAT_QSTAT ("stop" , stop ),
151+ VIRTNET_SQ_STAT_QSTAT ("wake" , wake ),
148152};
149153
150154static 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,
10141018 */
10151019 if (sq -> vq -> num_free < 2 + MAX_SKB_FRAGS ) {
10161020 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 );
10171024 if (use_napi ) {
10181025 if (unlikely (!virtqueue_enable_cb_delayed (sq -> vq )))
10191026 virtqueue_napi_schedule (& sq -> napi , sq -> vq );
@@ -1022,6 +1029,9 @@ static void check_sq_full_and_disable(struct virtnet_info *vi,
10221029 free_old_xmit (sq , false);
10231030 if (sq -> vq -> num_free >= 2 + MAX_SKB_FRAGS ) {
10241031 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 );
10251035 virtqueue_disable_cb (sq -> vq );
10261036 }
10271037 }
@@ -2322,8 +2332,14 @@ static void virtnet_poll_cleantx(struct receive_queue *rq)
23222332 free_old_xmit (sq , true);
23232333 } while (unlikely (!virtqueue_enable_cb_delayed (sq -> vq )));
23242334
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+ }
23262341 netif_tx_wake_queue (txq );
2342+ }
23272343
23282344 __netif_tx_unlock (txq );
23292345 }
@@ -2473,8 +2489,14 @@ static int virtnet_poll_tx(struct napi_struct *napi, int budget)
24732489 virtqueue_disable_cb (sq -> vq );
24742490 free_old_xmit (sq , true);
24752491
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+ }
24772498 netif_tx_wake_queue (txq );
2499+ }
24782500
24792501 opaque = virtqueue_enable_cb_prepare (sq -> vq );
24802502
@@ -4789,6 +4811,8 @@ static void virtnet_get_base_stats(struct net_device *dev,
47894811
47904812 tx -> bytes = 0 ;
47914813 tx -> packets = 0 ;
4814+ tx -> stop = 0 ;
4815+ tx -> wake = 0 ;
47924816
47934817 if (vi -> device_stats_cap & VIRTIO_NET_STATS_TYPE_TX_BASIC ) {
47944818 tx -> hw_drops = 0 ;
0 commit comments