aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaudio Imbrenda <imbrenda@linux.vnet.ibm.com>2016-03-22 12:05:51 -0400
committerDavid S. Miller <davem@davemloft.net>2016-03-22 16:18:41 -0400
commit6f57e56a1527d58264ae126eff94fdac067744fc (patch)
treebc5604c18b8e1ea7f9e68c9d22a39d538acf3402
parent9a0384c020b055a555500906be8ac314c92f3998 (diff)
Revert "vsock: Fix blocking ops call in prepare_to_wait"
This reverts commit 5988818008257ca42010d6b43a3e0e48afec9898 ("vsock: Fix blocking ops call in prepare_to_wait") The commit reverted with this patch caused us to potentially miss wakeups. Since the condition is not checked between the prepare_to_wait and the schedule(), if a wakeup happens after the condition is checked but before the sleep happens, we will miss it. ( A description of the problem can be found here: http://www.makelinux.net/ldd3/chp-6-sect-2 ). By reverting the patch, the behaviour is still incorrect (since we shouldn't sleep between the prepare_to_wait and the schedule) but at least it will not miss wakeups. The next patch in the series actually fixes the behaviour. Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/vmw_vsock/af_vsock.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index bbe65dcb9738..7fd1220fbfa0 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1557,6 +1557,8 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1557 if (err < 0) 1557 if (err < 0)
1558 goto out; 1558 goto out;
1559 1559
1560 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1561
1560 while (total_written < len) { 1562 while (total_written < len) {
1561 ssize_t written; 1563 ssize_t written;
1562 1564
@@ -1576,9 +1578,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1576 goto out_wait; 1578 goto out_wait;
1577 1579
1578 release_sock(sk); 1580 release_sock(sk);
1579 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1580 timeout = schedule_timeout(timeout); 1581 timeout = schedule_timeout(timeout);
1581 finish_wait(sk_sleep(sk), &wait);
1582 lock_sock(sk); 1582 lock_sock(sk);
1583 if (signal_pending(current)) { 1583 if (signal_pending(current)) {
1584 err = sock_intr_errno(timeout); 1584 err = sock_intr_errno(timeout);
@@ -1588,6 +1588,8 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1588 goto out_wait; 1588 goto out_wait;
1589 } 1589 }
1590 1590
1591 prepare_to_wait(sk_sleep(sk), &wait,
1592 TASK_INTERRUPTIBLE);
1591 } 1593 }
1592 1594
1593 /* These checks occur both as part of and after the loop 1595 /* These checks occur both as part of and after the loop
@@ -1633,6 +1635,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1633out_wait: 1635out_wait:
1634 if (total_written > 0) 1636 if (total_written > 0)
1635 err = total_written; 1637 err = total_written;
1638 finish_wait(sk_sleep(sk), &wait);
1636out: 1639out:
1637 release_sock(sk); 1640 release_sock(sk);
1638 return err; 1641 return err;
@@ -1713,6 +1716,7 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
1713 if (err < 0) 1716 if (err < 0)
1714 goto out; 1717 goto out;
1715 1718
1719 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1716 1720
1717 while (1) { 1721 while (1) {
1718 s64 ready = vsock_stream_has_data(vsk); 1722 s64 ready = vsock_stream_has_data(vsk);
@@ -1723,7 +1727,7 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
1723 */ 1727 */
1724 1728
1725 err = -ENOMEM; 1729 err = -ENOMEM;
1726 goto out; 1730 goto out_wait;
1727 } else if (ready > 0) { 1731 } else if (ready > 0) {
1728 ssize_t read; 1732 ssize_t read;
1729 1733
@@ -1746,7 +1750,7 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
1746 vsk, target, read, 1750 vsk, target, read,
1747 !(flags & MSG_PEEK), &recv_data); 1751 !(flags & MSG_PEEK), &recv_data);
1748 if (err < 0) 1752 if (err < 0)
1749 goto out; 1753 goto out_wait;
1750 1754
1751 if (read >= target || flags & MSG_PEEK) 1755 if (read >= target || flags & MSG_PEEK)
1752 break; 1756 break;
@@ -1769,9 +1773,7 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
1769 break; 1773 break;
1770 1774
1771 release_sock(sk); 1775 release_sock(sk);
1772 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1773 timeout = schedule_timeout(timeout); 1776 timeout = schedule_timeout(timeout);
1774 finish_wait(sk_sleep(sk), &wait);
1775 lock_sock(sk); 1777 lock_sock(sk);
1776 1778
1777 if (signal_pending(current)) { 1779 if (signal_pending(current)) {
@@ -1781,6 +1783,9 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
1781 err = -EAGAIN; 1783 err = -EAGAIN;
1782 break; 1784 break;
1783 } 1785 }
1786
1787 prepare_to_wait(sk_sleep(sk), &wait,
1788 TASK_INTERRUPTIBLE);
1784 } 1789 }
1785 } 1790 }
1786 1791
@@ -1811,6 +1816,8 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
1811 err = copied; 1816 err = copied;
1812 } 1817 }
1813 1818
1819out_wait:
1820 finish_wait(sk_sleep(sk), &wait);
1814out: 1821out:
1815 release_sock(sk); 1822 release_sock(sk);
1816 return err; 1823 return err;