[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>
This commit is contained in:
parent
c1cbe4b7ad
commit
830a1e5c21
@ -1063,10 +1063,12 @@ restart:
|
|||||||
/* 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,
|
|||||||
} 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,
|
|||||||
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 @@ pipe_err:
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user