summaryrefslogtreecommitdiff
path: root/net/unix
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-09-17 03:34:00 +0400
committerDavid S. Miller <davem@davemloft.net>2011-09-17 03:34:00 +0400
commitf78a5fda9116525809d088917638be912b85f838 (patch)
treeab6d7edaa915cea74d6c664c3e39a5ad15bab0f8 /net/unix
parent473e64ee4603671efa1e0785418e56e9ffdfc47b (diff)
downloadlinux-f78a5fda9116525809d088917638be912b85f838.tar.xz
Revert "Scm: Remove unnecessary pid & credential references in Unix socket's send and receive path"
This reverts commit 0856a304091b33a8e8f9f9c98e776f425af2b625. As requested by Eric Dumazet, it has various ref-counting problems and has introduced regressions. Eric will add a more suitable version of this performance fix. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/unix')
-rw-r--r--net/unix/af_unix.c45
1 files changed, 16 insertions, 29 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index e6d9d1014ed2..ec68e1c05b85 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1378,17 +1378,11 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
return max_level;
}
-static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb,
- bool send_fds, bool ref)
+static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
{
int err = 0;
- if (ref) {
- UNIXCB(skb).pid = get_pid(scm->pid);
- UNIXCB(skb).cred = get_cred(scm->cred);
- } else {
- UNIXCB(skb).pid = scm->pid;
- UNIXCB(skb).cred = scm->cred;
- }
+ UNIXCB(skb).pid = get_pid(scm->pid);
+ UNIXCB(skb).cred = get_cred(scm->cred);
UNIXCB(skb).fp = NULL;
if (scm->fp && send_fds)
err = unix_attach_fds(scm, skb);
@@ -1413,7 +1407,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
int namelen = 0; /* fake GCC */
int err;
unsigned hash;
- struct sk_buff *skb = NULL;
+ struct sk_buff *skb;
long timeo;
struct scm_cookie tmp_scm;
int max_level;
@@ -1454,7 +1448,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
if (skb == NULL)
goto out;
- err = unix_scm_to_skb(siocb->scm, skb, true, false);
+ err = unix_scm_to_skb(siocb->scm, skb, true);
if (err < 0)
goto out_free;
max_level = err + 1;
@@ -1550,7 +1544,7 @@ restart:
unix_state_unlock(other);
other->sk_data_ready(other, len);
sock_put(other);
- scm_release(siocb->scm);
+ scm_destroy(siocb->scm);
return len;
out_unlock:
@@ -1560,8 +1554,7 @@ out_free:
out:
if (other)
sock_put(other);
- if (skb == NULL)
- scm_destroy(siocb->scm);
+ scm_destroy(siocb->scm);
return err;
}
@@ -1573,7 +1566,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
struct sock *sk = sock->sk;
struct sock *other = NULL;
int err, size;
- struct sk_buff *skb = NULL;
+ struct sk_buff *skb;
int sent = 0;
struct scm_cookie tmp_scm;
bool fds_sent = false;
@@ -1638,11 +1631,11 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
size = min_t(int, size, skb_tailroom(skb));
- /* Only send the fds and no ref to pid in the first buffer */
- err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, fds_sent);
+ /* Only send the fds in the first buffer */
+ err = unix_scm_to_skb(siocb->scm, skb, !fds_sent);
if (err < 0) {
kfree_skb(skb);
- goto out;
+ goto out_err;
}
max_level = err + 1;
fds_sent = true;
@@ -1650,7 +1643,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
if (err) {
kfree_skb(skb);
- goto out;
+ goto out_err;
}
unix_state_lock(other);
@@ -1667,10 +1660,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
sent += size;
}
- if (skb)
- scm_release(siocb->scm);
- else
- scm_destroy(siocb->scm);
+ scm_destroy(siocb->scm);
siocb->scm = NULL;
return sent;
@@ -1683,9 +1673,7 @@ pipe_err:
send_sig(SIGPIPE, current, 0);
err = -EPIPE;
out_err:
- if (skb == NULL)
- scm_destroy(siocb->scm);
-out:
+ scm_destroy(siocb->scm);
siocb->scm = NULL;
return sent ? : err;
}
@@ -1789,7 +1777,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
siocb->scm = &tmp_scm;
memset(&tmp_scm, 0, sizeof(tmp_scm));
}
- scm_set_cred_noref(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
+ scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
unix_set_secdata(siocb->scm, skb);
if (!(flags & MSG_PEEK)) {
@@ -1951,8 +1939,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
}
} else {
/* Copy credentials */
- scm_set_cred_noref(siocb->scm, UNIXCB(skb).pid,
- UNIXCB(skb).cred);
+ scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
check_creds = 1;
}