SUNRPC: add sending,pending queue and max slot to xprt stats
authorAndy Adamson <andros@netapp.com>
Tue, 14 Feb 2012 21:19:18 +0000 (16:19 -0500)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Thu, 16 Feb 2012 19:55:27 +0000 (14:55 -0500)
With static RPC slots, the xprt backlog queue stats were useful in showing
when the transport (TCP) was starved by lack of RPC slots. The new dynamic
RPC slot code, commit d9ba131d8f58c0d2ff5029e7002ab43f913b36f9, always
provides an RPC slot and so only uses the xprt backlog queue when the
tcp_max_slot_table_entries value has been hit or when an allocation error
occurs. All requests are now placed on the xprt sending or pending queue which
need to be monitored for debugging.

The max_slot stat shows the maximum number of dynamic RPC slots reached which is
useful when debugging performance issues.

Add the new fields at the end of the mountstats xprt stanza so that mountstats
outputs the previous correct values and ignores the new fields. Bump
NFS_IOSTATS_VERS.

Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
include/linux/nfs_iostat.h
include/linux/sunrpc/xprt.h
net/sunrpc/xprt.c
net/sunrpc/xprtsock.c

index 8866bb3502ee1df94075aa2068a980cb7fe2f090..9dcbbe9a51fb17da49fe9d8e8a4deaadd67ccec1 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef _LINUX_NFS_IOSTAT
 #define _LINUX_NFS_IOSTAT
 
-#define NFS_IOSTAT_VERS                "1.0"
+#define NFS_IOSTAT_VERS                "1.1"
 
 /*
  * NFS byte counters
index b033f366d5f678943c04c9289f380a1ae3436317..ea712f97f4a13bae92d70821515ed954881e7d96 100644 (file)
@@ -219,10 +219,13 @@ struct rpc_xprt {
                                        connect_time,   /* jiffies waiting for connect */
                                        sends,          /* how many complete requests */
                                        recvs,          /* how many complete requests */
-                                       bad_xids;       /* lookup_rqst didn't find XID */
+                                       bad_xids,       /* lookup_rqst didn't find XID */
+                                       max_slots;      /* max rpc_slots used */
 
                unsigned long long      req_u,          /* average requests on the wire */
-                                       bklog_u;        /* backlog queue utilization */
+                                       bklog_u,        /* backlog queue utilization */
+                                       sending_u,      /* send q utilization */
+                                       pending_u;      /* pend q utilization */
        } stat;
 
        struct net              *xprt_net;
index efe5495ecf6501b6ab84c84930757765fe48b291..739df8a113824e42ee7040908efa3a042a24688d 100644 (file)
@@ -885,7 +885,7 @@ void xprt_transmit(struct rpc_task *task)
 {
        struct rpc_rqst *req = task->tk_rqstp;
        struct rpc_xprt *xprt = req->rq_xprt;
-       int status;
+       int status, numreqs;
 
        dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen);
 
@@ -922,9 +922,14 @@ void xprt_transmit(struct rpc_task *task)
 
        xprt->ops->set_retrans_timeout(task);
 
+       numreqs = atomic_read(&xprt->num_reqs);
+       if (numreqs > xprt->stat.max_slots)
+               xprt->stat.max_slots = numreqs;
        xprt->stat.sends++;
        xprt->stat.req_u += xprt->stat.sends - xprt->stat.recvs;
        xprt->stat.bklog_u += xprt->backlog.qlen;
+       xprt->stat.sending_u += xprt->sending.qlen;
+       xprt->stat.pending_u += xprt->pending.qlen;
 
        /* Don't race with disconnect */
        if (!xprt_connected(xprt))
index 55472c48825e6fd43c3357a2f58b398231a2767e..4c8281d29e2bd3d45a168a37b0200459636bc914 100644 (file)
@@ -2227,7 +2227,7 @@ static void xs_local_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
                idle_time = (long)(jiffies - xprt->last_used) / HZ;
 
        seq_printf(seq, "\txprt:\tlocal %lu %lu %lu %ld %lu %lu %lu "
-                       "%llu %llu\n",
+                       "%llu %llu %lu %llu %llu\n",
                        xprt->stat.bind_count,
                        xprt->stat.connect_count,
                        xprt->stat.connect_time,
@@ -2236,7 +2236,10 @@ static void xs_local_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
                        xprt->stat.recvs,
                        xprt->stat.bad_xids,
                        xprt->stat.req_u,
-                       xprt->stat.bklog_u);
+                       xprt->stat.bklog_u,
+                       xprt->stat.max_slots,
+                       xprt->stat.sending_u,
+                       xprt->stat.pending_u);
 }
 
 /**
@@ -2249,14 +2252,18 @@ static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
 {
        struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
 
-       seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n",
+       seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %llu %llu "
+                       "%lu %llu %llu\n",
                        transport->srcport,
                        xprt->stat.bind_count,
                        xprt->stat.sends,
                        xprt->stat.recvs,
                        xprt->stat.bad_xids,
                        xprt->stat.req_u,
-                       xprt->stat.bklog_u);
+                       xprt->stat.bklog_u,
+                       xprt->stat.max_slots,
+                       xprt->stat.sending_u,
+                       xprt->stat.pending_u);
 }
 
 /**
@@ -2273,7 +2280,8 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
        if (xprt_connected(xprt))
                idle_time = (long)(jiffies - xprt->last_used) / HZ;
 
-       seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n",
+       seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu "
+                       "%llu %llu %lu %llu %llu\n",
                        transport->srcport,
                        xprt->stat.bind_count,
                        xprt->stat.connect_count,
@@ -2283,7 +2291,10 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
                        xprt->stat.recvs,
                        xprt->stat.bad_xids,
                        xprt->stat.req_u,
-                       xprt->stat.bklog_u);
+                       xprt->stat.bklog_u,
+                       xprt->stat.max_slots,
+                       xprt->stat.sending_u,
+                       xprt->stat.pending_u);
 }
 
 /*