aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaudio Imbrenda <imbrenda@linux.vnet.ibm.com>2016-03-22 12:05:52 -0400
committerDavid S. Miller <davem@davemloft.net>2016-03-22 16:18:41 -0400
commitf7f9b5e7f8eccfd68ffa7b8d74b07c478bb9e7f0 (patch)
tree8ca3e07cbeae365ba4d5d359e5931261ed0151e4
parent6f57e56a1527d58264ae126eff94fdac067744fc (diff)
AF_VSOCK: Shrink the area influenced by prepare_to_wait
When a thread is prepared for waiting by calling prepare_to_wait, sleeping is not allowed until either the wait has taken place or finish_wait has been called. The existing code in af_vsock imposed unnecessary no-sleep assumptions to a broad list of backend functions. This patch shrinks the influence of prepare_to_wait to the area where it is strictly needed, therefore relaxing the no-sleep restriction there. 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.c158
1 files changed, 85 insertions, 73 deletions
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 7fd1220fbfa0..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,11 +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
1560 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1561 1559
1562 while (total_written < len) { 1560 while (total_written < len) {
1563 ssize_t written; 1561 ssize_t written;
1564 1562
1563 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1565 while (vsock_stream_has_space(vsk) == 0 && 1564 while (vsock_stream_has_space(vsk) == 0 &&
1566 sk->sk_err == 0 && 1565 sk->sk_err == 0 &&
1567 !(sk->sk_shutdown & SEND_SHUTDOWN) && 1566 !(sk->sk_shutdown & SEND_SHUTDOWN) &&
@@ -1570,27 +1569,33 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1570 /* Don't wait for non-blocking sockets. */ 1569 /* Don't wait for non-blocking sockets. */
1571 if (timeout == 0) { 1570 if (timeout == 0) {
1572 err = -EAGAIN; 1571 err = -EAGAIN;
1573 goto out_wait; 1572 finish_wait(sk_sleep(sk), &wait);
1573 goto out_err;
1574 } 1574 }
1575 1575
1576 err = transport->notify_send_pre_block(vsk, &send_data); 1576 err = transport->notify_send_pre_block(vsk, &send_data);
1577 if (err < 0) 1577 if (err < 0) {
1578 goto out_wait; 1578 finish_wait(sk_sleep(sk), &wait);
1579 goto out_err;
1580 }
1579 1581
1580 release_sock(sk); 1582 release_sock(sk);
1581 timeout = schedule_timeout(timeout); 1583 timeout = schedule_timeout(timeout);
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
1591 prepare_to_wait(sk_sleep(sk), &wait, 1595 prepare_to_wait(sk_sleep(sk), &wait,
1592 TASK_INTERRUPTIBLE); 1596 TASK_INTERRUPTIBLE);
1593 } 1597 }
1598 finish_wait(sk_sleep(sk), &wait);
1594 1599
1595 /* These checks occur both as part of and after the loop 1600 /* These checks occur both as part of and after the loop
1596 * conditional since we need to check before and after 1601 * conditional since we need to check before and after
@@ -1598,16 +1603,16 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1598 */ 1603 */
1599 if (sk->sk_err) { 1604 if (sk->sk_err) {
1600 err = -sk->sk_err; 1605 err = -sk->sk_err;
1601 goto out_wait; 1606 goto out_err;
1602 } else if ((sk->sk_shutdown & SEND_SHUTDOWN) || 1607 } else if ((sk->sk_shutdown & SEND_SHUTDOWN) ||
1603 (vsk->peer_shutdown & RCV_SHUTDOWN)) { 1608 (vsk->peer_shutdown & RCV_SHUTDOWN)) {
1604 err = -EPIPE; 1609 err = -EPIPE;
1605 goto out_wait; 1610 goto out_err;
1606 } 1611 }
1607 1612
1608 err = transport->notify_send_pre_enqueue(vsk, &send_data); 1613 err = transport->notify_send_pre_enqueue(vsk, &send_data);
1609 if (err < 0) 1614 if (err < 0)
1610 goto out_wait; 1615 goto out_err;
1611 1616
1612 /* 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
1613 * 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
@@ -1620,7 +1625,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1620 len - total_written); 1625 len - total_written);
1621 if (written < 0) { 1626 if (written < 0) {
1622 err = -ENOMEM; 1627 err = -ENOMEM;
1623 goto out_wait; 1628 goto out_err;
1624 } 1629 }
1625 1630
1626 total_written += written; 1631 total_written += written;
@@ -1628,14 +1633,13 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1628 err = transport->notify_send_post_enqueue( 1633 err = transport->notify_send_post_enqueue(
1629 vsk, written, &send_data); 1634 vsk, written, &send_data);
1630 if (err < 0) 1635 if (err < 0)
1631 goto out_wait; 1636 goto out_err;
1632 1637
1633 } 1638 }
1634 1639
1635out_wait: 1640out_err:
1636 if (total_written > 0) 1641 if (total_written > 0)
1637 err = total_written; 1642 err = total_written;
1638 finish_wait(sk_sleep(sk), &wait);
1639out: 1643out:
1640 release_sock(sk); 1644 release_sock(sk);
1641 return err; 1645 return err;
@@ -1716,21 +1720,61 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
1716 if (err < 0) 1720 if (err < 0)
1717 goto out; 1721 goto out;
1718 1722
1719 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1720 1723
1721 while (1) { 1724 while (1) {
1722 s64 ready = vsock_stream_has_data(vsk); 1725 s64 ready;
1723 1726
1724 if (ready < 0) { 1727 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1725 /* Invalid queue pair content. XXX This should be 1728 ready = vsock_stream_has_data(vsk);
1726 * changed to a connection reset in a later change.
1727 */
1728 1729
1729 err = -ENOMEM; 1730 if (ready == 0) {
1730 goto out_wait; 1731 if (sk->sk_err != 0 ||
1731 } 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 {
1732 ssize_t read; 1764 ssize_t read;
1733 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
1734 err = transport->notify_recv_pre_dequeue( 1778 err = transport->notify_recv_pre_dequeue(
1735 vsk, target, &recv_data); 1779 vsk, target, &recv_data);
1736 if (err < 0) 1780 if (err < 0)
@@ -1750,42 +1794,12 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
1750 vsk, target, read, 1794 vsk, target, read,
1751 !(flags & MSG_PEEK), &recv_data); 1795 !(flags & MSG_PEEK), &recv_data);
1752 if (err < 0) 1796 if (err < 0)
1753 goto out_wait; 1797 goto out;
1754 1798
1755 if (read >= target || flags & MSG_PEEK) 1799 if (read >= target || flags & MSG_PEEK)
1756 break; 1800 break;
1757 1801
1758 target -= read; 1802 target -= read;
1759 } else {
1760 if (sk->sk_err != 0 || (sk->sk_shutdown & RCV_SHUTDOWN)
1761 || (vsk->peer_shutdown & SEND_SHUTDOWN)) {
1762 break;
1763 }
1764 /* Don't wait for non-blocking sockets. */
1765 if (timeout == 0) {
1766 err = -EAGAIN;
1767 break;
1768 }
1769
1770 err = transport->notify_recv_pre_block(
1771 vsk, target, &recv_data);
1772 if (err < 0)
1773 break;
1774
1775 release_sock(sk);
1776 timeout = schedule_timeout(timeout);
1777 lock_sock(sk);
1778
1779 if (signal_pending(current)) {
1780 err = sock_intr_errno(timeout);
1781 break;
1782 } else if (timeout == 0) {
1783 err = -EAGAIN;
1784 break;
1785 }
1786
1787 prepare_to_wait(sk_sleep(sk), &wait,
1788 TASK_INTERRUPTIBLE);
1789 } 1803 }
1790 } 1804 }
1791 1805
@@ -1816,8 +1830,6 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
1816 err = copied; 1830 err = copied;
1817 } 1831 }
1818 1832
1819out_wait:
1820 finish_wait(sk_sleep(sk), &wait);
1821out: 1833out:
1822 release_sock(sk); 1834 release_sock(sk);
1823 return err; 1835 return err;