From: Yanjun Zhang To more accurately detect packet dropped, we add the dropped packet counter with the device when kfree_skb is called because of failing to transfer data to user space. Signed-off-by: Yanjun Zhang --- drivers/net/tap.c | 14 +++++++++++--- drivers/net/tun.c | 9 ++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/net/tap.c b/drivers/net/tap.c index bdf0788d8..9d288a1ad 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -759,6 +759,8 @@ static ssize_t tap_do_read(struct tap_queue *q, { DEFINE_WAIT(wait); ssize_t ret = 0; + struct tap_dev *tap; + enum skb_drop_reason drop_reason = SKB_DROP_REASON_NOT_SPECIFIED; if (!iov_iter_count(to)) { kfree_skb(skb); @@ -794,10 +796,16 @@ static ssize_t tap_do_read(struct tap_queue *q, put: if (skb) { ret = tap_put_user(q, skb, to); - if (unlikely(ret < 0)) - kfree_skb(skb); - else + if (unlikely(ret < 0)) { + kfree_skb_reason(skb, drop_reason); + rcu_read_lock(); + tap = rcu_dereference(q->tap); + if (tap && tap->count_rx_dropped) + tap->count_rx_dropped(tap); + rcu_read_unlock(); + } else { consume_skb(skb); + } } return ret; } diff --git a/drivers/net/tun.c b/drivers/net/tun.c index f8c5e2fd0..eb3c68e5f 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -2137,6 +2137,7 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, { ssize_t ret; int err; + enum skb_drop_reason drop_reason = SKB_DROP_REASON_NOT_SPECIFIED; if (!iov_iter_count(to)) { tun_ptr_free(ptr); @@ -2159,10 +2160,12 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile, struct sk_buff *skb = ptr; ret = tun_put_user(tun, tfile, skb, to); - if (unlikely(ret < 0)) - kfree_skb(skb); - else + if (unlikely(ret < 0)) { + dev_core_stats_tx_dropped_inc(tun->dev); + kfree_skb_reason(skb, drop_reason); + } else { consume_skb(skb); + } } return ret; -- 2.31.1