Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 92906
b: refs/heads/master
c: b6ddf64
h: refs/heads/master
v: v3
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Apr 19, 2008
1 parent ffa93c9 commit 64fbca6
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 24 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 24b74bf0c9e08cbda74d3c64af69ad402ed54e04
refs/heads/master: b6ddf64ffe9d59577a9176856bb6fe69a539f573
2 changes: 1 addition & 1 deletion trunk/include/linux/sunrpc/xprt.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ int xprt_unregister_transport(struct xprt_class *type);
void xprt_set_retrans_timeout_def(struct rpc_task *task);
void xprt_set_retrans_timeout_rtt(struct rpc_task *task);
void xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status);
void xprt_wait_for_buffer_space(struct rpc_task *task);
void xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action);
void xprt_write_space(struct rpc_xprt *xprt);
void xprt_update_rtt(struct rpc_task *task);
void xprt_adjust_cwnd(struct rpc_task *task, int result);
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/sunrpc/xprt.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,13 +447,13 @@ EXPORT_SYMBOL_GPL(xprt_wake_pending_tasks);
* @task: task to be put to sleep
*
*/
void xprt_wait_for_buffer_space(struct rpc_task *task)
void xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action)
{
struct rpc_rqst *req = task->tk_rqstp;
struct rpc_xprt *xprt = req->rq_xprt;

task->tk_timeout = req->rq_timeout;
rpc_sleep_on(&xprt->pending, task, NULL);
rpc_sleep_on(&xprt->pending, task, action);
}
EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space);

Expand Down
61 changes: 41 additions & 20 deletions trunk/net/sunrpc/xprtsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,14 @@ static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen,
return sent;
}

static void xs_nospace_callback(struct rpc_task *task)
{
struct sock_xprt *transport = container_of(task->tk_rqstp->rq_xprt, struct sock_xprt, xprt);

transport->inet->sk_write_pending--;
clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
}

/**
* xs_nospace - place task on wait queue if transmit was incomplete
* @task: task to put to sleep
Expand All @@ -531,20 +539,27 @@ static void xs_nospace(struct rpc_task *task)
task->tk_pid, req->rq_slen - req->rq_bytes_sent,
req->rq_slen);

if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) {
/* Protect against races with write_space */
spin_lock_bh(&xprt->transport_lock);

/* Don't race with disconnect */
if (!xprt_connected(xprt))
task->tk_status = -ENOTCONN;
else if (test_bit(SOCK_NOSPACE, &transport->sock->flags))
xprt_wait_for_buffer_space(task);
/* Protect against races with write_space */
spin_lock_bh(&xprt->transport_lock);

/* Don't race with disconnect */
if (xprt_connected(xprt)) {
if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) {
/*
* Notify TCP that we're limited by the application
* window size
*/
set_bit(SOCK_NOSPACE, &transport->sock->flags);
transport->inet->sk_write_pending++;
/* ...and wait for more buffer space */
xprt_wait_for_buffer_space(task, xs_nospace_callback);
}
} else {
clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
task->tk_status = -ENOTCONN;
}

spin_unlock_bh(&xprt->transport_lock);
} else
/* Keep holding the socket if it is blocked */
rpc_delay(task, HZ>>4);
spin_unlock_bh(&xprt->transport_lock);
}

/**
Expand Down Expand Up @@ -588,19 +603,20 @@ static int xs_udp_send_request(struct rpc_task *task)
}

switch (status) {
case -EAGAIN:
xs_nospace(task);
break;
case -ENETUNREACH:
case -EPIPE:
case -ECONNREFUSED:
/* When the server has died, an ICMP port unreachable message
* prompts ECONNREFUSED. */
break;
case -EAGAIN:
xs_nospace(task);
clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
break;
default:
clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
dprintk("RPC: sendmsg returned unrecognized error %d\n",
-status);
break;
}

return status;
Expand Down Expand Up @@ -695,12 +711,13 @@ static int xs_tcp_send_request(struct rpc_task *task)
case -ENOTCONN:
case -EPIPE:
status = -ENOTCONN;
clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
break;
default:
dprintk("RPC: sendmsg returned unrecognized error %d\n",
-status);
clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags);
xs_tcp_shutdown(xprt);
break;
}

return status;
Expand Down Expand Up @@ -1189,9 +1206,11 @@ static void xs_udp_write_space(struct sock *sk)

if (unlikely(!(sock = sk->sk_socket)))
goto out;
clear_bit(SOCK_NOSPACE, &sock->flags);

if (unlikely(!(xprt = xprt_from_sock(sk))))
goto out;
if (unlikely(!test_and_clear_bit(SOCK_NOSPACE, &sock->flags)))
if (test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags) == 0)
goto out;

xprt_write_space(xprt);
Expand Down Expand Up @@ -1222,9 +1241,11 @@ static void xs_tcp_write_space(struct sock *sk)

if (unlikely(!(sock = sk->sk_socket)))
goto out;
clear_bit(SOCK_NOSPACE, &sock->flags);

if (unlikely(!(xprt = xprt_from_sock(sk))))
goto out;
if (unlikely(!test_and_clear_bit(SOCK_NOSPACE, &sock->flags)))
if (test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags) == 0)
goto out;

xprt_write_space(xprt);
Expand Down

0 comments on commit 64fbca6

Please sign in to comment.