aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-03-22 16:18:42 -0400
committerDavid S. Miller <davem@davemloft.net>2016-03-22 16:18:42 -0400
commit9a3492194eca6253ae7ba93c7a402cecad7f1c94 (patch)
tree8ca3e07cbeae365ba4d5d359e5931261ed0151e4
parent9a0384c020b055a555500906be8ac314c92f3998 (diff)
parentf7f9b5e7f8eccfd68ffa7b8d74b07c478bb9e7f0 (diff)
Merge branch 'AF_VSOCK-missed-wakeups'
Claudio Imbrenda says: ==================== AF_VSOCK: Shrink the area influenced by prepare_to_wait This patchset applies on net-next. I think I found a problem with the patch submitted by Laura Abbott ( https://lkml.org/lkml/2016/2/4/711 ): we might 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, and we miss it. ( A description of the problem can be found here: http://www.makelinux.net/ldd3/chp-6-sect-2 ). The first patch reverts the previous broken patch, while the second patch properly fixes the sleep-while-waiting issue. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/vmw_vsock/af_vsock.c155
1 files changed, 87 insertions, 68 deletions
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index bbe65dcb9738..3dce53ebea92 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1209,10 +1209,14 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
1209 1209
1210 if (signal_pending(current)) { 1210 if (signal_pending(current)) {
1211 err = sock_intr_errno(timeout); 1211 err = sock_intr_errno(timeout);
1212 goto out_wait_error; 1212 sk->sk_state = SS_UNCONNECTED;
1213 sock->state = SS_UNCONNECTED;
1214 goto out_wait;
1213 } else if (timeout == 0) { 1215 } else if (timeout == 0) {
1214 err = -ETIMEDOUT; 1216 err = -ETIMEDOUT;
1215 goto out_wait_error; 1217 sk->sk_state = SS_UNCONNECTED;
1218 sock->state = SS_UNCONNECTED;
1219 goto out_wait;
1216 } 1220 }
1217 1221
1218 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 1222 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
@@ -1220,20 +1224,17 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
1220 1224
1221 if (sk->sk_err) { 1225 if (sk->sk_err) {
1222 err = -sk->sk_err; 1226 err = -sk->sk_err;
1223 goto out_wait_error; 1227 sk->sk_state = SS_UNCONNECTED;
1224 } else 1228 sock->state = SS_UNCONNECTED;
1229 } else {
1225 err = 0; 1230 err = 0;
1231 }
1226 1232
1227out_wait: 1233out_wait:
1228 finish_wait(sk_sleep(sk), &wait); 1234 finish_wait(sk_sleep(sk), &wait);
1229out: 1235out:
1230 release_sock(sk); 1236 release_sock(sk);
1231 return err; 1237 return err;
1232
1233out_wait_error:
1234 sk->sk_state = SS_UNCONNECTED;
1235 sock->state = SS_UNCONNECTED;
1236 goto out_wait;
1237} 1238}
1238 1239
1239static int vsock_accept(struct socket *sock, struct socket *newsock, int flags) 1240static int vsock_accept(struct socket *sock, struct socket *newsock, int flags)
@@ -1270,18 +1271,20 @@ static int vsock_accept(struct socket *sock, struct socket *newsock, int flags)
1270 listener->sk_err == 0) { 1271 listener->sk_err == 0) {
1271 release_sock(listener); 1272 release_sock(listener);
1272 timeout = schedule_timeout(timeout); 1273 timeout = schedule_timeout(timeout);
1274 finish_wait(sk_sleep(listener), &wait);
1273 lock_sock(listener); 1275 lock_sock(listener);
1274 1276
1275 if (signal_pending(current)) { 1277 if (signal_pending(current)) {
1276 err = sock_intr_errno(timeout); 1278 err = sock_intr_errno(timeout);
1277 goto out_wait; 1279 goto out;
1278 } else if (timeout == 0) { 1280 } else if (timeout == 0) {
1279 err = -EAGAIN; 1281 err = -EAGAIN;
1280 goto out_wait; 1282 goto out;
1281 } 1283 }
1282 1284
1283 prepare_to_wait(sk_sleep(listener), &wait, TASK_INTERRUPTIBLE); 1285 prepare_to_wait(sk_sleep(listener), &wait, TASK_INTERRUPTIBLE);
1284 } 1286 }
1287 finish_wait(sk_sleep(listener), &wait);
1285 1288
1286 if (listener->sk_err) 1289 if (listener->sk_err)
1287 err = -listener->sk_err; 1290 err = -listener->sk_err;
@@ -1301,19 +1304,15 @@ static int vsock_accept(struct socket *sock, struct socket *newsock, int flags)
1301 */ 1304 */
1302 if (err) { 1305 if (err) {
1303 vconnected->rejected = true; 1306 vconnected->rejected = true;
1304 release_sock(connected); 1307 } else {
1305 sock_put(connected); 1308 newsock->state = SS_CONNECTED;
1306 goto out_wait; 1309 sock_graft(connected, newsock);
1307 } 1310 }
1308 1311
1309 newsock->state = SS_CONNECTED;
1310 sock_graft(connected, newsock);
1311 release_sock(connected); 1312 release_sock(connected);
1312 sock_put(connected); 1313 sock_put(connected);
1313 } 1314 }
1314 1315
1315out_wait:
1316 finish_wait(sk_sleep(listener), &wait);
1317out: 1316out:
1318 release_sock(listener); 1317 release_sock(listener);
1319 return err; 1318 return err;
@@ -1557,9 +1556,11 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1557 if (err < 0) 1556 if (err < 0)
1558 goto out; 1557 goto out;
1559 1558
1559
1560 while (total_written < len) { 1560 while (total_written < len) {
1561 ssize_t written; 1561 ssize_t written;
1562 1562
1563 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1563 while (vsock_stream_has_space(vsk) == 0 && 1564 while (vsock_stream_has_space(vsk) == 0 &&
1564 sk->sk_err == 0 && 1565 sk->sk_err == 0 &&
1565 !(sk->sk_shutdown & SEND_SHUTDOWN) && 1566 !(sk->sk_shutdown & SEND_SHUTDOWN) &&
@@ -1568,27 +1569,33 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1568 /* Don't wait for non-blocking sockets. */ 1569 /* Don't wait for non-blocking sockets. */
1569 if (timeout == 0) { 1570 if (timeout == 0) {
1570 err = -EAGAIN; 1571 err = -EAGAIN;
1571 goto out_wait; 1572 finish_wait(sk_sleep(sk), &wait);
1573 goto out_err;
1572 } 1574 }
1573 1575
1574 err = transport->notify_send_pre_block(vsk, &send_data); 1576 err = transport->notify_send_pre_block(vsk, &send_data);
1575 if (err < 0) 1577 if (err < 0) {
1576 goto out_wait; 1578 finish_wait(sk_sleep(sk), &wait);
1579 goto out_err;
1580 }
1577 1581
1578 release_sock(sk); 1582 release_sock(sk);
1579 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1580 timeout = schedule_timeout(timeout); 1583 timeout = schedule_timeout(timeout);
1581 finish_wait(sk_sleep(sk), &wait);
1582 lock_sock(sk); 1584 lock_sock(sk);
1583 if (signal_pending(current)) { 1585 if (signal_pending(current)) {
1584 err = sock_intr_errno(timeout); 1586 err = sock_intr_errno(timeout);
1585 goto out_wait; 1587 finish_wait(sk_sleep(sk), &wait);
1588 goto out_err;
1586 } else if (timeout == 0) { 1589 } else if (timeout == 0) {
1587 err = -EAGAIN; 1590 err = -EAGAIN;
1588 goto out_wait; 1591 finish_wait(sk_sleep(sk), &wait);
1592 goto out_err;
1589 } 1593 }
1590 1594
1595 prepare_to_wait(sk_sleep(sk), &wait,
1596 TASK_INTERRUPTIBLE);
1591 } 1597 }
1598 finish_wait(sk_sleep(sk), &wait);
1592 1599
1593 /* These checks occur both as part of and after the loop 1600 /* These checks occur both as part of and after the loop
1594 * conditional since we need to check before and after 1601 * conditional since we need to check before and after
@@ -1596,16 +1603,16 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1596 */ 1603 */
1597 if (sk->sk_err) { 1604 if (sk->sk_err) {
1598 err = -sk->sk_err; 1605 err = -sk->sk_err;
1599 goto out_wait; 1606 goto out_err;
1600 } else if ((sk->sk_shutdown & SEND_SHUTDOWN) || 1607 } else if ((sk->sk_shutdown & SEND_SHUTDOWN) ||
1601 (vsk->peer_shutdown & RCV_SHUTDOWN)) { 1608 (vsk->peer_shutdown & RCV_SHUTDOWN)) {
1602 err = -EPIPE; 1609 err = -EPIPE;
1603 goto out_wait; 1610 goto out_err;
1604 } 1611 }
1605 1612
1606 err = transport->notify_send_pre_enqueue(vsk, &send_data); 1613 err = transport->notify_send_pre_enqueue(vsk, &send_data);
1607 if (err < 0) 1614 if (err < 0)
1608 goto out_wait; 1615 goto out_err;
1609 1616
1610 /* Note that enqueue will only write as many bytes as are free 1617 /* Note that enqueue will only write as many bytes as are free
1611 * in the produce queue, so we don't need to ensure len is 1618 * in the produce queue, so we don't need to ensure len is
@@ -1618,7 +1625,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1618 len - total_written); 1625 len - total_written);
1619 if (written < 0) { 1626 if (written < 0) {
1620 err = -ENOMEM; 1627 err = -ENOMEM;
1621 goto out_wait; 1628 goto out_err;
1622 } 1629 }
1623 1630
1624 total_written += written; 1631 total_written += written;
@@ -1626,11 +1633,11 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1626 err = transport->notify_send_post_enqueue( 1633 err = transport->notify_send_post_enqueue(
1627 vsk, written, &send_data); 1634 vsk, written, &send_data);
1628 if (err < 0) 1635 if (err < 0)
1629 goto out_wait; 1636 goto out_err;
1630 1637
1631 } 1638 }
1632 1639
1633out_wait: 1640out_err:
1634 if (total_written > 0) 1641 if (total_written > 0)
1635 err = total_written; 1642 err = total_written;
1636out: 1643out:
@@ -1715,18 +1722,59 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
1715 1722
1716 1723
1717 while (1) { 1724 while (1) {
1718 s64 ready = vsock_stream_has_data(vsk); 1725 s64 ready;
1719 1726
1720 if (ready < 0) { 1727 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1721 /* Invalid queue pair content. XXX This should be 1728 ready = vsock_stream_has_data(vsk);
1722 * changed to a connection reset in a later change.
1723 */
1724 1729
1725 err = -ENOMEM; 1730 if (ready == 0) {
1726 goto out; 1731 if (sk->sk_err != 0 ||
1727 } else if (ready > 0) { 1732 (sk->sk_shutdown & RCV_SHUTDOWN) ||
1733 (vsk->peer_shutdown & SEND_SHUTDOWN)) {
1734 finish_wait(sk_sleep(sk), &wait);
1735 break;
1736 }
1737 /* Don't wait for non-blocking sockets. */
1738 if (timeout == 0) {
1739 err = -EAGAIN;
1740 finish_wait(sk_sleep(sk), &wait);
1741 break;
1742 }
1743
1744 err = transport->notify_recv_pre_block(
1745 vsk, target, &recv_data);
1746 if (err < 0) {
1747 finish_wait(sk_sleep(sk), &wait);
1748 break;
1749 }
1750 release_sock(sk);
1751 timeout = schedule_timeout(timeout);
1752 lock_sock(sk);
1753
1754 if (signal_pending(current)) {
1755 err = sock_intr_errno(timeout);
1756 finish_wait(sk_sleep(sk), &wait);
1757 break;
1758 } else if (timeout == 0) {
1759 err = -EAGAIN;
1760 finish_wait(sk_sleep(sk), &wait);
1761 break;
1762 }
1763 } else {
1728 ssize_t read; 1764 ssize_t read;
1729 1765
1766 finish_wait(sk_sleep(sk), &wait);
1767
1768 if (ready < 0) {
1769 /* Invalid queue pair content. XXX This should
1770 * be changed to a connection reset in a later
1771 * change.
1772 */
1773
1774 err = -ENOMEM;
1775 goto out;
1776 }
1777
1730 err = transport->notify_recv_pre_dequeue( 1778 err = transport->notify_recv_pre_dequeue(
1731 vsk, target, &recv_data); 1779 vsk, target, &recv_data);
1732 if (err < 0) 1780 if (err < 0)
@@ -1752,35 +1800,6 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
1752 break; 1800 break;
1753 1801
1754 target -= read; 1802 target -= read;
1755 } else {
1756 if (sk->sk_err != 0 || (sk->sk_shutdown & RCV_SHUTDOWN)
1757 || (vsk->peer_shutdown & SEND_SHUTDOWN)) {
1758 break;
1759 }
1760 /* Don't wait for non-blocking sockets. */
1761 if (timeout == 0) {
1762 err = -EAGAIN;
1763 break;
1764 }
1765
1766 err = transport->notify_recv_pre_block(
1767 vsk, target, &recv_data);
1768 if (err < 0)
1769 break;
1770
1771 release_sock(sk);
1772 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1773 timeout = schedule_timeout(timeout);
1774 finish_wait(sk_sleep(sk), &wait);
1775 lock_sock(sk);
1776
1777 if (signal_pending(current)) {
1778 err = sock_intr_errno(timeout);
1779 break;
1780 } else if (timeout == 0) {
1781 err = -EAGAIN;
1782 break;
1783 }
1784 } 1803 }
1785 } 1804 }
1786 1805