diff options
author | Benjamin LaHaise <benjamin.c.lahaise@intel.com> | 2005-12-14 08:22:32 +0100 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-01-03 22:10:45 +0100 |
commit | 830a1e5c212fb3fdc83b66359c780c3b3a294897 (patch) | |
tree | 232215af3774d78aa179adb1612bfa5257af181d /net/unix | |
parent | [NET]: Avoid atomic xchg() for non-error case (diff) | |
download | linux-830a1e5c212fb3fdc83b66359c780c3b3a294897.tar.xz linux-830a1e5c212fb3fdc83b66359c780c3b3a294897.zip |
[AF_UNIX]: Remove superfluous reference counting in unix_stream_sendmsg
AF_UNIX stream socket performance on P4 CPUs tends to suffer due to a
lot of pipeline flushes from atomic operations. The patch below
removes the sock_hold() and sock_put() in unix_stream_sendmsg(). This
should be safe as the socket still holds a reference to its peer which
is only released after the file descriptor's final user invokes
unix_release_sock(). The only consideration is that we must add a
memory barrier before setting the peer initially.
Signed-off-by: Benjamin LaHaise <benjamin.c.lahaise@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/unix')
-rw-r--r-- | net/unix/af_unix.c | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index acc73ba8bade..1dc3685048f3 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1063,10 +1063,12 @@ restart: /* Set credentials */ sk->sk_peercred = other->sk_peercred; - sock_hold(newsk); - unix_peer(sk) = newsk; sock->state = SS_CONNECTED; sk->sk_state = TCP_ESTABLISHED; + sock_hold(newsk); + + smp_mb__after_atomic_inc(); /* sock_hold() does an atomic_inc() */ + unix_peer(sk) = newsk; unix_state_wunlock(sk); @@ -1414,7 +1416,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, } else { sunaddr = NULL; err = -ENOTCONN; - other = unix_peer_get(sk); + other = unix_peer(sk); if (!other) goto out_err; } @@ -1476,7 +1478,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, other->sk_data_ready(other, size); sent+=size; } - sock_put(other); scm_destroy(siocb->scm); siocb->scm = NULL; @@ -1491,8 +1492,6 @@ pipe_err: send_sig(SIGPIPE,current,0); err = -EPIPE; out_err: - if (other) - sock_put(other); scm_destroy(siocb->scm); siocb->scm = NULL; return sent ? : err; |