net: correct off-by-one write allocations reports

commit 2b85a34e91
(net: No more expensive sock_hold()/sock_put() on each tx)
changed initial sk_wmem_alloc value.

We need to take into account this offset when reporting
sk_wmem_alloc to user, in PROC_FS files or various
ioctls (SIOCOUTQ/TIOCOUTQ)

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Eric Dumazet 2009-06-17 19:05:41 -07:00 committed by David S. Miller
parent d3b238a03e
commit 31e6d363ab
25 changed files with 58 additions and 51 deletions

View file

@ -204,8 +204,8 @@ static int atalk_seq_socket_show(struct seq_file *seq, void *v)
"%02X %d\n", "%02X %d\n",
s->sk_type, ntohs(at->src_net), at->src_node, at->src_port, s->sk_type, ntohs(at->src_net), at->src_node, at->src_port,
ntohs(at->dest_net), at->dest_node, at->dest_port, ntohs(at->dest_net), at->dest_node, at->dest_port,
atomic_read(&s->sk_wmem_alloc), sk_wmem_alloc_get(s),
atomic_read(&s->sk_rmem_alloc), sk_rmem_alloc_get(s),
s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); s->sk_state, SOCK_INODE(s->sk_socket)->i_uid);
out: out:
return 0; return 0;

View file

@ -1748,8 +1748,7 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
switch (cmd) { switch (cmd) {
/* Protocol layer */ /* Protocol layer */
case TIOCOUTQ: { case TIOCOUTQ: {
long amount = sk->sk_sndbuf - long amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
atomic_read(&sk->sk_wmem_alloc);
if (amount < 0) if (amount < 0)
amount = 0; amount = 0;

View file

@ -1690,7 +1690,8 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
switch (cmd) { switch (cmd) {
case TIOCOUTQ: { case TIOCOUTQ: {
long amount; long amount;
amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
if (amount < 0) if (amount < 0)
amount = 0; amount = 0;
res = put_user(amount, (int __user *)argp); res = put_user(amount, (int __user *)argp);
@ -1780,8 +1781,8 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
ax25_info.idletimer = ax25_display_timer(&ax25->idletimer) / (60 * HZ); ax25_info.idletimer = ax25_display_timer(&ax25->idletimer) / (60 * HZ);
ax25_info.n2count = ax25->n2count; ax25_info.n2count = ax25->n2count;
ax25_info.state = ax25->state; ax25_info.state = ax25->state;
ax25_info.rcv_q = atomic_read(&sk->sk_rmem_alloc); ax25_info.rcv_q = sk_wmem_alloc_get(sk);
ax25_info.snd_q = atomic_read(&sk->sk_wmem_alloc); ax25_info.snd_q = sk_rmem_alloc_get(sk);
ax25_info.vs = ax25->vs; ax25_info.vs = ax25->vs;
ax25_info.vr = ax25->vr; ax25_info.vr = ax25->vr;
ax25_info.va = ax25->va; ax25_info.va = ax25->va;
@ -1921,8 +1922,8 @@ static int ax25_info_show(struct seq_file *seq, void *v)
if (ax25->sk != NULL) { if (ax25->sk != NULL) {
seq_printf(seq, " %d %d %lu\n", seq_printf(seq, " %d %d %lu\n",
atomic_read(&ax25->sk->sk_wmem_alloc), sk_wmem_alloc_get(ax25->sk),
atomic_read(&ax25->sk->sk_rmem_alloc), sk_rmem_alloc_get(ax25->sk),
sock_i_ino(ax25->sk)); sock_i_ino(ax25->sk));
} else { } else {
seq_puts(seq, " * * *\n"); seq_puts(seq, " * * *\n");

View file

@ -337,7 +337,7 @@ int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
if (sk->sk_state == BT_LISTEN) if (sk->sk_state == BT_LISTEN)
return -EINVAL; return -EINVAL;
amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
if (amount < 0) if (amount < 0)
amount = 0; amount = 0;
err = put_user(amount, (int __user *) arg); err = put_user(amount, (int __user *) arg);

View file

@ -1240,7 +1240,7 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
return val; return val;
case TIOCOUTQ: case TIOCOUTQ:
amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
if (amount < 0) if (amount < 0)
amount = 0; amount = 0;
err = put_user(amount, (int __user *)arg); err = put_user(amount, (int __user *)arg);

View file

@ -126,7 +126,8 @@ static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg)
switch (cmd) { switch (cmd) {
case SIOCOUTQ: case SIOCOUTQ:
{ {
int amount = atomic_read(&sk->sk_wmem_alloc); int amount = sk_wmem_alloc_get(sk);
return put_user(amount, (int __user *)arg); return put_user(amount, (int __user *)arg);
} }

View file

@ -156,10 +156,10 @@ static int inet_csk_diag_fill(struct sock *sk,
r->idiag_inode = sock_i_ino(sk); r->idiag_inode = sock_i_ino(sk);
if (minfo) { if (minfo) {
minfo->idiag_rmem = atomic_read(&sk->sk_rmem_alloc); minfo->idiag_rmem = sk_rmem_alloc_get(sk);
minfo->idiag_wmem = sk->sk_wmem_queued; minfo->idiag_wmem = sk->sk_wmem_queued;
minfo->idiag_fmem = sk->sk_forward_alloc; minfo->idiag_fmem = sk->sk_forward_alloc;
minfo->idiag_tmem = atomic_read(&sk->sk_wmem_alloc); minfo->idiag_tmem = sk_wmem_alloc_get(sk);
} }
handler->idiag_get_info(sk, r, info); handler->idiag_get_info(sk, r, info);

View file

@ -799,7 +799,8 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg)
{ {
switch (cmd) { switch (cmd) {
case SIOCOUTQ: { case SIOCOUTQ: {
int amount = atomic_read(&sk->sk_wmem_alloc); int amount = sk_wmem_alloc_get(sk);
return put_user(amount, (int __user *)arg); return put_user(amount, (int __user *)arg);
} }
case SIOCINQ: { case SIOCINQ: {
@ -935,8 +936,8 @@ static void raw_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
seq_printf(seq, "%4d: %08X:%04X %08X:%04X" seq_printf(seq, "%4d: %08X:%04X %08X:%04X"
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n",
i, src, srcp, dest, destp, sp->sk_state, i, src, srcp, dest, destp, sp->sk_state,
atomic_read(&sp->sk_wmem_alloc), sk_wmem_alloc_get(sp),
atomic_read(&sp->sk_rmem_alloc), sk_rmem_alloc_get(sp),
0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
} }

View file

@ -840,7 +840,8 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
switch (cmd) { switch (cmd) {
case SIOCOUTQ: case SIOCOUTQ:
{ {
int amount = atomic_read(&sk->sk_wmem_alloc); int amount = sk_wmem_alloc_get(sk);
return put_user(amount, (int __user *)arg); return put_user(amount, (int __user *)arg);
} }
@ -1721,8 +1722,8 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f,
seq_printf(f, "%4d: %08X:%04X %08X:%04X" seq_printf(f, "%4d: %08X:%04X %08X:%04X"
" %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d%n", " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d%n",
bucket, src, srcp, dest, destp, sp->sk_state, bucket, src, srcp, dest, destp, sp->sk_state,
atomic_read(&sp->sk_wmem_alloc), sk_wmem_alloc_get(sp),
atomic_read(&sp->sk_rmem_alloc), sk_rmem_alloc_get(sp),
0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_refcnt), sp,
atomic_read(&sp->sk_drops), len); atomic_read(&sp->sk_drops), len);

View file

@ -1130,7 +1130,8 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg)
switch(cmd) { switch(cmd) {
case SIOCOUTQ: case SIOCOUTQ:
{ {
int amount = atomic_read(&sk->sk_wmem_alloc); int amount = sk_wmem_alloc_get(sk);
return put_user(amount, (int __user *)arg); return put_user(amount, (int __user *)arg);
} }
case SIOCINQ: case SIOCINQ:
@ -1236,8 +1237,8 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
dest->s6_addr32[0], dest->s6_addr32[1], dest->s6_addr32[0], dest->s6_addr32[1],
dest->s6_addr32[2], dest->s6_addr32[3], destp, dest->s6_addr32[2], dest->s6_addr32[3], destp,
sp->sk_state, sp->sk_state,
atomic_read(&sp->sk_wmem_alloc), sk_wmem_alloc_get(sp),
atomic_read(&sp->sk_rmem_alloc), sk_rmem_alloc_get(sp),
0, 0L, 0, 0, 0L, 0,
sock_i_uid(sp), 0, sock_i_uid(sp), 0,
sock_i_ino(sp), sock_i_ino(sp),

View file

@ -1061,8 +1061,8 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket
dest->s6_addr32[0], dest->s6_addr32[1], dest->s6_addr32[0], dest->s6_addr32[1],
dest->s6_addr32[2], dest->s6_addr32[3], destp, dest->s6_addr32[2], dest->s6_addr32[3], destp,
sp->sk_state, sp->sk_state,
atomic_read(&sp->sk_wmem_alloc), sk_wmem_alloc_get(sp),
atomic_read(&sp->sk_rmem_alloc), sk_rmem_alloc_get(sp),
0, 0L, 0, 0, 0L, 0,
sock_i_uid(sp), 0, sock_i_uid(sp), 0,
sock_i_ino(sp), sock_i_ino(sp),

View file

@ -1835,7 +1835,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
switch (cmd) { switch (cmd) {
case TIOCOUTQ: case TIOCOUTQ:
amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
if (amount < 0) if (amount < 0)
amount = 0; amount = 0;
rc = put_user(amount, (int __user *)argp); rc = put_user(amount, (int __user *)argp);

View file

@ -280,8 +280,8 @@ static int ipx_seq_socket_show(struct seq_file *seq, void *v)
} }
seq_printf(seq, "%08X %08X %02X %03d\n", seq_printf(seq, "%08X %08X %02X %03d\n",
atomic_read(&s->sk_wmem_alloc), sk_wmem_alloc_get(s),
atomic_read(&s->sk_rmem_alloc), sk_rmem_alloc_get(s),
s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); s->sk_state, SOCK_INODE(s->sk_socket)->i_uid);
out: out:
return 0; return 0;

View file

@ -1762,7 +1762,8 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
switch (cmd) { switch (cmd) {
case TIOCOUTQ: { case TIOCOUTQ: {
long amount; long amount;
amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
if (amount < 0) if (amount < 0)
amount = 0; amount = 0;
if (put_user(amount, (unsigned int __user *)arg)) if (put_user(amount, (unsigned int __user *)arg))

View file

@ -3662,8 +3662,8 @@ static int pfkey_seq_show(struct seq_file *f, void *v)
seq_printf(f ,"%p %-6d %-6u %-6u %-6u %-6lu\n", seq_printf(f ,"%p %-6d %-6u %-6u %-6u %-6lu\n",
s, s,
atomic_read(&s->sk_refcnt), atomic_read(&s->sk_refcnt),
atomic_read(&s->sk_rmem_alloc), sk_rmem_alloc_get(s),
atomic_read(&s->sk_wmem_alloc), sk_wmem_alloc_get(s),
sock_i_uid(s), sock_i_uid(s),
sock_i_ino(s) sock_i_ino(s)
); );

View file

@ -134,8 +134,8 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v)
seq_printf(seq, "@%02X ", llc->sap->laddr.lsap); seq_printf(seq, "@%02X ", llc->sap->laddr.lsap);
llc_ui_format_mac(seq, llc->daddr.mac); llc_ui_format_mac(seq, llc->daddr.mac);
seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap, seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap,
atomic_read(&sk->sk_wmem_alloc), sk_wmem_alloc_get(sk),
atomic_read(&sk->sk_rmem_alloc) - llc->copied_seq, sk_rmem_alloc_get(sk) - llc->copied_seq,
sk->sk_state, sk->sk_state,
sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1, sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1,
llc->link); llc->link);

View file

@ -1914,8 +1914,8 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
s->sk_protocol, s->sk_protocol,
nlk->pid, nlk->pid,
nlk->groups ? (u32)nlk->groups[0] : 0, nlk->groups ? (u32)nlk->groups[0] : 0,
atomic_read(&s->sk_rmem_alloc), sk_rmem_alloc_get(s),
atomic_read(&s->sk_wmem_alloc), sk_wmem_alloc_get(s),
nlk->cb, nlk->cb,
atomic_read(&s->sk_refcnt), atomic_read(&s->sk_refcnt),
atomic_read(&s->sk_drops) atomic_read(&s->sk_drops)

View file

@ -1205,7 +1205,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
long amount; long amount;
lock_sock(sk); lock_sock(sk);
amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
if (amount < 0) if (amount < 0)
amount = 0; amount = 0;
release_sock(sk); release_sock(sk);
@ -1341,8 +1341,8 @@ static int nr_info_show(struct seq_file *seq, void *v)
nr->n2count, nr->n2count,
nr->n2, nr->n2,
nr->window, nr->window,
atomic_read(&s->sk_wmem_alloc), sk_wmem_alloc_get(s),
atomic_read(&s->sk_rmem_alloc), sk_rmem_alloc_get(s),
s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L);
bh_unlock_sock(s); bh_unlock_sock(s);

View file

@ -1987,7 +1987,8 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,
switch (cmd) { switch (cmd) {
case SIOCOUTQ: case SIOCOUTQ:
{ {
int amount = atomic_read(&sk->sk_wmem_alloc); int amount = sk_wmem_alloc_get(sk);
return put_user(amount, (int __user *)arg); return put_user(amount, (int __user *)arg);
} }
case SIOCINQ: case SIOCINQ:

View file

@ -1309,7 +1309,8 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
switch (cmd) { switch (cmd) {
case TIOCOUTQ: { case TIOCOUTQ: {
long amount; long amount;
amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
if (amount < 0) if (amount < 0)
amount = 0; amount = 0;
return put_user(amount, (unsigned int __user *) argp); return put_user(amount, (unsigned int __user *) argp);
@ -1480,8 +1481,8 @@ static int rose_info_show(struct seq_file *seq, void *v)
rose->hb / HZ, rose->hb / HZ,
ax25_display_timer(&rose->idletimer) / (60 * HZ), ax25_display_timer(&rose->idletimer) / (60 * HZ),
rose->idle / (60 * HZ), rose->idle / (60 * HZ),
atomic_read(&s->sk_wmem_alloc), sk_wmem_alloc_get(s),
atomic_read(&s->sk_rmem_alloc), sk_rmem_alloc_get(s),
s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L);
} }

View file

@ -349,13 +349,13 @@ META_COLLECTOR(int_sk_type)
META_COLLECTOR(int_sk_rmem_alloc) META_COLLECTOR(int_sk_rmem_alloc)
{ {
SKIP_NONLOCAL(skb); SKIP_NONLOCAL(skb);
dst->value = atomic_read(&skb->sk->sk_rmem_alloc); dst->value = sk_rmem_alloc_get(skb->sk);
} }
META_COLLECTOR(int_sk_wmem_alloc) META_COLLECTOR(int_sk_wmem_alloc)
{ {
SKIP_NONLOCAL(skb); SKIP_NONLOCAL(skb);
dst->value = atomic_read(&skb->sk->sk_wmem_alloc); dst->value = sk_wmem_alloc_get(skb->sk);
} }
META_COLLECTOR(int_sk_omem_alloc) META_COLLECTOR(int_sk_omem_alloc)

View file

@ -130,7 +130,7 @@ static inline int sctp_wspace(struct sctp_association *asoc)
if (asoc->ep->sndbuf_policy) if (asoc->ep->sndbuf_policy)
amt = asoc->sndbuf_used; amt = asoc->sndbuf_used;
else else
amt = atomic_read(&asoc->base.sk->sk_wmem_alloc); amt = sk_wmem_alloc_get(asoc->base.sk);
if (amt >= asoc->base.sk->sk_sndbuf) { if (amt >= asoc->base.sk->sk_sndbuf) {
if (asoc->base.sk->sk_userlocks & SOCK_SNDBUF_LOCK) if (asoc->base.sk->sk_userlocks & SOCK_SNDBUF_LOCK)
@ -6523,7 +6523,7 @@ static int sctp_writeable(struct sock *sk)
{ {
int amt = 0; int amt = 0;
amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); amt = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
if (amt < 0) if (amt < 0)
amt = 0; amt = 0;
return amt; return amt;

View file

@ -1946,7 +1946,7 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
switch (cmd) { switch (cmd) {
case SIOCOUTQ: case SIOCOUTQ:
amount = atomic_read(&sk->sk_wmem_alloc); amount = sk_wmem_alloc_get(sk);
err = put_user(amount, (int __user *)arg); err = put_user(amount, (int __user *)arg);
break; break;
case SIOCINQ: case SIOCINQ:

View file

@ -1271,8 +1271,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
switch (cmd) { switch (cmd) {
case TIOCOUTQ: { case TIOCOUTQ: {
int amount = sk->sk_sndbuf - int amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
atomic_read(&sk->sk_wmem_alloc);
if (amount < 0) if (amount < 0)
amount = 0; amount = 0;
rc = put_user(amount, (unsigned int __user *)argp); rc = put_user(amount, (unsigned int __user *)argp);

View file

@ -163,8 +163,8 @@ static int x25_seq_socket_show(struct seq_file *seq, void *v)
devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr, devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr,
x25->va, x25_display_timer(s) / HZ, x25->t2 / HZ, x25->va, x25_display_timer(s) / HZ, x25->t2 / HZ,
x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ, x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ,
atomic_read(&s->sk_wmem_alloc), sk_wmem_alloc_get(s),
atomic_read(&s->sk_rmem_alloc), sk_rmem_alloc_get(s),
s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L);
out: out:
return 0; return 0;