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) |
