Commit 830a1e5c authored by Benjamin LaHaise's avatar Benjamin LaHaise Committed by David S. Miller

[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: default avatarBenjamin LaHaise <benjamin.c.lahaise@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c1cbe4b7
...@@ -1063,10 +1063,12 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, ...@@ -1063,10 +1063,12 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
/* Set credentials */ /* Set credentials */
sk->sk_peercred = other->sk_peercred; sk->sk_peercred = other->sk_peercred;
sock_hold(newsk);
unix_peer(sk) = newsk;
sock->state = SS_CONNECTED; sock->state = SS_CONNECTED;
sk->sk_state = TCP_ESTABLISHED; 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); unix_state_wunlock(sk);
...@@ -1414,7 +1416,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, ...@@ -1414,7 +1416,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
} else { } else {
sunaddr = NULL; sunaddr = NULL;
err = -ENOTCONN; err = -ENOTCONN;
other = unix_peer_get(sk); other = unix_peer(sk);
if (!other) if (!other)
goto out_err; goto out_err;
} }
...@@ -1476,7 +1478,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, ...@@ -1476,7 +1478,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
other->sk_data_ready(other, size); other->sk_data_ready(other, size);
sent+=size; sent+=size;
} }
sock_put(other);
scm_destroy(siocb->scm); scm_destroy(siocb->scm);
siocb->scm = NULL; siocb->scm = NULL;
...@@ -1491,8 +1492,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, ...@@ -1491,8 +1492,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
send_sig(SIGPIPE,current,0); send_sig(SIGPIPE,current,0);
err = -EPIPE; err = -EPIPE;
out_err: out_err:
if (other)
sock_put(other);
scm_destroy(siocb->scm); scm_destroy(siocb->scm);
siocb->scm = NULL; siocb->scm = NULL;
return sent ? : err; return sent ? : err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment