diff options
Diffstat (limited to 'net/sunrpc/xprt.c')
-rw-r--r-- | net/sunrpc/xprt.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 8ff2c8acb223..4dd5b3cfe754 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -44,13 +44,13 @@ | |||
44 | #include <linux/random.h> | 44 | #include <linux/random.h> |
45 | 45 | ||
46 | #include <linux/sunrpc/clnt.h> | 46 | #include <linux/sunrpc/clnt.h> |
47 | #include <linux/sunrpc/metrics.h> | ||
47 | 48 | ||
48 | /* | 49 | /* |
49 | * Local variables | 50 | * Local variables |
50 | */ | 51 | */ |
51 | 52 | ||
52 | #ifdef RPC_DEBUG | 53 | #ifdef RPC_DEBUG |
53 | # undef RPC_DEBUG_DATA | ||
54 | # define RPCDBG_FACILITY RPCDBG_XPRT | 54 | # define RPCDBG_FACILITY RPCDBG_XPRT |
55 | #endif | 55 | #endif |
56 | 56 | ||
@@ -548,6 +548,7 @@ void xprt_connect(struct rpc_task *task) | |||
548 | 548 | ||
549 | task->tk_timeout = xprt->connect_timeout; | 549 | task->tk_timeout = xprt->connect_timeout; |
550 | rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL); | 550 | rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL); |
551 | xprt->stat.connect_start = jiffies; | ||
551 | xprt->ops->connect(task); | 552 | xprt->ops->connect(task); |
552 | } | 553 | } |
553 | return; | 554 | return; |
@@ -558,6 +559,8 @@ static void xprt_connect_status(struct rpc_task *task) | |||
558 | struct rpc_xprt *xprt = task->tk_xprt; | 559 | struct rpc_xprt *xprt = task->tk_xprt; |
559 | 560 | ||
560 | if (task->tk_status >= 0) { | 561 | if (task->tk_status >= 0) { |
562 | xprt->stat.connect_count++; | ||
563 | xprt->stat.connect_time += (long)jiffies - xprt->stat.connect_start; | ||
561 | dprintk("RPC: %4d xprt_connect_status: connection established\n", | 564 | dprintk("RPC: %4d xprt_connect_status: connection established\n", |
562 | task->tk_pid); | 565 | task->tk_pid); |
563 | return; | 566 | return; |
@@ -601,16 +604,14 @@ static void xprt_connect_status(struct rpc_task *task) | |||
601 | struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid) | 604 | struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid) |
602 | { | 605 | { |
603 | struct list_head *pos; | 606 | struct list_head *pos; |
604 | struct rpc_rqst *req = NULL; | ||
605 | 607 | ||
606 | list_for_each(pos, &xprt->recv) { | 608 | list_for_each(pos, &xprt->recv) { |
607 | struct rpc_rqst *entry = list_entry(pos, struct rpc_rqst, rq_list); | 609 | struct rpc_rqst *entry = list_entry(pos, struct rpc_rqst, rq_list); |
608 | if (entry->rq_xid == xid) { | 610 | if (entry->rq_xid == xid) |
609 | req = entry; | 611 | return entry; |
610 | break; | ||
611 | } | ||
612 | } | 612 | } |
613 | return req; | 613 | xprt->stat.bad_xids++; |
614 | return NULL; | ||
614 | } | 615 | } |
615 | 616 | ||
616 | /** | 617 | /** |
@@ -646,7 +647,12 @@ void xprt_complete_rqst(struct rpc_task *task, int copied) | |||
646 | dprintk("RPC: %5u xid %08x complete (%d bytes received)\n", | 647 | dprintk("RPC: %5u xid %08x complete (%d bytes received)\n", |
647 | task->tk_pid, ntohl(req->rq_xid), copied); | 648 | task->tk_pid, ntohl(req->rq_xid), copied); |
648 | 649 | ||
650 | task->tk_xprt->stat.recvs++; | ||
651 | task->tk_rtt = (long)jiffies - req->rq_xtime; | ||
652 | |||
649 | list_del_init(&req->rq_list); | 653 | list_del_init(&req->rq_list); |
654 | /* Ensure all writes are done before we update req->rq_received */ | ||
655 | smp_wmb(); | ||
650 | req->rq_received = req->rq_private_buf.len = copied; | 656 | req->rq_received = req->rq_private_buf.len = copied; |
651 | rpc_wake_up_task(task); | 657 | rpc_wake_up_task(task); |
652 | } | 658 | } |
@@ -723,7 +729,6 @@ void xprt_transmit(struct rpc_task *task) | |||
723 | 729 | ||
724 | dprintk("RPC: %4d xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); | 730 | dprintk("RPC: %4d xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); |
725 | 731 | ||
726 | smp_rmb(); | ||
727 | if (!req->rq_received) { | 732 | if (!req->rq_received) { |
728 | if (list_empty(&req->rq_list)) { | 733 | if (list_empty(&req->rq_list)) { |
729 | spin_lock_bh(&xprt->transport_lock); | 734 | spin_lock_bh(&xprt->transport_lock); |
@@ -744,12 +749,19 @@ void xprt_transmit(struct rpc_task *task) | |||
744 | if (status == 0) { | 749 | if (status == 0) { |
745 | dprintk("RPC: %4d xmit complete\n", task->tk_pid); | 750 | dprintk("RPC: %4d xmit complete\n", task->tk_pid); |
746 | spin_lock_bh(&xprt->transport_lock); | 751 | spin_lock_bh(&xprt->transport_lock); |
752 | |||
747 | xprt->ops->set_retrans_timeout(task); | 753 | xprt->ops->set_retrans_timeout(task); |
754 | |||
755 | xprt->stat.sends++; | ||
756 | xprt->stat.req_u += xprt->stat.sends - xprt->stat.recvs; | ||
757 | xprt->stat.bklog_u += xprt->backlog.qlen; | ||
758 | |||
748 | /* Don't race with disconnect */ | 759 | /* Don't race with disconnect */ |
749 | if (!xprt_connected(xprt)) | 760 | if (!xprt_connected(xprt)) |
750 | task->tk_status = -ENOTCONN; | 761 | task->tk_status = -ENOTCONN; |
751 | else if (!req->rq_received) | 762 | else if (!req->rq_received) |
752 | rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer); | 763 | rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer); |
764 | |||
753 | xprt->ops->release_xprt(xprt, task); | 765 | xprt->ops->release_xprt(xprt, task); |
754 | spin_unlock_bh(&xprt->transport_lock); | 766 | spin_unlock_bh(&xprt->transport_lock); |
755 | return; | 767 | return; |
@@ -848,6 +860,7 @@ void xprt_release(struct rpc_task *task) | |||
848 | 860 | ||
849 | if (!(req = task->tk_rqstp)) | 861 | if (!(req = task->tk_rqstp)) |
850 | return; | 862 | return; |
863 | rpc_count_iostats(task); | ||
851 | spin_lock_bh(&xprt->transport_lock); | 864 | spin_lock_bh(&xprt->transport_lock); |
852 | xprt->ops->release_xprt(xprt, task); | 865 | xprt->ops->release_xprt(xprt, task); |
853 | if (xprt->ops->release_request) | 866 | if (xprt->ops->release_request) |