aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/Kconfig2
-rw-r--r--net/sunrpc/svc.c6
-rw-r--r--net/sunrpc/svc_xprt.c127
-rw-r--r--net/sunrpc/svcsock.c35
4 files changed, 129 insertions, 41 deletions
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index afd91c78ce8e..443c161eb8bd 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -47,7 +47,7 @@ config RPCSEC_GSS_SPKM3
47 select CRYPTO_CBC 47 select CRYPTO_CBC
48 help 48 help
49 Choose Y here to enable Secure RPC using the SPKM3 public key 49 Choose Y here to enable Secure RPC using the SPKM3 public key
50 GSS-API mechansim (RFC 2025). 50 GSS-API mechanism (RFC 2025).
51 51
52 Secure RPC calls with SPKM3 require an auxiliary userspace 52 Secure RPC calls with SPKM3 require an auxiliary userspace
53 daemon which may be found in the Linux nfs-utils package 53 daemon which may be found in the Linux nfs-utils package
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 9f2f2412a2f3..8847add6ca16 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -317,8 +317,7 @@ svc_pool_map_set_cpumask(struct task_struct *task, unsigned int pidx)
317 } 317 }
318 case SVC_POOL_PERNODE: 318 case SVC_POOL_PERNODE:
319 { 319 {
320 node_to_cpumask_ptr(nodecpumask, node); 320 set_cpus_allowed_ptr(task, cpumask_of_node(node));
321 set_cpus_allowed_ptr(task, nodecpumask);
322 break; 321 break;
323 } 322 }
324 } 323 }
@@ -1009,6 +1008,8 @@ svc_process(struct svc_rqst *rqstp)
1009 rqstp->rq_res.tail[0].iov_len = 0; 1008 rqstp->rq_res.tail[0].iov_len = 0;
1010 /* Will be turned off only in gss privacy case: */ 1009 /* Will be turned off only in gss privacy case: */
1011 rqstp->rq_splice_ok = 1; 1010 rqstp->rq_splice_ok = 1;
1011 /* Will be turned off only when NFSv4 Sessions are used */
1012 rqstp->rq_usedeferral = 1;
1012 1013
1013 /* Setup reply header */ 1014 /* Setup reply header */
1014 rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); 1015 rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
@@ -1079,7 +1080,6 @@ svc_process(struct svc_rqst *rqstp)
1079 procp = versp->vs_proc + proc; 1080 procp = versp->vs_proc + proc;
1080 if (proc >= versp->vs_nproc || !procp->pc_func) 1081 if (proc >= versp->vs_nproc || !procp->pc_func)
1081 goto err_bad_proc; 1082 goto err_bad_proc;
1082 rqstp->rq_server = serv;
1083 rqstp->rq_procinfo = procp; 1083 rqstp->rq_procinfo = procp;
1084 1084
1085 /* Syntactic check complete */ 1085 /* Syntactic check complete */
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 2819ee093f36..c200d92e57e4 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -14,6 +14,8 @@
14 14
15#define RPCDBG_FACILITY RPCDBG_SVCXPRT 15#define RPCDBG_FACILITY RPCDBG_SVCXPRT
16 16
17#define SVC_MAX_WAKING 5
18
17static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt); 19static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt);
18static int svc_deferred_recv(struct svc_rqst *rqstp); 20static int svc_deferred_recv(struct svc_rqst *rqstp);
19static struct cache_deferred_req *svc_defer(struct cache_req *req); 21static struct cache_deferred_req *svc_defer(struct cache_req *req);
@@ -301,6 +303,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
301 struct svc_pool *pool; 303 struct svc_pool *pool;
302 struct svc_rqst *rqstp; 304 struct svc_rqst *rqstp;
303 int cpu; 305 int cpu;
306 int thread_avail;
304 307
305 if (!(xprt->xpt_flags & 308 if (!(xprt->xpt_flags &
306 ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED)))) 309 ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED))))
@@ -312,18 +315,14 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
312 315
313 spin_lock_bh(&pool->sp_lock); 316 spin_lock_bh(&pool->sp_lock);
314 317
315 if (!list_empty(&pool->sp_threads) &&
316 !list_empty(&pool->sp_sockets))
317 printk(KERN_ERR
318 "svc_xprt_enqueue: "
319 "threads and transports both waiting??\n");
320
321 if (test_bit(XPT_DEAD, &xprt->xpt_flags)) { 318 if (test_bit(XPT_DEAD, &xprt->xpt_flags)) {
322 /* Don't enqueue dead transports */ 319 /* Don't enqueue dead transports */
323 dprintk("svc: transport %p is dead, not enqueued\n", xprt); 320 dprintk("svc: transport %p is dead, not enqueued\n", xprt);
324 goto out_unlock; 321 goto out_unlock;
325 } 322 }
326 323
324 pool->sp_stats.packets++;
325
327 /* Mark transport as busy. It will remain in this state until 326 /* Mark transport as busy. It will remain in this state until
328 * the provider calls svc_xprt_received. We update XPT_BUSY 327 * the provider calls svc_xprt_received. We update XPT_BUSY
329 * atomically because it also guards against trying to enqueue 328 * atomically because it also guards against trying to enqueue
@@ -356,7 +355,15 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
356 } 355 }
357 356
358 process: 357 process:
359 if (!list_empty(&pool->sp_threads)) { 358 /* Work out whether threads are available */
359 thread_avail = !list_empty(&pool->sp_threads); /* threads are asleep */
360 if (pool->sp_nwaking >= SVC_MAX_WAKING) {
361 /* too many threads are runnable and trying to wake up */
362 thread_avail = 0;
363 pool->sp_stats.overloads_avoided++;
364 }
365
366 if (thread_avail) {
360 rqstp = list_entry(pool->sp_threads.next, 367 rqstp = list_entry(pool->sp_threads.next,
361 struct svc_rqst, 368 struct svc_rqst,
362 rq_list); 369 rq_list);
@@ -371,11 +378,15 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
371 svc_xprt_get(xprt); 378 svc_xprt_get(xprt);
372 rqstp->rq_reserved = serv->sv_max_mesg; 379 rqstp->rq_reserved = serv->sv_max_mesg;
373 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); 380 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
381 rqstp->rq_waking = 1;
382 pool->sp_nwaking++;
383 pool->sp_stats.threads_woken++;
374 BUG_ON(xprt->xpt_pool != pool); 384 BUG_ON(xprt->xpt_pool != pool);
375 wake_up(&rqstp->rq_wait); 385 wake_up(&rqstp->rq_wait);
376 } else { 386 } else {
377 dprintk("svc: transport %p put into queue\n", xprt); 387 dprintk("svc: transport %p put into queue\n", xprt);
378 list_add_tail(&xprt->xpt_ready, &pool->sp_sockets); 388 list_add_tail(&xprt->xpt_ready, &pool->sp_sockets);
389 pool->sp_stats.sockets_queued++;
379 BUG_ON(xprt->xpt_pool != pool); 390 BUG_ON(xprt->xpt_pool != pool);
380 } 391 }
381 392
@@ -588,6 +599,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
588 int pages; 599 int pages;
589 struct xdr_buf *arg; 600 struct xdr_buf *arg;
590 DECLARE_WAITQUEUE(wait, current); 601 DECLARE_WAITQUEUE(wait, current);
602 long time_left;
591 603
592 dprintk("svc: server %p waiting for data (to = %ld)\n", 604 dprintk("svc: server %p waiting for data (to = %ld)\n",
593 rqstp, timeout); 605 rqstp, timeout);
@@ -636,6 +648,11 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
636 return -EINTR; 648 return -EINTR;
637 649
638 spin_lock_bh(&pool->sp_lock); 650 spin_lock_bh(&pool->sp_lock);
651 if (rqstp->rq_waking) {
652 rqstp->rq_waking = 0;
653 pool->sp_nwaking--;
654 BUG_ON(pool->sp_nwaking < 0);
655 }
639 xprt = svc_xprt_dequeue(pool); 656 xprt = svc_xprt_dequeue(pool);
640 if (xprt) { 657 if (xprt) {
641 rqstp->rq_xprt = xprt; 658 rqstp->rq_xprt = xprt;
@@ -668,12 +685,14 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
668 add_wait_queue(&rqstp->rq_wait, &wait); 685 add_wait_queue(&rqstp->rq_wait, &wait);
669 spin_unlock_bh(&pool->sp_lock); 686 spin_unlock_bh(&pool->sp_lock);
670 687
671 schedule_timeout(timeout); 688 time_left = schedule_timeout(timeout);
672 689
673 try_to_freeze(); 690 try_to_freeze();
674 691
675 spin_lock_bh(&pool->sp_lock); 692 spin_lock_bh(&pool->sp_lock);
676 remove_wait_queue(&rqstp->rq_wait, &wait); 693 remove_wait_queue(&rqstp->rq_wait, &wait);
694 if (!time_left)
695 pool->sp_stats.threads_timedout++;
677 696
678 xprt = rqstp->rq_xprt; 697 xprt = rqstp->rq_xprt;
679 if (!xprt) { 698 if (!xprt) {
@@ -958,7 +977,7 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req)
958 struct svc_rqst *rqstp = container_of(req, struct svc_rqst, rq_chandle); 977 struct svc_rqst *rqstp = container_of(req, struct svc_rqst, rq_chandle);
959 struct svc_deferred_req *dr; 978 struct svc_deferred_req *dr;
960 979
961 if (rqstp->rq_arg.page_len) 980 if (rqstp->rq_arg.page_len || !rqstp->rq_usedeferral)
962 return NULL; /* if more than a page, give up FIXME */ 981 return NULL; /* if more than a page, give up FIXME */
963 if (rqstp->rq_deferred) { 982 if (rqstp->rq_deferred) {
964 dr = rqstp->rq_deferred; 983 dr = rqstp->rq_deferred;
@@ -1112,3 +1131,93 @@ int svc_xprt_names(struct svc_serv *serv, char *buf, int buflen)
1112 return totlen; 1131 return totlen;
1113} 1132}
1114EXPORT_SYMBOL_GPL(svc_xprt_names); 1133EXPORT_SYMBOL_GPL(svc_xprt_names);
1134
1135
1136/*----------------------------------------------------------------------------*/
1137
1138static void *svc_pool_stats_start(struct seq_file *m, loff_t *pos)
1139{
1140 unsigned int pidx = (unsigned int)*pos;
1141 struct svc_serv *serv = m->private;
1142
1143 dprintk("svc_pool_stats_start, *pidx=%u\n", pidx);
1144
1145 lock_kernel();
1146 /* bump up the pseudo refcount while traversing */
1147 svc_get(serv);
1148 unlock_kernel();
1149
1150 if (!pidx)
1151 return SEQ_START_TOKEN;
1152 return (pidx > serv->sv_nrpools ? NULL : &serv->sv_pools[pidx-1]);
1153}
1154
1155static void *svc_pool_stats_next(struct seq_file *m, void *p, loff_t *pos)
1156{
1157 struct svc_pool *pool = p;
1158 struct svc_serv *serv = m->private;
1159
1160 dprintk("svc_pool_stats_next, *pos=%llu\n", *pos);
1161
1162 if (p == SEQ_START_TOKEN) {
1163 pool = &serv->sv_pools[0];
1164 } else {
1165 unsigned int pidx = (pool - &serv->sv_pools[0]);
1166 if (pidx < serv->sv_nrpools-1)
1167 pool = &serv->sv_pools[pidx+1];
1168 else
1169 pool = NULL;
1170 }
1171 ++*pos;
1172 return pool;
1173}
1174
1175static void svc_pool_stats_stop(struct seq_file *m, void *p)
1176{
1177 struct svc_serv *serv = m->private;
1178
1179 lock_kernel();
1180 /* this function really, really should have been called svc_put() */
1181 svc_destroy(serv);
1182 unlock_kernel();
1183}
1184
1185static int svc_pool_stats_show(struct seq_file *m, void *p)
1186{
1187 struct svc_pool *pool = p;
1188
1189 if (p == SEQ_START_TOKEN) {
1190 seq_puts(m, "# pool packets-arrived sockets-enqueued threads-woken overloads-avoided threads-timedout\n");
1191 return 0;
1192 }
1193
1194 seq_printf(m, "%u %lu %lu %lu %lu %lu\n",
1195 pool->sp_id,
1196 pool->sp_stats.packets,
1197 pool->sp_stats.sockets_queued,
1198 pool->sp_stats.threads_woken,
1199 pool->sp_stats.overloads_avoided,
1200 pool->sp_stats.threads_timedout);
1201
1202 return 0;
1203}
1204
1205static const struct seq_operations svc_pool_stats_seq_ops = {
1206 .start = svc_pool_stats_start,
1207 .next = svc_pool_stats_next,
1208 .stop = svc_pool_stats_stop,
1209 .show = svc_pool_stats_show,
1210};
1211
1212int svc_pool_stats_open(struct svc_serv *serv, struct file *file)
1213{
1214 int err;
1215
1216 err = seq_open(file, &svc_pool_stats_seq_ops);
1217 if (!err)
1218 ((struct seq_file *) file->private_data)->private = serv;
1219 return err;
1220}
1221EXPORT_SYMBOL(svc_pool_stats_open);
1222
1223/*----------------------------------------------------------------------------*/
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 9d504234af4a..af3198814c15 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -345,7 +345,6 @@ static void svc_sock_setbufsize(struct socket *sock, unsigned int snd,
345 lock_sock(sock->sk); 345 lock_sock(sock->sk);
346 sock->sk->sk_sndbuf = snd * 2; 346 sock->sk->sk_sndbuf = snd * 2;
347 sock->sk->sk_rcvbuf = rcv * 2; 347 sock->sk->sk_rcvbuf = rcv * 2;
348 sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK|SOCK_RCVBUF_LOCK;
349 release_sock(sock->sk); 348 release_sock(sock->sk);
350#endif 349#endif
351} 350}
@@ -797,23 +796,6 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
797 test_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags), 796 test_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags),
798 test_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags)); 797 test_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags));
799 798
800 if (test_and_clear_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags))
801 /* sndbuf needs to have room for one request
802 * per thread, otherwise we can stall even when the
803 * network isn't a bottleneck.
804 *
805 * We count all threads rather than threads in a
806 * particular pool, which provides an upper bound
807 * on the number of threads which will access the socket.
808 *
809 * rcvbuf just needs to be able to hold a few requests.
810 * Normally they will be removed from the queue
811 * as soon a a complete request arrives.
812 */
813 svc_sock_setbufsize(svsk->sk_sock,
814 (serv->sv_nrthreads+3) * serv->sv_max_mesg,
815 3 * serv->sv_max_mesg);
816
817 clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 799 clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
818 800
819 /* Receive data. If we haven't got the record length yet, get 801 /* Receive data. If we haven't got the record length yet, get
@@ -1061,15 +1043,6 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
1061 1043
1062 tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; 1044 tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF;
1063 1045
1064 /* initialise setting must have enough space to
1065 * receive and respond to one request.
1066 * svc_tcp_recvfrom will re-adjust if necessary
1067 */
1068 svc_sock_setbufsize(svsk->sk_sock,
1069 3 * svsk->sk_xprt.xpt_server->sv_max_mesg,
1070 3 * svsk->sk_xprt.xpt_server->sv_max_mesg);
1071
1072 set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags);
1073 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); 1046 set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
1074 if (sk->sk_state != TCP_ESTABLISHED) 1047 if (sk->sk_state != TCP_ESTABLISHED)
1075 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); 1048 set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
@@ -1139,8 +1112,14 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
1139 /* Initialize the socket */ 1112 /* Initialize the socket */
1140 if (sock->type == SOCK_DGRAM) 1113 if (sock->type == SOCK_DGRAM)
1141 svc_udp_init(svsk, serv); 1114 svc_udp_init(svsk, serv);
1142 else 1115 else {
1116 /* initialise setting must have enough space to
1117 * receive and respond to one request.
1118 */
1119 svc_sock_setbufsize(svsk->sk_sock, 4 * serv->sv_max_mesg,
1120 4 * serv->sv_max_mesg);
1143 svc_tcp_init(svsk, serv); 1121 svc_tcp_init(svsk, serv);
1122 }
1144 1123
1145 dprintk("svc: svc_setup_socket created %p (inet %p)\n", 1124 dprintk("svc: svc_setup_socket created %p (inet %p)\n",
1146 svsk, svsk->sk_sk); 1125 svsk, svsk->sk_sk);