aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svc_xprt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/svc_xprt.c')
-rw-r--r--net/sunrpc/svc_xprt.c66
1 files changed, 28 insertions, 38 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index df124f78ee48..061b2e0f9118 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -9,6 +9,7 @@
9#include <linux/errno.h> 9#include <linux/errno.h>
10#include <linux/freezer.h> 10#include <linux/freezer.h>
11#include <linux/kthread.h> 11#include <linux/kthread.h>
12#include <linux/slab.h>
12#include <net/sock.h> 13#include <net/sock.h>
13#include <linux/sunrpc/stats.h> 14#include <linux/sunrpc/stats.h>
14#include <linux/sunrpc/svc_xprt.h> 15#include <linux/sunrpc/svc_xprt.h>
@@ -16,8 +17,6 @@
16 17
17#define RPCDBG_FACILITY RPCDBG_SVCXPRT 18#define RPCDBG_FACILITY RPCDBG_SVCXPRT
18 19
19#define SVC_MAX_WAKING 5
20
21static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt); 20static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt);
22static int svc_deferred_recv(struct svc_rqst *rqstp); 21static int svc_deferred_recv(struct svc_rqst *rqstp);
23static struct cache_deferred_req *svc_defer(struct cache_req *req); 22static struct cache_deferred_req *svc_defer(struct cache_req *req);
@@ -129,8 +128,8 @@ static void svc_xprt_free(struct kref *kref)
129 struct svc_xprt *xprt = 128 struct svc_xprt *xprt =
130 container_of(kref, struct svc_xprt, xpt_ref); 129 container_of(kref, struct svc_xprt, xpt_ref);
131 struct module *owner = xprt->xpt_class->xcl_owner; 130 struct module *owner = xprt->xpt_class->xcl_owner;
132 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags) 131 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags) &&
133 && xprt->xpt_auth_cache != NULL) 132 xprt->xpt_auth_cache != NULL)
134 svcauth_unix_info_release(xprt->xpt_auth_cache); 133 svcauth_unix_info_release(xprt->xpt_auth_cache);
135 xprt->xpt_ops->xpo_free(xprt); 134 xprt->xpt_ops->xpo_free(xprt);
136 module_put(owner); 135 module_put(owner);
@@ -175,11 +174,13 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
175 .sin_addr.s_addr = htonl(INADDR_ANY), 174 .sin_addr.s_addr = htonl(INADDR_ANY),
176 .sin_port = htons(port), 175 .sin_port = htons(port),
177 }; 176 };
177#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
178 struct sockaddr_in6 sin6 = { 178 struct sockaddr_in6 sin6 = {
179 .sin6_family = AF_INET6, 179 .sin6_family = AF_INET6,
180 .sin6_addr = IN6ADDR_ANY_INIT, 180 .sin6_addr = IN6ADDR_ANY_INIT,
181 .sin6_port = htons(port), 181 .sin6_port = htons(port),
182 }; 182 };
183#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
183 struct sockaddr *sap; 184 struct sockaddr *sap;
184 size_t len; 185 size_t len;
185 186
@@ -188,10 +189,12 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
188 sap = (struct sockaddr *)&sin; 189 sap = (struct sockaddr *)&sin;
189 len = sizeof(sin); 190 len = sizeof(sin);
190 break; 191 break;
192#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
191 case PF_INET6: 193 case PF_INET6:
192 sap = (struct sockaddr *)&sin6; 194 sap = (struct sockaddr *)&sin6;
193 len = sizeof(sin6); 195 len = sizeof(sin6);
194 break; 196 break;
197#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
195 default: 198 default:
196 return ERR_PTR(-EAFNOSUPPORT); 199 return ERR_PTR(-EAFNOSUPPORT);
197 } 200 }
@@ -233,7 +236,10 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
233 err: 236 err:
234 spin_unlock(&svc_xprt_class_lock); 237 spin_unlock(&svc_xprt_class_lock);
235 dprintk("svc: transport %s not found\n", xprt_name); 238 dprintk("svc: transport %s not found\n", xprt_name);
236 return -ENOENT; 239
240 /* This errno is exposed to user space. Provide a reasonable
241 * perror msg for a bad transport. */
242 return -EPROTONOSUPPORT;
237} 243}
238EXPORT_SYMBOL_GPL(svc_create_xprt); 244EXPORT_SYMBOL_GPL(svc_create_xprt);
239 245
@@ -306,7 +312,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
306 struct svc_pool *pool; 312 struct svc_pool *pool;
307 struct svc_rqst *rqstp; 313 struct svc_rqst *rqstp;
308 int cpu; 314 int cpu;
309 int thread_avail;
310 315
311 if (!(xprt->xpt_flags & 316 if (!(xprt->xpt_flags &
312 ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED)))) 317 ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED))))
@@ -318,6 +323,12 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
318 323
319 spin_lock_bh(&pool->sp_lock); 324 spin_lock_bh(&pool->sp_lock);
320 325
326 if (!list_empty(&pool->sp_threads) &&
327 !list_empty(&pool->sp_sockets))
328 printk(KERN_ERR
329 "svc_xprt_enqueue: "
330 "threads and transports both waiting??\n");
331
321 if (test_bit(XPT_DEAD, &xprt->xpt_flags)) { 332 if (test_bit(XPT_DEAD, &xprt->xpt_flags)) {
322 /* Don't enqueue dead transports */ 333 /* Don't enqueue dead transports */
323 dprintk("svc: transport %p is dead, not enqueued\n", xprt); 334 dprintk("svc: transport %p is dead, not enqueued\n", xprt);
@@ -358,15 +369,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
358 } 369 }
359 370
360 process: 371 process:
361 /* Work out whether threads are available */ 372 if (!list_empty(&pool->sp_threads)) {
362 thread_avail = !list_empty(&pool->sp_threads); /* threads are asleep */
363 if (pool->sp_nwaking >= SVC_MAX_WAKING) {
364 /* too many threads are runnable and trying to wake up */
365 thread_avail = 0;
366 pool->sp_stats.overloads_avoided++;
367 }
368
369 if (thread_avail) {
370 rqstp = list_entry(pool->sp_threads.next, 373 rqstp = list_entry(pool->sp_threads.next,
371 struct svc_rqst, 374 struct svc_rqst,
372 rq_list); 375 rq_list);
@@ -381,8 +384,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
381 svc_xprt_get(xprt); 384 svc_xprt_get(xprt);
382 rqstp->rq_reserved = serv->sv_max_mesg; 385 rqstp->rq_reserved = serv->sv_max_mesg;
383 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); 386 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
384 rqstp->rq_waking = 1;
385 pool->sp_nwaking++;
386 pool->sp_stats.threads_woken++; 387 pool->sp_stats.threads_woken++;
387 BUG_ON(xprt->xpt_pool != pool); 388 BUG_ON(xprt->xpt_pool != pool);
388 wake_up(&rqstp->rq_wait); 389 wake_up(&rqstp->rq_wait);
@@ -651,11 +652,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
651 return -EINTR; 652 return -EINTR;
652 653
653 spin_lock_bh(&pool->sp_lock); 654 spin_lock_bh(&pool->sp_lock);
654 if (rqstp->rq_waking) {
655 rqstp->rq_waking = 0;
656 pool->sp_nwaking--;
657 BUG_ON(pool->sp_nwaking < 0);
658 }
659 xprt = svc_xprt_dequeue(pool); 655 xprt = svc_xprt_dequeue(pool);
660 if (xprt) { 656 if (xprt) {
661 rqstp->rq_xprt = xprt; 657 rqstp->rq_xprt = xprt;
@@ -711,7 +707,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
711 spin_unlock_bh(&pool->sp_lock); 707 spin_unlock_bh(&pool->sp_lock);
712 708
713 len = 0; 709 len = 0;
714 if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { 710 if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
711 dprintk("svc_recv: found XPT_CLOSE\n");
712 svc_delete_xprt(xprt);
713 } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
715 struct svc_xprt *newxpt; 714 struct svc_xprt *newxpt;
716 newxpt = xprt->xpt_ops->xpo_accept(xprt); 715 newxpt = xprt->xpt_ops->xpo_accept(xprt);
717 if (newxpt) { 716 if (newxpt) {
@@ -737,7 +736,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
737 svc_xprt_received(newxpt); 736 svc_xprt_received(newxpt);
738 } 737 }
739 svc_xprt_received(xprt); 738 svc_xprt_received(xprt);
740 } else if (!test_bit(XPT_CLOSE, &xprt->xpt_flags)) { 739 } else {
741 dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", 740 dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
742 rqstp, pool->sp_id, xprt, 741 rqstp, pool->sp_id, xprt,
743 atomic_read(&xprt->xpt_ref.refcount)); 742 atomic_read(&xprt->xpt_ref.refcount));
@@ -750,11 +749,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
750 dprintk("svc: got len=%d\n", len); 749 dprintk("svc: got len=%d\n", len);
751 } 750 }
752 751
753 if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
754 dprintk("svc_recv: found XPT_CLOSE\n");
755 svc_delete_xprt(xprt);
756 }
757
758 /* No data, incomplete (TCP) read, or accept() */ 752 /* No data, incomplete (TCP) read, or accept() */
759 if (len == 0 || len == -EAGAIN) { 753 if (len == 0 || len == -EAGAIN) {
760 rqstp->rq_res.len = 0; 754 rqstp->rq_res.len = 0;
@@ -846,8 +840,8 @@ static void svc_age_temp_xprts(unsigned long closure)
846 * through, close it. */ 840 * through, close it. */
847 if (!test_and_set_bit(XPT_OLD, &xprt->xpt_flags)) 841 if (!test_and_set_bit(XPT_OLD, &xprt->xpt_flags))
848 continue; 842 continue;
849 if (atomic_read(&xprt->xpt_ref.refcount) > 1 843 if (atomic_read(&xprt->xpt_ref.refcount) > 1 ||
850 || test_bit(XPT_BUSY, &xprt->xpt_flags)) 844 test_bit(XPT_BUSY, &xprt->xpt_flags))
851 continue; 845 continue;
852 svc_xprt_get(xprt); 846 svc_xprt_get(xprt);
853 list_move(le, &to_be_aged); 847 list_move(le, &to_be_aged);
@@ -900,11 +894,8 @@ void svc_delete_xprt(struct svc_xprt *xprt)
900 if (test_bit(XPT_TEMP, &xprt->xpt_flags)) 894 if (test_bit(XPT_TEMP, &xprt->xpt_flags))
901 serv->sv_tmpcnt--; 895 serv->sv_tmpcnt--;
902 896
903 for (dr = svc_deferred_dequeue(xprt); dr; 897 while ((dr = svc_deferred_dequeue(xprt)) != NULL)
904 dr = svc_deferred_dequeue(xprt)) {
905 svc_xprt_put(xprt);
906 kfree(dr); 898 kfree(dr);
907 }
908 899
909 svc_xprt_put(xprt); 900 svc_xprt_put(xprt);
910 spin_unlock_bh(&serv->sv_lock); 901 spin_unlock_bh(&serv->sv_lock);
@@ -1204,16 +1195,15 @@ static int svc_pool_stats_show(struct seq_file *m, void *p)
1204 struct svc_pool *pool = p; 1195 struct svc_pool *pool = p;
1205 1196
1206 if (p == SEQ_START_TOKEN) { 1197 if (p == SEQ_START_TOKEN) {
1207 seq_puts(m, "# pool packets-arrived sockets-enqueued threads-woken overloads-avoided threads-timedout\n"); 1198 seq_puts(m, "# pool packets-arrived sockets-enqueued threads-woken threads-timedout\n");
1208 return 0; 1199 return 0;
1209 } 1200 }
1210 1201
1211 seq_printf(m, "%u %lu %lu %lu %lu %lu\n", 1202 seq_printf(m, "%u %lu %lu %lu %lu\n",
1212 pool->sp_id, 1203 pool->sp_id,
1213 pool->sp_stats.packets, 1204 pool->sp_stats.packets,
1214 pool->sp_stats.sockets_queued, 1205 pool->sp_stats.sockets_queued,
1215 pool->sp_stats.threads_woken, 1206 pool->sp_stats.threads_woken,
1216 pool->sp_stats.overloads_avoided,
1217 pool->sp_stats.threads_timedout); 1207 pool->sp_stats.threads_timedout);
1218 1208
1219 return 0; 1209 return 0;