aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2018-03-27 10:51:39 -0400
committerJ. Bruce Fields <bfields@redhat.com>2018-04-03 15:08:12 -0400
commitaaba72cd4e793fbf1c04e06dee3d2c3710339678 (patch)
tree07c10dd49ba18ca0cee58d1a96d27505d53f1378
parent0b9547bf6b94317b3f8e2496dc2b44cb6e599b01 (diff)
sunrpc: Report per-RPC execution stats
Introduce a mechanism to report the server-side execution latency of each RPC. The goal is to enable user space to filter the trace record for latency outliers, build histograms, etc. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--include/linux/sunrpc/svc.h1
-rw-r--r--include/trace/events/sunrpc.h21
-rw-r--r--net/sunrpc/svc_xprt.c3
3 files changed, 24 insertions, 1 deletions
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 786ae2255f05..3bd7504066e1 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -283,6 +283,7 @@ struct svc_rqst {
283 int rq_reserved; /* space on socket outq 283 int rq_reserved; /* space on socket outq
284 * reserved for this request 284 * reserved for this request
285 */ 285 */
286 ktime_t rq_stime; /* start time */
286 287
287 struct cache_req rq_chandle; /* handle passed to caches for 288 struct cache_req rq_chandle; /* handle passed to caches for
288 * request delaying 289 * request delaying
diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
index 5a8157c04900..1b383f71ccd7 100644
--- a/include/trace/events/sunrpc.h
+++ b/include/trace/events/sunrpc.h
@@ -705,6 +705,27 @@ TRACE_EVENT(svc_handle_xprt,
705 __entry->len, show_svc_xprt_flags(__entry->flags)) 705 __entry->len, show_svc_xprt_flags(__entry->flags))
706); 706);
707 707
708TRACE_EVENT(svc_stats_latency,
709 TP_PROTO(const struct svc_rqst *rqst),
710
711 TP_ARGS(rqst),
712
713 TP_STRUCT__entry(
714 __field(u32, xid)
715 __field(unsigned long, execute)
716 __string(addr, rqst->rq_xprt->xpt_remotebuf)
717 ),
718
719 TP_fast_assign(
720 __entry->xid = be32_to_cpu(rqst->rq_xid);
721 __entry->execute = ktime_to_us(ktime_sub(ktime_get(),
722 rqst->rq_stime));
723 __assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
724 ),
725
726 TP_printk("addr=%s xid=0x%08x execute-us=%lu",
727 __get_str(addr), __entry->xid, __entry->execute)
728);
708 729
709DECLARE_EVENT_CLASS(svc_deferred_event, 730DECLARE_EVENT_CLASS(svc_deferred_event,
710 TP_PROTO(struct svc_deferred_req *dr), 731 TP_PROTO(struct svc_deferred_req *dr),
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index f745754a55ea..a7425da14f5b 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -782,7 +782,7 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt)
782 len = svc_deferred_recv(rqstp); 782 len = svc_deferred_recv(rqstp);
783 else 783 else
784 len = xprt->xpt_ops->xpo_recvfrom(rqstp); 784 len = xprt->xpt_ops->xpo_recvfrom(rqstp);
785 dprintk("svc: got len=%d\n", len); 785 rqstp->rq_stime = ktime_get();
786 rqstp->rq_reserved = serv->sv_max_mesg; 786 rqstp->rq_reserved = serv->sv_max_mesg;
787 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); 787 atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
788 } 788 }
@@ -888,6 +888,7 @@ int svc_send(struct svc_rqst *rqstp)
888 888
889 /* Grab mutex to serialize outgoing data. */ 889 /* Grab mutex to serialize outgoing data. */
890 mutex_lock(&xprt->xpt_mutex); 890 mutex_lock(&xprt->xpt_mutex);
891 trace_svc_stats_latency(rqstp);
891 if (test_bit(XPT_DEAD, &xprt->xpt_flags) 892 if (test_bit(XPT_DEAD, &xprt->xpt_flags)
892 || test_bit(XPT_CLOSE, &xprt->xpt_flags)) 893 || test_bit(XPT_CLOSE, &xprt->xpt_flags))
893 len = -ENOTCONN; 894 len = -ENOTCONN;