aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/xprt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r--net/sunrpc/xprt.c80
1 files changed, 51 insertions, 29 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index c64c0ef519b5..0cbcd1ab49ab 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -66,6 +66,7 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net);
66static void xprt_request_init(struct rpc_task *, struct rpc_xprt *); 66static void xprt_request_init(struct rpc_task *, struct rpc_xprt *);
67static void xprt_connect_status(struct rpc_task *task); 67static void xprt_connect_status(struct rpc_task *task);
68static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *); 68static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);
69static void xprt_destroy(struct rpc_xprt *xprt);
69 70
70static DEFINE_SPINLOCK(xprt_list_lock); 71static DEFINE_SPINLOCK(xprt_list_lock);
71static LIST_HEAD(xprt_list); 72static LIST_HEAD(xprt_list);
@@ -292,54 +293,57 @@ static inline int xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task)
292 return retval; 293 return retval;
293} 294}
294 295
295static void __xprt_lock_write_next(struct rpc_xprt *xprt) 296static bool __xprt_lock_write_func(struct rpc_task *task, void *data)
296{ 297{
297 struct rpc_task *task; 298 struct rpc_xprt *xprt = data;
298 struct rpc_rqst *req; 299 struct rpc_rqst *req;
299 300
300 if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
301 return;
302
303 task = rpc_wake_up_next(&xprt->sending);
304 if (task == NULL)
305 goto out_unlock;
306
307 req = task->tk_rqstp; 301 req = task->tk_rqstp;
308 xprt->snd_task = task; 302 xprt->snd_task = task;
309 if (req) { 303 if (req) {
310 req->rq_bytes_sent = 0; 304 req->rq_bytes_sent = 0;
311 req->rq_ntrans++; 305 req->rq_ntrans++;
312 } 306 }
313 return; 307 return true;
308}
314 309
315out_unlock: 310static void __xprt_lock_write_next(struct rpc_xprt *xprt)
311{
312 if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
313 return;
314
315 if (rpc_wake_up_first(&xprt->sending, __xprt_lock_write_func, xprt))
316 return;
316 xprt_clear_locked(xprt); 317 xprt_clear_locked(xprt);
317} 318}
318 319
319static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt) 320static bool __xprt_lock_write_cong_func(struct rpc_task *task, void *data)
320{ 321{
321 struct rpc_task *task; 322 struct rpc_xprt *xprt = data;
322 struct rpc_rqst *req; 323 struct rpc_rqst *req;
323 324
324 if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
325 return;
326 if (RPCXPRT_CONGESTED(xprt))
327 goto out_unlock;
328 task = rpc_wake_up_next(&xprt->sending);
329 if (task == NULL)
330 goto out_unlock;
331
332 req = task->tk_rqstp; 325 req = task->tk_rqstp;
333 if (req == NULL) { 326 if (req == NULL) {
334 xprt->snd_task = task; 327 xprt->snd_task = task;
335 return; 328 return true;
336 } 329 }
337 if (__xprt_get_cong(xprt, task)) { 330 if (__xprt_get_cong(xprt, task)) {
338 xprt->snd_task = task; 331 xprt->snd_task = task;
339 req->rq_bytes_sent = 0; 332 req->rq_bytes_sent = 0;
340 req->rq_ntrans++; 333 req->rq_ntrans++;
341 return; 334 return true;
342 } 335 }
336 return false;
337}
338
339static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt)
340{
341 if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
342 return;
343 if (RPCXPRT_CONGESTED(xprt))
344 goto out_unlock;
345 if (rpc_wake_up_first(&xprt->sending, __xprt_lock_write_cong_func, xprt))
346 return;
343out_unlock: 347out_unlock:
344 xprt_clear_locked(xprt); 348 xprt_clear_locked(xprt);
345} 349}
@@ -712,9 +716,7 @@ void xprt_connect(struct rpc_task *task)
712 if (xprt_connected(xprt)) 716 if (xprt_connected(xprt))
713 xprt_release_write(xprt, task); 717 xprt_release_write(xprt, task);
714 else { 718 else {
715 if (task->tk_rqstp) 719 task->tk_rqstp->rq_bytes_sent = 0;
716 task->tk_rqstp->rq_bytes_sent = 0;
717
718 task->tk_timeout = task->tk_rqstp->rq_timeout; 720 task->tk_timeout = task->tk_rqstp->rq_timeout;
719 rpc_sleep_on(&xprt->pending, task, xprt_connect_status); 721 rpc_sleep_on(&xprt->pending, task, xprt_connect_status);
720 722
@@ -750,7 +752,7 @@ static void xprt_connect_status(struct rpc_task *task)
750 default: 752 default:
751 dprintk("RPC: %5u xprt_connect_status: error %d connecting to " 753 dprintk("RPC: %5u xprt_connect_status: error %d connecting to "
752 "server %s\n", task->tk_pid, -task->tk_status, 754 "server %s\n", task->tk_pid, -task->tk_status,
753 task->tk_client->cl_server); 755 xprt->servername);
754 xprt_release_write(xprt, task); 756 xprt_release_write(xprt, task);
755 task->tk_status = -EIO; 757 task->tk_status = -EIO;
756 } 758 }
@@ -884,7 +886,7 @@ void xprt_transmit(struct rpc_task *task)
884{ 886{
885 struct rpc_rqst *req = task->tk_rqstp; 887 struct rpc_rqst *req = task->tk_rqstp;
886 struct rpc_xprt *xprt = req->rq_xprt; 888 struct rpc_xprt *xprt = req->rq_xprt;
887 int status; 889 int status, numreqs;
888 890
889 dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); 891 dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen);
890 892
@@ -921,9 +923,14 @@ void xprt_transmit(struct rpc_task *task)
921 923
922 xprt->ops->set_retrans_timeout(task); 924 xprt->ops->set_retrans_timeout(task);
923 925
926 numreqs = atomic_read(&xprt->num_reqs);
927 if (numreqs > xprt->stat.max_slots)
928 xprt->stat.max_slots = numreqs;
924 xprt->stat.sends++; 929 xprt->stat.sends++;
925 xprt->stat.req_u += xprt->stat.sends - xprt->stat.recvs; 930 xprt->stat.req_u += xprt->stat.sends - xprt->stat.recvs;
926 xprt->stat.bklog_u += xprt->backlog.qlen; 931 xprt->stat.bklog_u += xprt->backlog.qlen;
932 xprt->stat.sending_u += xprt->sending.qlen;
933 xprt->stat.pending_u += xprt->pending.qlen;
927 934
928 /* Don't race with disconnect */ 935 /* Don't race with disconnect */
929 if (!xprt_connected(xprt)) 936 if (!xprt_connected(xprt))
@@ -1131,7 +1138,10 @@ void xprt_release(struct rpc_task *task)
1131 return; 1138 return;
1132 1139
1133 xprt = req->rq_xprt; 1140 xprt = req->rq_xprt;
1134 rpc_count_iostats(task); 1141 if (task->tk_ops->rpc_count_stats != NULL)
1142 task->tk_ops->rpc_count_stats(task, task->tk_calldata);
1143 else if (task->tk_client)
1144 rpc_count_iostats(task, task->tk_client->cl_metrics);
1135 spin_lock_bh(&xprt->transport_lock); 1145 spin_lock_bh(&xprt->transport_lock);
1136 xprt->ops->release_xprt(xprt, task); 1146 xprt->ops->release_xprt(xprt, task);
1137 if (xprt->ops->release_request) 1147 if (xprt->ops->release_request)
@@ -1220,6 +1230,17 @@ found:
1220 (unsigned long)xprt); 1230 (unsigned long)xprt);
1221 else 1231 else
1222 init_timer(&xprt->timer); 1232 init_timer(&xprt->timer);
1233
1234 if (strlen(args->servername) > RPC_MAXNETNAMELEN) {
1235 xprt_destroy(xprt);
1236 return ERR_PTR(-EINVAL);
1237 }
1238 xprt->servername = kstrdup(args->servername, GFP_KERNEL);
1239 if (xprt->servername == NULL) {
1240 xprt_destroy(xprt);
1241 return ERR_PTR(-ENOMEM);
1242 }
1243
1223 dprintk("RPC: created transport %p with %u slots\n", xprt, 1244 dprintk("RPC: created transport %p with %u slots\n", xprt,
1224 xprt->max_reqs); 1245 xprt->max_reqs);
1225out: 1246out:
@@ -1242,6 +1263,7 @@ static void xprt_destroy(struct rpc_xprt *xprt)
1242 rpc_destroy_wait_queue(&xprt->sending); 1263 rpc_destroy_wait_queue(&xprt->sending);
1243 rpc_destroy_wait_queue(&xprt->backlog); 1264 rpc_destroy_wait_queue(&xprt->backlog);
1244 cancel_work_sync(&xprt->task_cleanup); 1265 cancel_work_sync(&xprt->task_cleanup);
1266 kfree(xprt->servername);
1245 /* 1267 /*
1246 * Tear down transport state and free the rpc_xprt 1268 * Tear down transport state and free the rpc_xprt
1247 */ 1269 */