From 6c206b20092a3623184cff9470dba75d21507874 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Fri, 8 Jun 2018 11:35:40 +0200 Subject: udp: fix rx queue len reported by diag and proc interface After commit 6b229cf77d68 ("udp: add batching to udp_rmem_release()") the sk_rmem_alloc field does not measure exactly anymore the receive queue length, because we batch the rmem release. The issue is really apparent only after commit 0d4a6608f68c ("udp: do rmem bulk free even if the rx sk queue is empty"): the user space can easily check for an empty socket with not-0 queue length reported by the 'ss' tool or the procfs interface. We need to use a custom UDP helper to report the correct queue length, taking into account the forward allocation deficit. Reported-by: trevor.francis@46labs.com Fixes: 6b229cf77d68 ("UDP: add batching to udp_rmem_release()") Signed-off-by: Paolo Abeni Signed-off-by: David S. Miller --- net/ipv4/udp.c | 2 +- net/ipv4/udp_diag.c | 2 +- net/ipv6/datagram.c | 6 +++--- net/ipv6/udp.c | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) (limited to 'net') diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 3365362cac88..9bb27df4dac5 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -2772,7 +2772,7 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f, " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d", bucket, src, srcp, dest, destp, sp->sk_state, sk_wmem_alloc_get(sp), - sk_rmem_alloc_get(sp), + udp_rqueue_get(sp), 0, 0L, 0, from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)), 0, sock_i_ino(sp), diff --git a/net/ipv4/udp_diag.c b/net/ipv4/udp_diag.c index d0390d844ac8..d9ad986c7b2c 100644 --- a/net/ipv4/udp_diag.c +++ b/net/ipv4/udp_diag.c @@ -163,7 +163,7 @@ static int udp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh, static void udp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, void *info) { - r->idiag_rqueue = sk_rmem_alloc_get(sk); + r->idiag_rqueue = udp_rqueue_get(sk); r->idiag_wqueue = sk_wmem_alloc_get(sk); } diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index a02ad100f0d7..2ee08b6a86a4 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -1019,8 +1019,8 @@ exit_f: } EXPORT_SYMBOL_GPL(ip6_datagram_send_ctl); -void ip6_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp, - __u16 srcp, __u16 destp, int bucket) +void __ip6_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp, + __u16 srcp, __u16 destp, int rqueue, int bucket) { const struct in6_addr *dest, *src; @@ -1036,7 +1036,7 @@ void ip6_dgram_sock_seq_show(struct seq_file *seq, struct sock *sp, dest->s6_addr32[2], dest->s6_addr32[3], destp, sp->sk_state, sk_wmem_alloc_get(sp), - sk_rmem_alloc_get(sp), + rqueue, 0, 0L, 0, from_kuid_munged(seq_user_ns(seq), sock_i_uid(sp)), 0, diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 164afd31aebf..e6645cae403e 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1523,7 +1523,8 @@ int udp6_seq_show(struct seq_file *seq, void *v) struct inet_sock *inet = inet_sk(v); __u16 srcp = ntohs(inet->inet_sport); __u16 destp = ntohs(inet->inet_dport); - ip6_dgram_sock_seq_show(seq, v, srcp, destp, bucket); + __ip6_dgram_sock_seq_show(seq, v, srcp, destp, + udp_rqueue_get(v), bucket); } return 0; } -- cgit v1.2.3-59-g8ed1b