Skip to content

Commit f7f9b5e

Browse files
Claudio Imbrendadavem330
authored andcommitted
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>
1 parent 6f57e56 commit f7f9b5e

File tree

1 file changed

+85
-73
lines changed

1 file changed

+85
-73
lines changed

net/vmw_vsock/af_vsock.c

Lines changed: 85 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,31 +1209,32 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
12091209

12101210
if (signal_pending(current)) {
12111211
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;
12131215
} else if (timeout == 0) {
12141216
err = -ETIMEDOUT;
1215-
goto out_wait_error;
1217+
sk->sk_state = SS_UNCONNECTED;
1218+
sock->state = SS_UNCONNECTED;
1219+
goto out_wait;
12161220
}
12171221

12181222
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
12191223
}
12201224

12211225
if (sk->sk_err) {
12221226
err = -sk->sk_err;
1223-
goto out_wait_error;
1224-
} else
1227+
sk->sk_state = SS_UNCONNECTED;
1228+
sock->state = SS_UNCONNECTED;
1229+
} else {
12251230
err = 0;
1231+
}
12261232

12271233
out_wait:
12281234
finish_wait(sk_sleep(sk), &wait);
12291235
out:
12301236
release_sock(sk);
12311237
return err;
1232-
1233-
out_wait_error:
1234-
sk->sk_state = SS_UNCONNECTED;
1235-
sock->state = SS_UNCONNECTED;
1236-
goto out_wait;
12371238
}
12381239

12391240
static 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)
12701271
listener->sk_err == 0) {
12711272
release_sock(listener);
12721273
timeout = schedule_timeout(timeout);
1274+
finish_wait(sk_sleep(listener), &wait);
12731275
lock_sock(listener);
12741276

12751277
if (signal_pending(current)) {
12761278
err = sock_intr_errno(timeout);
1277-
goto out_wait;
1279+
goto out;
12781280
} else if (timeout == 0) {
12791281
err = -EAGAIN;
1280-
goto out_wait;
1282+
goto out;
12811283
}
12821284

12831285
prepare_to_wait(sk_sleep(listener), &wait, TASK_INTERRUPTIBLE);
12841286
}
1287+
finish_wait(sk_sleep(listener), &wait);
12851288

12861289
if (listener->sk_err)
12871290
err = -listener->sk_err;
@@ -1301,19 +1304,15 @@ static int vsock_accept(struct socket *sock, struct socket *newsock, int flags)
13011304
*/
13021305
if (err) {
13031306
vconnected->rejected = true;
1304-
release_sock(connected);
1305-
sock_put(connected);
1306-
goto out_wait;
1307+
} else {
1308+
newsock->state = SS_CONNECTED;
1309+
sock_graft(connected, newsock);
13071310
}
13081311

1309-
newsock->state = SS_CONNECTED;
1310-
sock_graft(connected, newsock);
13111312
release_sock(connected);
13121313
sock_put(connected);
13131314
}
13141315

1315-
out_wait:
1316-
finish_wait(sk_sleep(listener), &wait);
13171316
out:
13181317
release_sock(listener);
13191318
return err;
@@ -1557,11 +1556,11 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
15571556
if (err < 0)
15581557
goto out;
15591558

1560-
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
15611559

15621560
while (total_written < len) {
15631561
ssize_t written;
15641562

1563+
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
15651564
while (vsock_stream_has_space(vsk) == 0 &&
15661565
sk->sk_err == 0 &&
15671566
!(sk->sk_shutdown & SEND_SHUTDOWN) &&
@@ -1570,44 +1569,50 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
15701569
/* Don't wait for non-blocking sockets. */
15711570
if (timeout == 0) {
15721571
err = -EAGAIN;
1573-
goto out_wait;
1572+
finish_wait(sk_sleep(sk), &wait);
1573+
goto out_err;
15741574
}
15751575

15761576
err = transport->notify_send_pre_block(vsk, &send_data);
1577-
if (err < 0)
1578-
goto out_wait;
1577+
if (err < 0) {
1578+
finish_wait(sk_sleep(sk), &wait);
1579+
goto out_err;
1580+
}
15791581

15801582
release_sock(sk);
15811583
timeout = schedule_timeout(timeout);
15821584
lock_sock(sk);
15831585
if (signal_pending(current)) {
15841586
err = sock_intr_errno(timeout);
1585-
goto out_wait;
1587+
finish_wait(sk_sleep(sk), &wait);
1588+
goto out_err;
15861589
} else if (timeout == 0) {
15871590
err = -EAGAIN;
1588-
goto out_wait;
1591+
finish_wait(sk_sleep(sk), &wait);
1592+
goto out_err;
15891593
}
15901594

15911595
prepare_to_wait(sk_sleep(sk), &wait,
15921596
TASK_INTERRUPTIBLE);
15931597
}
1598+
finish_wait(sk_sleep(sk), &wait);
15941599

15951600
/* These checks occur both as part of and after the loop
15961601
* conditional since we need to check before and after
15971602
* sleeping.
15981603
*/
15991604
if (sk->sk_err) {
16001605
err = -sk->sk_err;
1601-
goto out_wait;
1606+
goto out_err;
16021607
} else if ((sk->sk_shutdown & SEND_SHUTDOWN) ||
16031608
(vsk->peer_shutdown & RCV_SHUTDOWN)) {
16041609
err = -EPIPE;
1605-
goto out_wait;
1610+
goto out_err;
16061611
}
16071612

16081613
err = transport->notify_send_pre_enqueue(vsk, &send_data);
16091614
if (err < 0)
1610-
goto out_wait;
1615+
goto out_err;
16111616

16121617
/* Note that enqueue will only write as many bytes as are free
16131618
* in the produce queue, so we don't need to ensure len is
@@ -1620,22 +1625,21 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
16201625
len - total_written);
16211626
if (written < 0) {
16221627
err = -ENOMEM;
1623-
goto out_wait;
1628+
goto out_err;
16241629
}
16251630

16261631
total_written += written;
16271632

16281633
err = transport->notify_send_post_enqueue(
16291634
vsk, written, &send_data);
16301635
if (err < 0)
1631-
goto out_wait;
1636+
goto out_err;
16321637

16331638
}
16341639

1635-
out_wait:
1640+
out_err:
16361641
if (total_written > 0)
16371642
err = total_written;
1638-
finish_wait(sk_sleep(sk), &wait);
16391643
out:
16401644
release_sock(sk);
16411645
return err;
@@ -1716,21 +1720,61 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
17161720
if (err < 0)
17171721
goto out;
17181722

1719-
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
17201723

17211724
while (1) {
1722-
s64 ready = vsock_stream_has_data(vsk);
1725+
s64 ready;
17231726

1724-
if (ready < 0) {
1725-
/* Invalid queue pair content. XXX This should be
1726-
* changed to a connection reset in a later change.
1727-
*/
1727+
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
1728+
ready = vsock_stream_has_data(vsk);
17281729

1729-
err = -ENOMEM;
1730-
goto out_wait;
1731-
} else if (ready > 0) {
1730+
if (ready == 0) {
1731+
if (sk->sk_err != 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 {
17321764
ssize_t read;
17331765

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+
17341778
err = transport->notify_recv_pre_dequeue(
17351779
vsk, target, &recv_data);
17361780
if (err < 0)
@@ -1750,42 +1794,12 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
17501794
vsk, target, read,
17511795
!(flags & MSG_PEEK), &recv_data);
17521796
if (err < 0)
1753-
goto out_wait;
1797+
goto out;
17541798

17551799
if (read >= target || flags & MSG_PEEK)
17561800
break;
17571801

17581802
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);
17891803
}
17901804
}
17911805

@@ -1816,8 +1830,6 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
18161830
err = copied;
18171831
}
18181832

1819-
out_wait:
1820-
finish_wait(sk_sleep(sk), &wait);
18211833
out:
18221834
release_sock(sk);
18231835
return err;

0 commit comments

Comments
 (0)