aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-09-16 19:34:00 -0400
committerDavid S. Miller <davem@davemloft.net>2011-09-16 19:34:00 -0400
commitf78a5fda9116525809d088917638be912b85f838 (patch)
treeab6d7edaa915cea74d6c664c3e39a5ad15bab0f8 /net/unix/af_unix.c
parent473e64ee4603671efa1e0785418e56e9ffdfc47b (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.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)
1378 return max_level; 1378 return max_level;
1379} 1379}
1380 1380
1381static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, 1381static 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
1556out_unlock: 1550out_unlock:
@@ -1560,8 +1554,7 @@ out_free:
1560out: 1554out:
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;
1685out_err: 1675out_err:
1686 if (skb == NULL) 1676 scm_destroy(siocb->scm);
1687 scm_destroy(siocb->scm);
1688out:
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