SUNRPC: Fix suspicious enobufs issues.
The current test is racy when dealing with fast NICs. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
parent
f1dc237c60
commit
9ffadfbc09
|
@ -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) {
|
vm_wait = false;
|
||||||
status = -EAGAIN;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (status == -EAGAIN && sk_stream_is_writeable(transport->inet))
|
|
||||||
status = -ENOBUFS;
|
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case -ENOTSOCK:
|
case -ENOTSOCK:
|
||||||
|
|
Loading…
Reference in New Issue