Skip to content

Commit

Permalink
Revert "Scm: Remove unnecessary pid & credential references in Unix s…
Browse files Browse the repository at this point in the history
…ocket's send and receive path"

This reverts commit 0856a30.

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>
  • Loading branch information
David S. Miller committed Sep 16, 2011
1 parent 473e64e commit f78a5fd
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 48 deletions.
22 changes: 3 additions & 19 deletions include/net/scm.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,6 @@ static __inline__ void scm_set_cred(struct scm_cookie *scm,
cred_to_ucred(pid, cred, &scm->creds);
}

static __inline__ void scm_set_cred_noref(struct scm_cookie *scm,
struct pid *pid, const struct cred *cred)
{
scm->pid = pid;
scm->cred = cred;
cred_to_ucred(pid, cred, &scm->creds);
}

static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
{
put_pid(scm->pid);
Expand All @@ -78,15 +70,6 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
__scm_destroy(scm);
}

static __inline__ void scm_release(struct scm_cookie *scm)
{
/* keep ref on pid and cred */
scm->pid = NULL;
scm->cred = NULL;
if (scm->fp)
__scm_destroy(scm);
}

static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
struct scm_cookie *scm)
{
Expand Down Expand Up @@ -125,14 +108,15 @@ static __inline__ void scm_recv(struct socket *sock, struct msghdr *msg,
if (!msg->msg_control) {
if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp)
msg->msg_flags |= MSG_CTRUNC;
if (scm && scm->fp)
__scm_destroy(scm);
scm_destroy(scm);
return;
}

if (test_bit(SOCK_PASSCRED, &sock->flags))
put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds);

scm_destroy_cred(scm);

scm_passec(sock, msg, scm);

if (!scm->fp)
Expand Down
45 changes: 16 additions & 29 deletions net/unix/af_unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1550,7 +1544,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
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:
Expand All @@ -1560,8 +1554,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
out:
if (other)
sock_put(other);
if (skb == NULL)
scm_destroy(siocb->scm);
scm_destroy(siocb->scm);
return err;
}

Expand All @@ -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;
Expand Down Expand Up @@ -1638,19 +1631,19 @@ 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;

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);
Expand All @@ -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;
Expand All @@ -1683,9 +1673,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
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;
}
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit f78a5fd

Please sign in to comment.