diff options
author | David S. Miller <davem@davemloft.net> | 2011-09-16 19:34:00 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-09-16 19:34:00 -0400 |
commit | f78a5fda9116525809d088917638be912b85f838 (patch) | |
tree | ab6d7edaa915cea74d6c664c3e39a5ad15bab0f8 /net/unix/af_unix.c | |
parent | 473e64ee4603671efa1e0785418e56e9ffdfc47b (diff) |
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/af_unix.c')
-rw-r--r-- | net/unix/af_unix.c | 45 |
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) | |||
1378 | return max_level; | 1378 | return max_level; |
1379 | } | 1379 | } |
1380 | 1380 | ||
1381 | static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, | 1381 | static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) |
1382 | bool send_fds, bool ref) | ||
1383 | { | 1382 | { |
1384 | int err = 0; | 1383 | int err = 0; |
1385 | if (ref) { | 1384 | UNIXCB(skb).pid = get_pid(scm->pid); |
1386 | UNIXCB(skb).pid = get_pid(scm->pid); | 1385 | UNIXCB(skb).cred = get_cred(scm->cred); |
1387 | UNIXCB(skb).cred = get_cred(scm->cred); | ||
1388 | } else { | ||
1389 | UNIXCB(skb).pid = scm->pid; | ||
1390 | UNIXCB(skb).cred = scm->cred; | ||
1391 | } | ||
1392 | UNIXCB(skb).fp = NULL; | 1386 | UNIXCB(skb).fp = NULL; |
1393 | if (scm->fp && send_fds) | 1387 | if (scm->fp && send_fds) |
1394 | err = unix_attach_fds(scm, skb); | 1388 | err = unix_attach_fds(scm, skb); |
@@ -1413,7 +1407,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1413 | int namelen = 0; /* fake GCC */ | 1407 | int namelen = 0; /* fake GCC */ |
1414 | int err; | 1408 | int err; |
1415 | unsigned hash; | 1409 | unsigned hash; |
1416 | struct sk_buff *skb = NULL; | 1410 | struct sk_buff *skb; |
1417 | long timeo; | 1411 | long timeo; |
1418 | struct scm_cookie tmp_scm; | 1412 | struct scm_cookie tmp_scm; |
1419 | int max_level; | 1413 | int max_level; |
@@ -1454,7 +1448,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1454 | if (skb == NULL) | 1448 | if (skb == NULL) |
1455 | goto out; | 1449 | goto out; |
1456 | 1450 | ||
1457 | err = unix_scm_to_skb(siocb->scm, skb, true, false); | 1451 | err = unix_scm_to_skb(siocb->scm, skb, true); |
1458 | if (err < 0) | 1452 | if (err < 0) |
1459 | goto out_free; | 1453 | goto out_free; |
1460 | max_level = err + 1; | 1454 | max_level = err + 1; |
@@ -1550,7 +1544,7 @@ restart: | |||
1550 | unix_state_unlock(other); | 1544 | unix_state_unlock(other); |
1551 | other->sk_data_ready(other, len); | 1545 | other->sk_data_ready(other, len); |
1552 | sock_put(other); | 1546 | sock_put(other); |
1553 | scm_release(siocb->scm); | 1547 | scm_destroy(siocb->scm); |
1554 | return len; | 1548 | return len; |
1555 | 1549 | ||
1556 | out_unlock: | 1550 | out_unlock: |
@@ -1560,8 +1554,7 @@ out_free: | |||
1560 | out: | 1554 | out: |
1561 | if (other) | 1555 | if (other) |
1562 | sock_put(other); | 1556 | sock_put(other); |
1563 | if (skb == NULL) | 1557 | scm_destroy(siocb->scm); |
1564 | scm_destroy(siocb->scm); | ||
1565 | return err; | 1558 | return err; |
1566 | } | 1559 | } |
1567 | 1560 | ||
@@ -1573,7 +1566,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1573 | struct sock *sk = sock->sk; | 1566 | struct sock *sk = sock->sk; |
1574 | struct sock *other = NULL; | 1567 | struct sock *other = NULL; |
1575 | int err, size; | 1568 | int err, size; |
1576 | struct sk_buff *skb = NULL; | 1569 | struct sk_buff *skb; |
1577 | int sent = 0; | 1570 | int sent = 0; |
1578 | struct scm_cookie tmp_scm; | 1571 | struct scm_cookie tmp_scm; |
1579 | bool fds_sent = false; | 1572 | bool fds_sent = false; |
@@ -1638,11 +1631,11 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1638 | size = min_t(int, size, skb_tailroom(skb)); | 1631 | size = min_t(int, size, skb_tailroom(skb)); |
1639 | 1632 | ||
1640 | 1633 | ||
1641 | /* Only send the fds and no ref to pid in the first buffer */ | 1634 | /* Only send the fds in the first buffer */ |
1642 | err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, fds_sent); | 1635 | err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); |
1643 | if (err < 0) { | 1636 | if (err < 0) { |
1644 | kfree_skb(skb); | 1637 | kfree_skb(skb); |
1645 | goto out; | 1638 | goto out_err; |
1646 | } | 1639 | } |
1647 | max_level = err + 1; | 1640 | max_level = err + 1; |
1648 | fds_sent = true; | 1641 | fds_sent = true; |
@@ -1650,7 +1643,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1650 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 1643 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); |
1651 | if (err) { | 1644 | if (err) { |
1652 | kfree_skb(skb); | 1645 | kfree_skb(skb); |
1653 | goto out; | 1646 | goto out_err; |
1654 | } | 1647 | } |
1655 | 1648 | ||
1656 | unix_state_lock(other); | 1649 | unix_state_lock(other); |
@@ -1667,10 +1660,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1667 | sent += size; | 1660 | sent += size; |
1668 | } | 1661 | } |
1669 | 1662 | ||
1670 | if (skb) | 1663 | scm_destroy(siocb->scm); |
1671 | scm_release(siocb->scm); | ||
1672 | else | ||
1673 | scm_destroy(siocb->scm); | ||
1674 | siocb->scm = NULL; | 1664 | siocb->scm = NULL; |
1675 | 1665 | ||
1676 | return sent; | 1666 | return sent; |
@@ -1683,9 +1673,7 @@ pipe_err: | |||
1683 | send_sig(SIGPIPE, current, 0); | 1673 | send_sig(SIGPIPE, current, 0); |
1684 | err = -EPIPE; | 1674 | err = -EPIPE; |
1685 | out_err: | 1675 | out_err: |
1686 | if (skb == NULL) | 1676 | scm_destroy(siocb->scm); |
1687 | scm_destroy(siocb->scm); | ||
1688 | out: | ||
1689 | siocb->scm = NULL; | 1677 | siocb->scm = NULL; |
1690 | return sent ? : err; | 1678 | return sent ? : err; |
1691 | } | 1679 | } |
@@ -1789,7 +1777,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1789 | siocb->scm = &tmp_scm; | 1777 | siocb->scm = &tmp_scm; |
1790 | memset(&tmp_scm, 0, sizeof(tmp_scm)); | 1778 | memset(&tmp_scm, 0, sizeof(tmp_scm)); |
1791 | } | 1779 | } |
1792 | scm_set_cred_noref(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); | 1780 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); |
1793 | unix_set_secdata(siocb->scm, skb); | 1781 | unix_set_secdata(siocb->scm, skb); |
1794 | 1782 | ||
1795 | if (!(flags & MSG_PEEK)) { | 1783 | if (!(flags & MSG_PEEK)) { |
@@ -1951,8 +1939,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1951 | } | 1939 | } |
1952 | } else { | 1940 | } else { |
1953 | /* Copy credentials */ | 1941 | /* Copy credentials */ |
1954 | scm_set_cred_noref(siocb->scm, UNIXCB(skb).pid, | 1942 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); |
1955 | UNIXCB(skb).cred); | ||
1956 | check_creds = 1; | 1943 | check_creds = 1; |
1957 | } | 1944 | } |
1958 | 1945 | ||