Commit f78a5fda9116525809d088917638be912b85f838
1 parent
473e64ee46
Exists in
master
and in
38 other branches
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>
Showing 2 changed files with 19 additions and 48 deletions Side-by-side Diff
include/net/scm.h
... | ... | @@ -53,14 +53,6 @@ |
53 | 53 | cred_to_ucred(pid, cred, &scm->creds); |
54 | 54 | } |
55 | 55 | |
56 | -static __inline__ void scm_set_cred_noref(struct scm_cookie *scm, | |
57 | - struct pid *pid, const struct cred *cred) | |
58 | -{ | |
59 | - scm->pid = pid; | |
60 | - scm->cred = cred; | |
61 | - cred_to_ucred(pid, cred, &scm->creds); | |
62 | -} | |
63 | - | |
64 | 56 | static __inline__ void scm_destroy_cred(struct scm_cookie *scm) |
65 | 57 | { |
66 | 58 | put_pid(scm->pid); |
... | ... | @@ -78,15 +70,6 @@ |
78 | 70 | __scm_destroy(scm); |
79 | 71 | } |
80 | 72 | |
81 | -static __inline__ void scm_release(struct scm_cookie *scm) | |
82 | -{ | |
83 | - /* keep ref on pid and cred */ | |
84 | - scm->pid = NULL; | |
85 | - scm->cred = NULL; | |
86 | - if (scm->fp) | |
87 | - __scm_destroy(scm); | |
88 | -} | |
89 | - | |
90 | 73 | static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, |
91 | 74 | struct scm_cookie *scm) |
92 | 75 | { |
93 | 76 | |
... | ... | @@ -125,13 +108,14 @@ |
125 | 108 | if (!msg->msg_control) { |
126 | 109 | if (test_bit(SOCK_PASSCRED, &sock->flags) || scm->fp) |
127 | 110 | msg->msg_flags |= MSG_CTRUNC; |
128 | - if (scm && scm->fp) | |
129 | - __scm_destroy(scm); | |
111 | + scm_destroy(scm); | |
130 | 112 | return; |
131 | 113 | } |
132 | 114 | |
133 | 115 | if (test_bit(SOCK_PASSCRED, &sock->flags)) |
134 | 116 | put_cmsg(msg, SOL_SOCKET, SCM_CREDENTIALS, sizeof(scm->creds), &scm->creds); |
117 | + | |
118 | + scm_destroy_cred(scm); | |
135 | 119 | |
136 | 120 | scm_passec(sock, msg, scm); |
137 | 121 |
net/unix/af_unix.c
... | ... | @@ -1378,17 +1378,11 @@ |
1378 | 1378 | return max_level; |
1379 | 1379 | } |
1380 | 1380 | |
1381 | -static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, | |
1382 | - bool send_fds, bool ref) | |
1381 | +static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) | |
1383 | 1382 | { |
1384 | 1383 | int err = 0; |
1385 | - if (ref) { | |
1386 | - UNIXCB(skb).pid = get_pid(scm->pid); | |
1387 | - UNIXCB(skb).cred = get_cred(scm->cred); | |
1388 | - } else { | |
1389 | - UNIXCB(skb).pid = scm->pid; | |
1390 | - UNIXCB(skb).cred = scm->cred; | |
1391 | - } | |
1384 | + UNIXCB(skb).pid = get_pid(scm->pid); | |
1385 | + UNIXCB(skb).cred = get_cred(scm->cred); | |
1392 | 1386 | UNIXCB(skb).fp = NULL; |
1393 | 1387 | if (scm->fp && send_fds) |
1394 | 1388 | err = unix_attach_fds(scm, skb); |
... | ... | @@ -1413,7 +1407,7 @@ |
1413 | 1407 | int namelen = 0; /* fake GCC */ |
1414 | 1408 | int err; |
1415 | 1409 | unsigned hash; |
1416 | - struct sk_buff *skb = NULL; | |
1410 | + struct sk_buff *skb; | |
1417 | 1411 | long timeo; |
1418 | 1412 | struct scm_cookie tmp_scm; |
1419 | 1413 | int max_level; |
... | ... | @@ -1454,7 +1448,7 @@ |
1454 | 1448 | if (skb == NULL) |
1455 | 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 | 1452 | if (err < 0) |
1459 | 1453 | goto out_free; |
1460 | 1454 | max_level = err + 1; |
... | ... | @@ -1550,7 +1544,7 @@ |
1550 | 1544 | unix_state_unlock(other); |
1551 | 1545 | other->sk_data_ready(other, len); |
1552 | 1546 | sock_put(other); |
1553 | - scm_release(siocb->scm); | |
1547 | + scm_destroy(siocb->scm); | |
1554 | 1548 | return len; |
1555 | 1549 | |
1556 | 1550 | out_unlock: |
... | ... | @@ -1560,8 +1554,7 @@ |
1560 | 1554 | out: |
1561 | 1555 | if (other) |
1562 | 1556 | sock_put(other); |
1563 | - if (skb == NULL) | |
1564 | - scm_destroy(siocb->scm); | |
1557 | + scm_destroy(siocb->scm); | |
1565 | 1558 | return err; |
1566 | 1559 | } |
1567 | 1560 | |
... | ... | @@ -1573,7 +1566,7 @@ |
1573 | 1566 | struct sock *sk = sock->sk; |
1574 | 1567 | struct sock *other = NULL; |
1575 | 1568 | int err, size; |
1576 | - struct sk_buff *skb = NULL; | |
1569 | + struct sk_buff *skb; | |
1577 | 1570 | int sent = 0; |
1578 | 1571 | struct scm_cookie tmp_scm; |
1579 | 1572 | bool fds_sent = false; |
1580 | 1573 | |
... | ... | @@ -1638,11 +1631,11 @@ |
1638 | 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 */ | |
1642 | - err = unix_scm_to_skb(siocb->scm, skb, !fds_sent, fds_sent); | |
1634 | + /* Only send the fds in the first buffer */ | |
1635 | + err = unix_scm_to_skb(siocb->scm, skb, !fds_sent); | |
1643 | 1636 | if (err < 0) { |
1644 | 1637 | kfree_skb(skb); |
1645 | - goto out; | |
1638 | + goto out_err; | |
1646 | 1639 | } |
1647 | 1640 | max_level = err + 1; |
1648 | 1641 | fds_sent = true; |
... | ... | @@ -1650,7 +1643,7 @@ |
1650 | 1643 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); |
1651 | 1644 | if (err) { |
1652 | 1645 | kfree_skb(skb); |
1653 | - goto out; | |
1646 | + goto out_err; | |
1654 | 1647 | } |
1655 | 1648 | |
1656 | 1649 | unix_state_lock(other); |
... | ... | @@ -1667,10 +1660,7 @@ |
1667 | 1660 | sent += size; |
1668 | 1661 | } |
1669 | 1662 | |
1670 | - if (skb) | |
1671 | - scm_release(siocb->scm); | |
1672 | - else | |
1673 | - scm_destroy(siocb->scm); | |
1663 | + scm_destroy(siocb->scm); | |
1674 | 1664 | siocb->scm = NULL; |
1675 | 1665 | |
1676 | 1666 | return sent; |
... | ... | @@ -1683,9 +1673,7 @@ |
1683 | 1673 | send_sig(SIGPIPE, current, 0); |
1684 | 1674 | err = -EPIPE; |
1685 | 1675 | out_err: |
1686 | - if (skb == NULL) | |
1687 | - scm_destroy(siocb->scm); | |
1688 | -out: | |
1676 | + scm_destroy(siocb->scm); | |
1689 | 1677 | siocb->scm = NULL; |
1690 | 1678 | return sent ? : err; |
1691 | 1679 | } |
... | ... | @@ -1789,7 +1777,7 @@ |
1789 | 1777 | siocb->scm = &tmp_scm; |
1790 | 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 | 1781 | unix_set_secdata(siocb->scm, skb); |
1794 | 1782 | |
1795 | 1783 | if (!(flags & MSG_PEEK)) { |
... | ... | @@ -1951,8 +1939,7 @@ |
1951 | 1939 | } |
1952 | 1940 | } else { |
1953 | 1941 | /* Copy credentials */ |
1954 | - scm_set_cred_noref(siocb->scm, UNIXCB(skb).pid, | |
1955 | - UNIXCB(skb).cred); | |
1942 | + scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); | |
1956 | 1943 | check_creds = 1; |
1957 | 1944 | } |
1958 | 1945 |