Commit f78a5fda9116525809d088917638be912b85f838

Authored by David S. Miller
1 parent 473e64ee46

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

... ... @@ -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  
... ... @@ -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