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.c29
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)
601struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid) 604struct 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)