aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sunrpc/svc_xprt.c103
1 files changed, 67 insertions, 36 deletions
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 295e6ed21ca0..6ebc9a95bbab 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -568,33 +568,12 @@ static void svc_check_conn_limits(struct svc_serv *serv)
568 } 568 }
569} 569}
570 570
571/* 571int svc_alloc_arg(struct svc_rqst *rqstp)
572 * Receive the next request on any transport. This code is carefully
573 * organised not to touch any cachelines in the shared svc_serv
574 * structure, only cachelines in the local svc_pool.
575 */
576int svc_recv(struct svc_rqst *rqstp, long timeout)
577{ 572{
578 struct svc_xprt *xprt = NULL; 573 struct svc_serv *serv = rqstp->rq_server;
579 struct svc_serv *serv = rqstp->rq_server; 574 struct xdr_buf *arg;
580 struct svc_pool *pool = rqstp->rq_pool; 575 int pages;
581 int len, i; 576 int i;
582 int pages;
583 struct xdr_buf *arg;
584 DECLARE_WAITQUEUE(wait, current);
585 long time_left;
586
587 dprintk("svc: server %p waiting for data (to = %ld)\n",
588 rqstp, timeout);
589
590 if (rqstp->rq_xprt)
591 printk(KERN_ERR
592 "svc_recv: service %p, transport not NULL!\n",
593 rqstp);
594 if (waitqueue_active(&rqstp->rq_wait))
595 printk(KERN_ERR
596 "svc_recv: service %p, wait queue active!\n",
597 rqstp);
598 577
599 /* now allocate needed pages. If we get a failure, sleep briefly */ 578 /* now allocate needed pages. If we get a failure, sleep briefly */
600 pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE; 579 pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE;
@@ -624,11 +603,15 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
624 arg->page_len = (pages-2)*PAGE_SIZE; 603 arg->page_len = (pages-2)*PAGE_SIZE;
625 arg->len = (pages-1)*PAGE_SIZE; 604 arg->len = (pages-1)*PAGE_SIZE;
626 arg->tail[0].iov_len = 0; 605 arg->tail[0].iov_len = 0;
606 return 0;
607}
627 608
628 try_to_freeze(); 609struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout)
629 cond_resched(); 610{
630 if (signalled() || kthread_should_stop()) 611 struct svc_xprt *xprt;
631 return -EINTR; 612 struct svc_pool *pool = rqstp->rq_pool;
613 DECLARE_WAITQUEUE(wait, current);
614 long time_left;
632 615
633 /* Normally we will wait up to 5 seconds for any required 616 /* Normally we will wait up to 5 seconds for any required
634 * cache information to be provided. 617 * cache information to be provided.
@@ -666,7 +649,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
666 if (kthread_should_stop()) { 649 if (kthread_should_stop()) {
667 set_current_state(TASK_RUNNING); 650 set_current_state(TASK_RUNNING);
668 spin_unlock_bh(&pool->sp_lock); 651 spin_unlock_bh(&pool->sp_lock);
669 return -EINTR; 652 return ERR_PTR(-EINTR);
670 } 653 }
671 654
672 add_wait_queue(&rqstp->rq_wait, &wait); 655 add_wait_queue(&rqstp->rq_wait, &wait);
@@ -687,19 +670,25 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
687 spin_unlock_bh(&pool->sp_lock); 670 spin_unlock_bh(&pool->sp_lock);
688 dprintk("svc: server %p, no data yet\n", rqstp); 671 dprintk("svc: server %p, no data yet\n", rqstp);
689 if (signalled() || kthread_should_stop()) 672 if (signalled() || kthread_should_stop())
690 return -EINTR; 673 return ERR_PTR(-EINTR);
691 else 674 else
692 return -EAGAIN; 675 return ERR_PTR(-EAGAIN);
693 } 676 }
694 } 677 }
695 spin_unlock_bh(&pool->sp_lock); 678 spin_unlock_bh(&pool->sp_lock);
679 return xprt;
680}
681
682static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt)
683{
684 struct svc_serv *serv = rqstp->rq_server;
685 int len = 0;
696 686
697 len = 0;
698 if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { 687 if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
699 dprintk("svc_recv: found XPT_CLOSE\n"); 688 dprintk("svc_recv: found XPT_CLOSE\n");
700 svc_delete_xprt(xprt); 689 svc_delete_xprt(xprt);
701 /* Leave XPT_BUSY set on the dead xprt: */ 690 /* Leave XPT_BUSY set on the dead xprt: */
702 goto out; 691 return 0;
703 } 692 }
704 if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { 693 if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) {
705 struct svc_xprt *newxpt; 694 struct svc_xprt *newxpt;
@@ -727,8 +716,9 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
727 svc_xprt_received(newxpt); 716 svc_xprt_received(newxpt);
728 } 717 }
729 } else if (xprt->xpt_ops->xpo_has_wspace(xprt)) { 718 } else if (xprt->xpt_ops->xpo_has_wspace(xprt)) {
719 /* XPT_DATA|XPT_DEFERRED case: */
730 dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", 720 dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n",
731 rqstp, pool->sp_id, xprt, 721 rqstp, rqstp->rq_pool->sp_id, xprt,
732 atomic_read(&xprt->xpt_ref.refcount)); 722 atomic_read(&xprt->xpt_ref.refcount));
733 rqstp->rq_deferred = svc_deferred_dequeue(xprt); 723 rqstp->rq_deferred = svc_deferred_dequeue(xprt);
734 if (rqstp->rq_deferred) 724 if (rqstp->rq_deferred)
@@ -739,7 +729,48 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
739 rqstp->rq_reserved = serv->sv_max_mesg; 729 rqstp->rq_reserved = serv->sv_max_mesg;
740 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); 730 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
741 } 731 }
732 /* clear XPT_BUSY: */
742 svc_xprt_received(xprt); 733 svc_xprt_received(xprt);
734 return len;
735}
736
737/*
738 * Receive the next request on any transport. This code is carefully
739 * organised not to touch any cachelines in the shared svc_serv
740 * structure, only cachelines in the local svc_pool.
741 */
742int svc_recv(struct svc_rqst *rqstp, long timeout)
743{
744 struct svc_xprt *xprt = NULL;
745 struct svc_serv *serv = rqstp->rq_server;
746 int len, err;
747
748 dprintk("svc: server %p waiting for data (to = %ld)\n",
749 rqstp, timeout);
750
751 if (rqstp->rq_xprt)
752 printk(KERN_ERR
753 "svc_recv: service %p, transport not NULL!\n",
754 rqstp);
755 if (waitqueue_active(&rqstp->rq_wait))
756 printk(KERN_ERR
757 "svc_recv: service %p, wait queue active!\n",
758 rqstp);
759
760 err = svc_alloc_arg(rqstp);
761 if (err)
762 return err;
763
764 try_to_freeze();
765 cond_resched();
766 if (signalled() || kthread_should_stop())
767 return -EINTR;
768
769 xprt = svc_get_next_xprt(rqstp, timeout);
770 if (IS_ERR(xprt))
771 return PTR_ERR(xprt);
772
773 len = svc_handle_xprt(rqstp, xprt);
743 774
744 /* No data, incomplete (TCP) read, or accept() */ 775 /* No data, incomplete (TCP) read, or accept() */
745 if (len <= 0) 776 if (len <= 0)