|
@@ -642,6 +642,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
|
|
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
|
struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
|
|
struct xdr_buf *xdr = &req->rq_snd_buf;
|
|
struct xdr_buf *xdr = &req->rq_snd_buf;
|
|
bool zerocopy = true;
|
|
bool zerocopy = true;
|
|
|
|
+ bool vm_wait = false;
|
|
int status;
|
|
int status;
|
|
int sent;
|
|
int sent;
|
|
|
|
|
|
@@ -677,15 +678,33 @@ static int xs_tcp_send_request(struct rpc_task *task)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ WARN_ON_ONCE(sent == 0 && status == 0);
|
|
|
|
+
|
|
|
|
+ if (status == -EAGAIN ) {
|
|
|
|
+ /*
|
|
|
|
+ * Return EAGAIN if we're sure we're hitting the
|
|
|
|
+ * socket send buffer limits.
|
|
|
|
+ */
|
|
|
|
+ if (test_bit(SOCK_NOSPACE, &transport->sock->flags))
|
|
|
|
+ break;
|
|
|
|
+ /*
|
|
|
|
+ * Did we hit a memory allocation failure?
|
|
|
|
+ */
|
|
|
|
+ if (sent == 0) {
|
|
|
|
+ status = -ENOBUFS;
|
|
|
|
+ if (vm_wait)
|
|
|
|
+ break;
|
|
|
|
+ /* Retry, knowing now that we're below the
|
|
|
|
+ * socket send buffer limit
|
|
|
|
+ */
|
|
|
|
+ vm_wait = true;
|
|
|
|
+ }
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
if (status < 0)
|
|
if (status < 0)
|
|
break;
|
|
break;
|
|
- if (sent == 0) {
|
|
|
|
- status = -EAGAIN;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ vm_wait = false;
|
|
}
|
|
}
|
|
- if (status == -EAGAIN && sk_stream_is_writeable(transport->inet))
|
|
|
|
- status = -ENOBUFS;
|
|
|
|
|
|
|
|
switch (status) {
|
|
switch (status) {
|
|
case -ENOTSOCK:
|
|
case -ENOTSOCK:
|