Преглед изворни кода

SUNRPC: introduce per-task RPC iostats

Account for various things that occur while an RPC task is executed.
Separate timers for RPC round trip and RPC execution time show how
long RPC requests wait in queue before being sent.  Eventually these
will be accumulated at xprt_release time in one place where they can
be viewed from userland.

Test plan:
Compile kernel with CONFIG_NFS enabled.

Signed-off-by: Chuck Lever <cel@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Chuck Lever пре 19 година
родитељ
комит
ef759a2e54
5 измењених фајлова са 14 додато и 0 уклоњено
  1. 6 0
      include/linux/sunrpc/sched.h
  2. 2 0
      net/sunrpc/clnt.c
  3. 3 0
      net/sunrpc/sched.c
  4. 2 0
      net/sunrpc/xprt.c
  5. 1 0
      net/sunrpc/xprtsock.c

+ 6 - 0
include/linux/sunrpc/sched.h

@@ -86,6 +86,12 @@ struct rpc_task {
 		struct work_struct	tk_work;	/* Async task work queue */
 		struct work_struct	tk_work;	/* Async task work queue */
 		struct rpc_wait		tk_wait;	/* RPC wait */
 		struct rpc_wait		tk_wait;	/* RPC wait */
 	} u;
 	} u;
+
+	unsigned short		tk_timeouts;	/* maj timeouts */
+	size_t			tk_bytes_sent;	/* total bytes sent */
+	unsigned long		tk_start;	/* RPC task init timestamp */
+	long			tk_rtt;		/* round-trip time (jiffies) */
+
 #ifdef RPC_DEBUG
 #ifdef RPC_DEBUG
 	unsigned short		tk_pid;		/* debugging aid */
 	unsigned short		tk_pid;		/* debugging aid */
 #endif
 #endif

+ 2 - 0
net/sunrpc/clnt.c

@@ -996,6 +996,8 @@ call_timeout(struct rpc_task *task)
 	}
 	}
 
 
 	dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid);
 	dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid);
+	task->tk_timeouts++;
+
 	if (RPC_IS_SOFT(task)) {
 	if (RPC_IS_SOFT(task)) {
 		printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
 		printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
 				clnt->cl_protname, clnt->cl_server);
 				clnt->cl_protname, clnt->cl_server);

+ 3 - 0
net/sunrpc/sched.c

@@ -817,6 +817,9 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons
 
 
 	BUG_ON(task->tk_ops == NULL);
 	BUG_ON(task->tk_ops == NULL);
 
 
+	/* starting timestamp */
+	task->tk_start = jiffies;
+
 	dprintk("RPC: %4d new task procpid %d\n", task->tk_pid,
 	dprintk("RPC: %4d new task procpid %d\n", task->tk_pid,
 				current->pid);
 				current->pid);
 }
 }

+ 2 - 0
net/sunrpc/xprt.c

@@ -648,6 +648,8 @@ void xprt_complete_rqst(struct rpc_task *task, int copied)
 			task->tk_pid, ntohl(req->rq_xid), copied);
 			task->tk_pid, ntohl(req->rq_xid), copied);
 
 
 	task->tk_xprt->stat.recvs++;
 	task->tk_xprt->stat.recvs++;
+	task->tk_rtt = (long)jiffies - req->rq_xtime;
+
 	list_del_init(&req->rq_list);
 	list_del_init(&req->rq_list);
 	req->rq_received = req->rq_private_buf.len = copied;
 	req->rq_received = req->rq_private_buf.len = copied;
 	rpc_wake_up_task(task);
 	rpc_wake_up_task(task);

+ 1 - 0
net/sunrpc/xprtsock.c

@@ -382,6 +382,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
 		/* If we've sent the entire packet, immediately
 		/* If we've sent the entire packet, immediately
 		 * reset the count of bytes sent. */
 		 * reset the count of bytes sent. */
 		req->rq_bytes_sent += status;
 		req->rq_bytes_sent += status;
+		task->tk_bytes_sent += status;
 		if (likely(req->rq_bytes_sent >= req->rq_slen)) {
 		if (likely(req->rq_bytes_sent >= req->rq_slen)) {
 			req->rq_bytes_sent = 0;
 			req->rq_bytes_sent = 0;
 			return 0;
 			return 0;