Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Claudio Imbrenda and committed by
David S. Miller
6f57e56a 9a0384c0

+13 -6
+13 -6
net/vmw_vsock/af_vsock.c
··· 1557 1557 if (err < 0) 1558 1558 goto out; 1559 1559 1560 + prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 1561 + 1560 1562 while (total_written < len) { 1561 1563 ssize_t written; 1562 1564 ··· 1578 1576 goto out_wait; 1579 1577 1580 1578 release_sock(sk); 1581 - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 1582 1579 timeout = schedule_timeout(timeout); 1583 - finish_wait(sk_sleep(sk), &wait); 1584 1580 lock_sock(sk); 1585 1581 if (signal_pending(current)) { 1586 1582 err = sock_intr_errno(timeout); ··· 1588 1588 goto out_wait; 1589 1589 } 1590 1590 1591 + prepare_to_wait(sk_sleep(sk), &wait, 1592 + TASK_INTERRUPTIBLE); 1591 1593 } 1592 1594 1593 1595 /* These checks occur both as part of and after the loop ··· 1635 1633 out_wait: 1636 1634 if (total_written > 0) 1637 1635 err = total_written; 1636 + finish_wait(sk_sleep(sk), &wait); 1638 1637 out: 1639 1638 release_sock(sk); 1640 1639 return err; ··· 1716 1713 if (err < 0) 1717 1714 goto out; 1718 1715 1716 + prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 1719 1717 1720 1718 while (1) { 1721 1719 s64 ready = vsock_stream_has_data(vsk); ··· 1727 1723 */ 1728 1724 1729 1725 err = -ENOMEM; 1730 - goto out; 1726 + goto out_wait; 1731 1727 } else if (ready > 0) { 1732 1728 ssize_t read; 1733 1729 ··· 1750 1746 vsk, target, read, 1751 1747 !(flags & MSG_PEEK), &recv_data); 1752 1748 if (err < 0) 1753 - goto out; 1749 + goto out_wait; 1754 1750 1755 1751 if (read >= target || flags & MSG_PEEK) 1756 1752 break; ··· 1773 1769 break; 1774 1770 1775 1771 release_sock(sk); 1776 - prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 1777 1772 timeout = schedule_timeout(timeout); 1778 - finish_wait(sk_sleep(sk), &wait); 1779 1773 lock_sock(sk); 1780 1774 1781 1775 if (signal_pending(current)) { ··· 1783 1781 err = -EAGAIN; 1784 1782 break; 1785 1783 } 1784 + 1785 + prepare_to_wait(sk_sleep(sk), &wait, 1786 + TASK_INTERRUPTIBLE); 1786 1787 } 1787 1788 } 1788 1789 ··· 1816 1811 err = copied; 1817 1812 } 1818 1813 1814 + out_wait: 1815 + finish_wait(sk_sleep(sk), &wait); 1819 1816 out: 1820 1817 release_sock(sk); 1821 1818 return err;