Merge tag 'nfs-for-5.8-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Jun 2020 19:22:41 +0000 (12:22 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Jun 2020 19:22:41 +0000 (12:22 -0700)
Pull NFS client updates from Anna Schumaker:
 "New features and improvements:
   - Sunrpc receive buffer sizes only change when establishing a GSS credentials
   - Add more sunrpc tracepoints
   - Improve on tracepoints to capture internal NFS I/O errors

  Other bugfixes and cleanups:
   - Move a dprintk() to after a call to nfs_alloc_fattr()
   - Fix off-by-one issues in rpc_ntop6
   - Fix a few coccicheck warnings
   - Use the correct SPDX license identifiers
   - Fix rpc_call_done assignment for BIND_CONN_TO_SESSION
   - Replace zero-length array with flexible array
   - Remove duplicate headers
   - Set invalid blocks after NFSv4 writes to update space_used attribute
   - Fix direct WRITE throughput regression"

* tag 'nfs-for-5.8-1' of git://git.linux-nfs.org/projects/anna/linux-nfs: (27 commits)
  NFS: Fix direct WRITE throughput regression
  SUNRPC: rpc_xprt lifetime events should record xprt->state
  xprtrdma: Make xprt_rdma_slot_table_entries static
  nfs: set invalid blocks after NFSv4 writes
  NFS: remove redundant initialization of variable result
  sunrpc: add missing newline when printing parameter 'auth_hashtable_size' by sysfs
  NFS: Add a tracepoint in nfs_set_pgio_error()
  NFS: Trace short NFS READs
  NFS: nfs_xdr_status should record the procedure name
  SUNRPC: Set SOFTCONN when destroying GSS contexts
  SUNRPC: rpc_call_null_helper() should set RPC_TASK_SOFT
  SUNRPC: rpc_call_null_helper() already sets RPC_TASK_NULLCREDS
  SUNRPC: trace RPC client lifetime events
  SUNRPC: Trace transport lifetime events
  SUNRPC: Split the xdr_buf event class
  SUNRPC: Add tracepoint to rpc_call_rpcerror()
  SUNRPC: Update the RPC_SHOW_SOCKET() macro
  SUNRPC: Update the rpc_show_task_flags() macro
  SUNRPC: Trace GSS context lifetimes
  SUNRPC: receive buffer size estimation values almost never change
  ...

1  2 
include/trace/events/rpcrdma.h
include/trace/events/sunrpc.h
net/sunrpc/svc_xprt.c

@@@ -380,12 -380,8 +380,8 @@@ TRACE_EVENT(xprtrdma_inline_thresh
  
  DEFINE_CONN_EVENT(connect);
  DEFINE_CONN_EVENT(disconnect);
- DEFINE_CONN_EVENT(flush_dct);
  
- DEFINE_RXPRT_EVENT(xprtrdma_create);
- DEFINE_RXPRT_EVENT(xprtrdma_op_destroy);
  DEFINE_RXPRT_EVENT(xprtrdma_op_inject_dsc);
- DEFINE_RXPRT_EVENT(xprtrdma_op_close);
  DEFINE_RXPRT_EVENT(xprtrdma_op_setport);
  
  TRACE_EVENT(xprtrdma_op_connect,
@@@ -1279,42 -1275,38 +1275,42 @@@ TRACE_EVENT(xprtrdma_leaked_rep
   ** Server-side RPC/RDMA events
   **/
  
 -DECLARE_EVENT_CLASS(svcrdma_xprt_event,
 +DECLARE_EVENT_CLASS(svcrdma_accept_class,
        TP_PROTO(
 -              const struct svc_xprt *xprt
 +              const struct svcxprt_rdma *rdma,
 +              long status
        ),
  
 -      TP_ARGS(xprt),
 +      TP_ARGS(rdma, status),
  
        TP_STRUCT__entry(
 -              __field(const void *, xprt)
 -              __string(addr, xprt->xpt_remotebuf)
 +              __field(long, status)
 +              __string(addr, rdma->sc_xprt.xpt_remotebuf)
        ),
  
        TP_fast_assign(
 -              __entry->xprt = xprt;
 -              __assign_str(addr, xprt->xpt_remotebuf);
 +              __entry->status = status;
 +              __assign_str(addr, rdma->sc_xprt.xpt_remotebuf);
        ),
  
 -      TP_printk("xprt=%p addr=%s",
 -              __entry->xprt, __get_str(addr)
 +      TP_printk("addr=%s status=%ld",
 +              __get_str(addr), __entry->status
        )
  );
  
 -#define DEFINE_XPRT_EVENT(name)                                               \
 -              DEFINE_EVENT(svcrdma_xprt_event, svcrdma_xprt_##name,   \
 -                              TP_PROTO(                               \
 -                                      const struct svc_xprt *xprt     \
 -                              ),                                      \
 -                              TP_ARGS(xprt))
 +#define DEFINE_ACCEPT_EVENT(name) \
 +              DEFINE_EVENT(svcrdma_accept_class, svcrdma_##name##_err, \
 +                              TP_PROTO( \
 +                                      const struct svcxprt_rdma *rdma, \
 +                                      long status \
 +                              ), \
 +                              TP_ARGS(rdma, status))
  
 -DEFINE_XPRT_EVENT(accept);
 -DEFINE_XPRT_EVENT(fail);
 -DEFINE_XPRT_EVENT(free);
 +DEFINE_ACCEPT_EVENT(pd);
 +DEFINE_ACCEPT_EVENT(qp);
 +DEFINE_ACCEPT_EVENT(fabric);
 +DEFINE_ACCEPT_EVENT(initdepth);
 +DEFINE_ACCEPT_EVENT(accept);
  
  TRACE_DEFINE_ENUM(RDMA_MSG);
  TRACE_DEFINE_ENUM(RDMA_NOMSG);
@@@ -1359,7 -1351,7 +1355,7 @@@ TRACE_EVENT(svcrdma_decode_rqst
                show_rpcrdma_proc(__entry->proc), __entry->hdrlen)
  );
  
 -TRACE_EVENT(svcrdma_decode_short,
 +TRACE_EVENT(svcrdma_decode_short_err,
        TP_PROTO(
                unsigned int hdrlen
        ),
@@@ -1403,8 -1395,7 +1399,8 @@@ DECLARE_EVENT_CLASS(svcrdma_badreq_even
  );
  
  #define DEFINE_BADREQ_EVENT(name)                                     \
 -              DEFINE_EVENT(svcrdma_badreq_event, svcrdma_decode_##name,\
 +              DEFINE_EVENT(svcrdma_badreq_event,                      \
 +                           svcrdma_decode_##name##_err,               \
                                TP_PROTO(                               \
                                        __be32 *p                       \
                                ),                                      \
@@@ -1588,117 -1579,28 +1584,117 @@@ DECLARE_EVENT_CLASS(svcrdma_dma_map_cla
  DEFINE_SVC_DMA_EVENT(dma_map_page);
  DEFINE_SVC_DMA_EVENT(dma_unmap_page);
  
 -TRACE_EVENT(svcrdma_dma_map_rwctx,
 +TRACE_EVENT(svcrdma_dma_map_rw_err,
        TP_PROTO(
                const struct svcxprt_rdma *rdma,
 +              unsigned int nents,
                int status
        ),
  
 -      TP_ARGS(rdma, status),
 +      TP_ARGS(rdma, nents, status),
  
        TP_STRUCT__entry(
                __field(int, status)
 +              __field(unsigned int, nents)
                __string(device, rdma->sc_cm_id->device->name)
                __string(addr, rdma->sc_xprt.xpt_remotebuf)
        ),
  
        TP_fast_assign(
                __entry->status = status;
 +              __entry->nents = nents;
 +              __assign_str(device, rdma->sc_cm_id->device->name);
 +              __assign_str(addr, rdma->sc_xprt.xpt_remotebuf);
 +      ),
 +
 +      TP_printk("addr=%s device=%s nents=%u status=%d",
 +              __get_str(addr), __get_str(device), __entry->nents,
 +              __entry->status
 +      )
 +);
 +
 +TRACE_EVENT(svcrdma_no_rwctx_err,
 +      TP_PROTO(
 +              const struct svcxprt_rdma *rdma,
 +              unsigned int num_sges
 +      ),
 +
 +      TP_ARGS(rdma, num_sges),
 +
 +      TP_STRUCT__entry(
 +              __field(unsigned int, num_sges)
 +              __string(device, rdma->sc_cm_id->device->name)
 +              __string(addr, rdma->sc_xprt.xpt_remotebuf)
 +      ),
 +
 +      TP_fast_assign(
 +              __entry->num_sges = num_sges;
 +              __assign_str(device, rdma->sc_cm_id->device->name);
 +              __assign_str(addr, rdma->sc_xprt.xpt_remotebuf);
 +      ),
 +
 +      TP_printk("addr=%s device=%s num_sges=%d",
 +              __get_str(addr), __get_str(device), __entry->num_sges
 +      )
 +);
 +
 +TRACE_EVENT(svcrdma_page_overrun_err,
 +      TP_PROTO(
 +              const struct svcxprt_rdma *rdma,
 +              const struct svc_rqst *rqst,
 +              unsigned int pageno
 +      ),
 +
 +      TP_ARGS(rdma, rqst, pageno),
 +
 +      TP_STRUCT__entry(
 +              __field(unsigned int, pageno)
 +              __field(u32, xid)
 +              __string(device, rdma->sc_cm_id->device->name)
 +              __string(addr, rdma->sc_xprt.xpt_remotebuf)
 +      ),
 +
 +      TP_fast_assign(
 +              __entry->pageno = pageno;
 +              __entry->xid = __be32_to_cpu(rqst->rq_xid);
 +              __assign_str(device, rdma->sc_cm_id->device->name);
 +              __assign_str(addr, rdma->sc_xprt.xpt_remotebuf);
 +      ),
 +
 +      TP_printk("addr=%s device=%s xid=0x%08x pageno=%u", __get_str(addr),
 +              __get_str(device), __entry->xid, __entry->pageno
 +      )
 +);
 +
 +TRACE_EVENT(svcrdma_small_wrch_err,
 +      TP_PROTO(
 +              const struct svcxprt_rdma *rdma,
 +              unsigned int remaining,
 +              unsigned int seg_no,
 +              unsigned int num_segs
 +      ),
 +
 +      TP_ARGS(rdma, remaining, seg_no, num_segs),
 +
 +      TP_STRUCT__entry(
 +              __field(unsigned int, remaining)
 +              __field(unsigned int, seg_no)
 +              __field(unsigned int, num_segs)
 +              __string(device, rdma->sc_cm_id->device->name)
 +              __string(addr, rdma->sc_xprt.xpt_remotebuf)
 +      ),
 +
 +      TP_fast_assign(
 +              __entry->remaining = remaining;
 +              __entry->seg_no = seg_no;
 +              __entry->num_segs = num_segs;
                __assign_str(device, rdma->sc_cm_id->device->name);
                __assign_str(addr, rdma->sc_xprt.xpt_remotebuf);
        ),
  
 -      TP_printk("addr=%s device=%s status=%d",
 -              __get_str(addr), __get_str(device), __entry->status
 +      TP_printk("addr=%s device=%s remaining=%u seg_no=%u num_segs=%u",
 +              __get_str(addr), __get_str(device), __entry->remaining,
 +              __entry->seg_no, __entry->num_segs
        )
  );
  
  #include <linux/net.h>
  #include <linux/tracepoint.h>
  
- DECLARE_EVENT_CLASS(xdr_buf_class,
 +TRACE_DEFINE_ENUM(SOCK_STREAM);
 +TRACE_DEFINE_ENUM(SOCK_DGRAM);
 +TRACE_DEFINE_ENUM(SOCK_RAW);
 +TRACE_DEFINE_ENUM(SOCK_RDM);
 +TRACE_DEFINE_ENUM(SOCK_SEQPACKET);
 +TRACE_DEFINE_ENUM(SOCK_DCCP);
 +TRACE_DEFINE_ENUM(SOCK_PACKET);
 +
 +#define show_socket_type(type)                                        \
 +      __print_symbolic(type,                                  \
 +              { SOCK_STREAM,          "STREAM" },             \
 +              { SOCK_DGRAM,           "DGRAM" },              \
 +              { SOCK_RAW,             "RAW" },                \
 +              { SOCK_RDM,             "RDM" },                \
 +              { SOCK_SEQPACKET,       "SEQPACKET" },          \
 +              { SOCK_DCCP,            "DCCP" },               \
 +              { SOCK_PACKET,          "PACKET" })
 +
 +/* This list is known to be incomplete, add new enums as needed. */
 +TRACE_DEFINE_ENUM(AF_UNSPEC);
 +TRACE_DEFINE_ENUM(AF_UNIX);
 +TRACE_DEFINE_ENUM(AF_LOCAL);
 +TRACE_DEFINE_ENUM(AF_INET);
 +TRACE_DEFINE_ENUM(AF_INET6);
 +
 +#define rpc_show_address_family(family)                               \
 +      __print_symbolic(family,                                \
 +              { AF_UNSPEC,            "AF_UNSPEC" },          \
 +              { AF_UNIX,              "AF_UNIX" },            \
 +              { AF_LOCAL,             "AF_LOCAL" },           \
 +              { AF_INET,              "AF_INET" },            \
 +              { AF_INET6,             "AF_INET6" })
 +
+ DECLARE_EVENT_CLASS(rpc_xdr_buf_class,
        TP_PROTO(
+               const struct rpc_task *task,
                const struct xdr_buf *xdr
        ),
  
-       TP_ARGS(xdr),
+       TP_ARGS(task, xdr),
  
        TP_STRUCT__entry(
+               __field(unsigned int, task_id)
+               __field(unsigned int, client_id)
                __field(const void *, head_base)
                __field(size_t, head_len)
                __field(const void *, tail_base)
@@@ -64,6 -34,8 +67,8 @@@
        ),
  
        TP_fast_assign(
+               __entry->task_id = task->tk_pid;
+               __entry->client_id = task->tk_client->cl_clid;
                __entry->head_base = xdr->head[0].iov_base;
                __entry->head_len = xdr->head[0].iov_len;
                __entry->tail_base = xdr->tail[0].iov_base;
                __entry->msg_len = xdr->len;
        ),
  
-       TP_printk("head=[%p,%zu] page=%u tail=[%p,%zu] len=%u",
+       TP_printk("task:%u@%u head=[%p,%zu] page=%u tail=[%p,%zu] len=%u",
+               __entry->task_id, __entry->client_id,
                __entry->head_base, __entry->head_len, __entry->page_len,
                __entry->tail_base, __entry->tail_len, __entry->msg_len
        )
  );
  
- #define DEFINE_XDRBUF_EVENT(name)                                     \
-               DEFINE_EVENT(xdr_buf_class, name,                       \
+ #define DEFINE_RPCXDRBUF_EVENT(name)                                  \
+               DEFINE_EVENT(rpc_xdr_buf_class,                         \
+                               rpc_xdr_##name,                         \
                                TP_PROTO(                               \
+                                       const struct rpc_task *task,    \
                                        const struct xdr_buf *xdr       \
                                ),                                      \
-                               TP_ARGS(xdr))
+                               TP_ARGS(task, xdr))
+ DEFINE_RPCXDRBUF_EVENT(sendto);
+ DEFINE_RPCXDRBUF_EVENT(recvfrom);
+ DEFINE_RPCXDRBUF_EVENT(reply_pages);
+ DECLARE_EVENT_CLASS(rpc_clnt_class,
+       TP_PROTO(
+               const struct rpc_clnt *clnt
+       ),
+       TP_ARGS(clnt),
+       TP_STRUCT__entry(
+               __field(unsigned int, client_id)
+       ),
+       TP_fast_assign(
+               __entry->client_id = clnt->cl_clid;
+       ),
+       TP_printk("clid=%u", __entry->client_id)
+ );
+ #define DEFINE_RPC_CLNT_EVENT(name)                                   \
+               DEFINE_EVENT(rpc_clnt_class,                            \
+                               rpc_clnt_##name,                        \
+                               TP_PROTO(                               \
+                                       const struct rpc_clnt *clnt     \
+                               ),                                      \
+                               TP_ARGS(clnt))
+ DEFINE_RPC_CLNT_EVENT(free);
+ DEFINE_RPC_CLNT_EVENT(killall);
+ DEFINE_RPC_CLNT_EVENT(shutdown);
+ DEFINE_RPC_CLNT_EVENT(release);
+ DEFINE_RPC_CLNT_EVENT(replace_xprt);
+ DEFINE_RPC_CLNT_EVENT(replace_xprt_err);
+ TRACE_EVENT(rpc_clnt_new,
+       TP_PROTO(
+               const struct rpc_clnt *clnt,
+               const struct rpc_xprt *xprt,
+               const char *program,
+               const char *server
+       ),
+       TP_ARGS(clnt, xprt, program, server),
+       TP_STRUCT__entry(
+               __field(unsigned int, client_id)
+               __string(addr, xprt->address_strings[RPC_DISPLAY_ADDR])
+               __string(port, xprt->address_strings[RPC_DISPLAY_PORT])
+               __string(program, program)
+               __string(server, server)
+       ),
+       TP_fast_assign(
+               __entry->client_id = clnt->cl_clid;
+               __assign_str(addr, xprt->address_strings[RPC_DISPLAY_ADDR]);
+               __assign_str(port, xprt->address_strings[RPC_DISPLAY_PORT]);
+               __assign_str(program, program)
+               __assign_str(server, server)
+       ),
+       TP_printk("client=%u peer=[%s]:%s program=%s server=%s",
+               __entry->client_id, __get_str(addr), __get_str(port),
+               __get_str(program), __get_str(server))
+ );
+ TRACE_EVENT(rpc_clnt_new_err,
+       TP_PROTO(
+               const char *program,
+               const char *server,
+               int error
+       ),
+       TP_ARGS(program, server, error),
+       TP_STRUCT__entry(
+               __field(int, error)
+               __string(program, program)
+               __string(server, server)
+       ),
+       TP_fast_assign(
+               __entry->error = error;
+               __assign_str(program, program)
+               __assign_str(server, server)
+       ),
+       TP_printk("program=%s server=%s error=%d",
+               __get_str(program), __get_str(server), __entry->error)
+ );
+ TRACE_EVENT(rpc_clnt_clone_err,
+       TP_PROTO(
+               const struct rpc_clnt *clnt,
+               int error
+       ),
+       TP_ARGS(clnt, error),
+       TP_STRUCT__entry(
+               __field(unsigned int, client_id)
+               __field(int, error)
+       ),
+       TP_fast_assign(
+               __entry->client_id = clnt->cl_clid;
+               __entry->error = error;
+       ),
+       TP_printk("client=%u error=%d", __entry->client_id, __entry->error)
+ );
  
- DEFINE_XDRBUF_EVENT(xprt_sendto);
- DEFINE_XDRBUF_EVENT(xprt_recvfrom);
- DEFINE_XDRBUF_EVENT(svc_recvfrom);
- DEFINE_XDRBUF_EVENT(svc_sendto);
  
  TRACE_DEFINE_ENUM(RPC_AUTH_OK);
  TRACE_DEFINE_ENUM(RPC_AUTH_BADCRED);
@@@ -175,29 -261,35 +294,35 @@@ TRACE_EVENT(rpc_request
  
  TRACE_DEFINE_ENUM(RPC_TASK_ASYNC);
  TRACE_DEFINE_ENUM(RPC_TASK_SWAPPER);
+ TRACE_DEFINE_ENUM(RPC_TASK_NULLCREDS);
  TRACE_DEFINE_ENUM(RPC_CALL_MAJORSEEN);
  TRACE_DEFINE_ENUM(RPC_TASK_ROOTCREDS);
  TRACE_DEFINE_ENUM(RPC_TASK_DYNAMIC);
+ TRACE_DEFINE_ENUM(RPC_TASK_NO_ROUND_ROBIN);
  TRACE_DEFINE_ENUM(RPC_TASK_SOFT);
  TRACE_DEFINE_ENUM(RPC_TASK_SOFTCONN);
  TRACE_DEFINE_ENUM(RPC_TASK_SENT);
  TRACE_DEFINE_ENUM(RPC_TASK_TIMEOUT);
  TRACE_DEFINE_ENUM(RPC_TASK_NOCONNECT);
  TRACE_DEFINE_ENUM(RPC_TASK_NO_RETRANS_TIMEOUT);
+ TRACE_DEFINE_ENUM(RPC_TASK_CRED_NOREF);
  
  #define rpc_show_task_flags(flags)                                    \
        __print_flags(flags, "|",                                       \
                { RPC_TASK_ASYNC, "ASYNC" },                            \
                { RPC_TASK_SWAPPER, "SWAPPER" },                        \
+               { RPC_TASK_NULLCREDS, "NULLCREDS" },                    \
                { RPC_CALL_MAJORSEEN, "MAJORSEEN" },                    \
                { RPC_TASK_ROOTCREDS, "ROOTCREDS" },                    \
                { RPC_TASK_DYNAMIC, "DYNAMIC" },                        \
+               { RPC_TASK_NO_ROUND_ROBIN, "NO_ROUND_ROBIN" },          \
                { RPC_TASK_SOFT, "SOFT" },                              \
                { RPC_TASK_SOFTCONN, "SOFTCONN" },                      \
                { RPC_TASK_SENT, "SENT" },                              \
                { RPC_TASK_TIMEOUT, "TIMEOUT" },                        \
                { RPC_TASK_NOCONNECT, "NOCONNECT" },                    \
-               { RPC_TASK_NO_RETRANS_TIMEOUT, "NORTO" })
+               { RPC_TASK_NO_RETRANS_TIMEOUT, "NORTO" },               \
+               { RPC_TASK_CRED_NOREF, "CRED_NOREF" })
  
  TRACE_DEFINE_ENUM(RPC_TASK_RUNNING);
  TRACE_DEFINE_ENUM(RPC_TASK_QUEUED);
@@@ -392,6 -484,34 +517,34 @@@ DEFINE_RPC_REPLY_EVENT(stale_creds)
  DEFINE_RPC_REPLY_EVENT(bad_creds);
  DEFINE_RPC_REPLY_EVENT(auth_tooweak);
  
+ TRACE_EVENT(rpc_call_rpcerror,
+       TP_PROTO(
+               const struct rpc_task *task,
+               int tk_status,
+               int rpc_status
+       ),
+       TP_ARGS(task, tk_status, rpc_status),
+       TP_STRUCT__entry(
+               __field(unsigned int, task_id)
+               __field(unsigned int, client_id)
+               __field(int, tk_status)
+               __field(int, rpc_status)
+       ),
+       TP_fast_assign(
+               __entry->client_id = task->tk_client->cl_clid;
+               __entry->task_id = task->tk_pid;
+               __entry->tk_status = tk_status;
+               __entry->rpc_status = rpc_status;
+       ),
+       TP_printk("task:%u@%u tk_status=%d rpc_status=%d",
+               __entry->task_id, __entry->client_id,
+               __entry->tk_status, __entry->rpc_status)
+ );
  TRACE_EVENT(rpc_stats_latency,
  
        TP_PROTO(
@@@ -559,43 -679,6 +712,6 @@@ TRACE_EVENT(rpc_xdr_alignment
        )
  );
  
- TRACE_EVENT(rpc_reply_pages,
-       TP_PROTO(
-               const struct rpc_rqst *req
-       ),
-       TP_ARGS(req),
-       TP_STRUCT__entry(
-               __field(unsigned int, task_id)
-               __field(unsigned int, client_id)
-               __field(const void *, head_base)
-               __field(size_t, head_len)
-               __field(const void *, tail_base)
-               __field(size_t, tail_len)
-               __field(unsigned int, page_len)
-       ),
-       TP_fast_assign(
-               __entry->task_id = req->rq_task->tk_pid;
-               __entry->client_id = req->rq_task->tk_client->cl_clid;
-               __entry->head_base = req->rq_rcv_buf.head[0].iov_base;
-               __entry->head_len = req->rq_rcv_buf.head[0].iov_len;
-               __entry->page_len = req->rq_rcv_buf.page_len;
-               __entry->tail_base = req->rq_rcv_buf.tail[0].iov_base;
-               __entry->tail_len = req->rq_rcv_buf.tail[0].iov_len;
-       ),
-       TP_printk(
-               "task:%u@%u xdr=[%p,%zu]/%u/[%p,%zu]\n",
-               __entry->task_id, __entry->client_id,
-               __entry->head_base, __entry->head_len,
-               __entry->page_len,
-               __entry->tail_base, __entry->tail_len
-       )
- );
  /*
   * First define the enums in the below macros to be exported to userspace
   * via TRACE_DEFINE_ENUM().
  #define RPC_SHOW_SOCKET                               \
        EM( SS_FREE, "FREE" )                   \
        EM( SS_UNCONNECTED, "UNCONNECTED" )     \
-       EM( SS_CONNECTING, "CONNECTING," )      \
-       EM( SS_CONNECTED, "CONNECTED," )        \
-       EMe(SS_DISCONNECTING, "DISCONNECTING" )
+       EM( SS_CONNECTING, "CONNECTING" )       \
+       EM( SS_CONNECTED, "CONNECTED" )         \
+       EMe( SS_DISCONNECTING, "DISCONNECTING" )
  
  #define rpc_show_socket_state(state) \
        __print_symbolic(state, RPC_SHOW_SOCKET)
@@@ -752,6 -835,69 +868,69 @@@ DEFINE_RPC_SOCKET_EVENT_DONE(rpc_socket
  DEFINE_RPC_SOCKET_EVENT(rpc_socket_close);
  DEFINE_RPC_SOCKET_EVENT(rpc_socket_shutdown);
  
+ TRACE_DEFINE_ENUM(XPRT_LOCKED);
+ TRACE_DEFINE_ENUM(XPRT_CONNECTED);
+ TRACE_DEFINE_ENUM(XPRT_CONNECTING);
+ TRACE_DEFINE_ENUM(XPRT_CLOSE_WAIT);
+ TRACE_DEFINE_ENUM(XPRT_BOUND);
+ TRACE_DEFINE_ENUM(XPRT_BINDING);
+ TRACE_DEFINE_ENUM(XPRT_CLOSING);
+ TRACE_DEFINE_ENUM(XPRT_CONGESTED);
+ TRACE_DEFINE_ENUM(XPRT_CWND_WAIT);
+ TRACE_DEFINE_ENUM(XPRT_WRITE_SPACE);
+ #define rpc_show_xprt_state(x)                                                \
+       __print_flags(x, "|",                                           \
+               { (1UL << XPRT_LOCKED),         "LOCKED"},              \
+               { (1UL << XPRT_CONNECTED),      "CONNECTED"},           \
+               { (1UL << XPRT_CONNECTING),     "CONNECTING"},          \
+               { (1UL << XPRT_CLOSE_WAIT),     "CLOSE_WAIT"},          \
+               { (1UL << XPRT_BOUND),          "BOUND"},               \
+               { (1UL << XPRT_BINDING),        "BINDING"},             \
+               { (1UL << XPRT_CLOSING),        "CLOSING"},             \
+               { (1UL << XPRT_CONGESTED),      "CONGESTED"},           \
+               { (1UL << XPRT_CWND_WAIT),      "CWND_WAIT"},           \
+               { (1UL << XPRT_WRITE_SPACE),    "WRITE_SPACE"})
+ DECLARE_EVENT_CLASS(rpc_xprt_lifetime_class,
+       TP_PROTO(
+               const struct rpc_xprt *xprt
+       ),
+       TP_ARGS(xprt),
+       TP_STRUCT__entry(
+               __field(unsigned long, state)
+               __string(addr, xprt->address_strings[RPC_DISPLAY_ADDR])
+               __string(port, xprt->address_strings[RPC_DISPLAY_PORT])
+       ),
+       TP_fast_assign(
+               __entry->state = xprt->state;
+               __assign_str(addr, xprt->address_strings[RPC_DISPLAY_ADDR]);
+               __assign_str(port, xprt->address_strings[RPC_DISPLAY_PORT]);
+       ),
+       TP_printk("peer=[%s]:%s state=%s",
+               __get_str(addr), __get_str(port),
+               rpc_show_xprt_state(__entry->state))
+ );
+ #define DEFINE_RPC_XPRT_LIFETIME_EVENT(name) \
+       DEFINE_EVENT(rpc_xprt_lifetime_class, \
+                       xprt_##name, \
+                       TP_PROTO( \
+                               const struct rpc_xprt *xprt \
+                       ), \
+                       TP_ARGS(xprt))
+ DEFINE_RPC_XPRT_LIFETIME_EVENT(create);
+ DEFINE_RPC_XPRT_LIFETIME_EVENT(disconnect_auto);
+ DEFINE_RPC_XPRT_LIFETIME_EVENT(disconnect_done);
+ DEFINE_RPC_XPRT_LIFETIME_EVENT(disconnect_force);
+ DEFINE_RPC_XPRT_LIFETIME_EVENT(disconnect_cleanup);
+ DEFINE_RPC_XPRT_LIFETIME_EVENT(destroy);
  DECLARE_EVENT_CLASS(rpc_xprt_event,
        TP_PROTO(
                const struct rpc_xprt *xprt,
@@@ -1023,6 -1169,54 +1202,54 @@@ TRACE_EVENT(xs_stream_read_request
                        __entry->copied, __entry->reclen, __entry->offset)
  );
  
+ DECLARE_EVENT_CLASS(svc_xdr_buf_class,
+       TP_PROTO(
+               const struct svc_rqst *rqst,
+               const struct xdr_buf *xdr
+       ),
+       TP_ARGS(rqst, xdr),
+       TP_STRUCT__entry(
+               __field(u32, xid)
+               __field(const void *, head_base)
+               __field(size_t, head_len)
+               __field(const void *, tail_base)
+               __field(size_t, tail_len)
+               __field(unsigned int, page_len)
+               __field(unsigned int, msg_len)
+       ),
+       TP_fast_assign(
+               __entry->xid = be32_to_cpu(rqst->rq_xid);
+               __entry->head_base = xdr->head[0].iov_base;
+               __entry->head_len = xdr->head[0].iov_len;
+               __entry->tail_base = xdr->tail[0].iov_base;
+               __entry->tail_len = xdr->tail[0].iov_len;
+               __entry->page_len = xdr->page_len;
+               __entry->msg_len = xdr->len;
+       ),
+       TP_printk("xid=0x%08x head=[%p,%zu] page=%u tail=[%p,%zu] len=%u",
+               __entry->xid,
+               __entry->head_base, __entry->head_len, __entry->page_len,
+               __entry->tail_base, __entry->tail_len, __entry->msg_len
+       )
+ );
+ #define DEFINE_SVCXDRBUF_EVENT(name)                                  \
+               DEFINE_EVENT(svc_xdr_buf_class,                         \
+                               svc_xdr_##name,                         \
+                               TP_PROTO(                               \
+                                       const struct svc_rqst *rqst,    \
+                                       const struct xdr_buf *xdr       \
+                               ),                                      \
+                               TP_ARGS(rqst, xdr))
+ DEFINE_SVCXDRBUF_EVENT(recvfrom);
+ DEFINE_SVCXDRBUF_EVENT(sendto);
  #define show_rqstp_flags(flags)                                               \
        __print_flags(flags, "|",                                       \
                { (1UL << RQ_SECURE),           "RQ_SECURE"},           \
@@@ -1057,17 -1251,6 +1284,17 @@@ TRACE_EVENT(svc_recv
                        show_rqstp_flags(__entry->flags))
  );
  
 +TRACE_DEFINE_ENUM(SVC_GARBAGE);
 +TRACE_DEFINE_ENUM(SVC_SYSERR);
 +TRACE_DEFINE_ENUM(SVC_VALID);
 +TRACE_DEFINE_ENUM(SVC_NEGATIVE);
 +TRACE_DEFINE_ENUM(SVC_OK);
 +TRACE_DEFINE_ENUM(SVC_DROP);
 +TRACE_DEFINE_ENUM(SVC_CLOSE);
 +TRACE_DEFINE_ENUM(SVC_DENIED);
 +TRACE_DEFINE_ENUM(SVC_PENDING);
 +TRACE_DEFINE_ENUM(SVC_COMPLETE);
 +
  #define svc_show_status(status)                               \
        __print_symbolic(status,                        \
                { SVC_GARBAGE,  "SVC_GARBAGE" },        \
@@@ -1211,54 -1394,28 +1438,54 @@@ DEFINE_EVENT(svc_rqst_status, svc_send
                { (1UL << XPT_KILL_TEMP),       "XPT_KILL_TEMP"},       \
                { (1UL << XPT_CONG_CTRL),       "XPT_CONG_CTRL"})
  
 +TRACE_EVENT(svc_xprt_create_err,
 +      TP_PROTO(
 +              const char *program,
 +              const char *protocol,
 +              struct sockaddr *sap,
 +              const struct svc_xprt *xprt
 +      ),
 +
 +      TP_ARGS(program, protocol, sap, xprt),
 +
 +      TP_STRUCT__entry(
 +              __field(long, error)
 +              __string(program, program)
 +              __string(protocol, protocol)
 +              __array(unsigned char, addr, sizeof(struct sockaddr_in6))
 +      ),
 +
 +      TP_fast_assign(
 +              __entry->error = PTR_ERR(xprt);
 +              __assign_str(program, program);
 +              __assign_str(protocol, protocol);
 +              memcpy(__entry->addr, sap, sizeof(__entry->addr));
 +      ),
 +
 +      TP_printk("addr=%pISpc program=%s protocol=%s error=%ld",
 +              __entry->addr, __get_str(program), __get_str(protocol),
 +              __entry->error)
 +);
 +
  TRACE_EVENT(svc_xprt_do_enqueue,
        TP_PROTO(struct svc_xprt *xprt, struct svc_rqst *rqst),
  
        TP_ARGS(xprt, rqst),
  
        TP_STRUCT__entry(
 -              __field(struct svc_xprt *, xprt)
                __field(int, pid)
                __field(unsigned long, flags)
                __string(addr, xprt->xpt_remotebuf)
        ),
  
        TP_fast_assign(
 -              __entry->xprt = xprt;
                __entry->pid = rqst? rqst->rq_task->pid : 0;
                __entry->flags = xprt->xpt_flags;
                __assign_str(addr, xprt->xpt_remotebuf);
        ),
  
 -      TP_printk("xprt=%p addr=%s pid=%d flags=%s",
 -                      __entry->xprt, __get_str(addr),
 -                      __entry->pid, show_svc_xprt_flags(__entry->flags))
 +      TP_printk("addr=%s pid=%d flags=%s", __get_str(addr),
 +              __entry->pid, show_svc_xprt_flags(__entry->flags))
  );
  
  DECLARE_EVENT_CLASS(svc_xprt_event,
        TP_ARGS(xprt),
  
        TP_STRUCT__entry(
 -              __field(struct svc_xprt *, xprt)
                __field(unsigned long, flags)
                __string(addr, xprt->xpt_remotebuf)
        ),
  
        TP_fast_assign(
 -              __entry->xprt = xprt;
                __entry->flags = xprt->xpt_flags;
                __assign_str(addr, xprt->xpt_remotebuf);
        ),
  
 -      TP_printk("xprt=%p addr=%s flags=%s",
 -                      __entry->xprt, __get_str(addr),
 -                      show_svc_xprt_flags(__entry->flags))
 +      TP_printk("addr=%s flags=%s", __get_str(addr),
 +              show_svc_xprt_flags(__entry->flags))
  );
  
 -DEFINE_EVENT(svc_xprt_event, svc_xprt_no_write_space,
 -      TP_PROTO(struct svc_xprt *xprt),
 -      TP_ARGS(xprt));
 +#define DEFINE_SVC_XPRT_EVENT(name) \
 +      DEFINE_EVENT(svc_xprt_event, svc_xprt_##name, \
 +                      TP_PROTO( \
 +                              struct svc_xprt *xprt \
 +                      ), \
 +                      TP_ARGS(xprt))
 +
 +DEFINE_SVC_XPRT_EVENT(no_write_space);
 +DEFINE_SVC_XPRT_EVENT(close);
 +DEFINE_SVC_XPRT_EVENT(detach);
 +DEFINE_SVC_XPRT_EVENT(free);
 +
 +TRACE_EVENT(svc_xprt_accept,
 +      TP_PROTO(
 +              const struct svc_xprt *xprt,
 +              const char *service
 +      ),
 +
 +      TP_ARGS(xprt, service),
 +
 +      TP_STRUCT__entry(
 +              __string(addr, xprt->xpt_remotebuf)
 +              __string(protocol, xprt->xpt_class->xcl_name)
 +              __string(service, service)
 +      ),
 +
 +      TP_fast_assign(
 +              __assign_str(addr, xprt->xpt_remotebuf);
 +              __assign_str(protocol, xprt->xpt_class->xcl_name)
 +              __assign_str(service, service);
 +      ),
 +
 +      TP_printk("addr=%s protocol=%s service=%s",
 +              __get_str(addr), __get_str(protocol), __get_str(service)
 +      )
 +);
  
  TRACE_EVENT(svc_xprt_dequeue,
        TP_PROTO(struct svc_rqst *rqst),
        TP_ARGS(rqst),
  
        TP_STRUCT__entry(
 -              __field(struct svc_xprt *, xprt)
                __field(unsigned long, flags)
                __field(unsigned long, wakeup)
                __string(addr, rqst->rq_xprt->xpt_remotebuf)
        ),
  
        TP_fast_assign(
 -              __entry->xprt = rqst->rq_xprt;
                __entry->flags = rqst->rq_xprt->xpt_flags;
                __entry->wakeup = ktime_to_us(ktime_sub(ktime_get(),
                                                        rqst->rq_qtime));
                __assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
        ),
  
 -      TP_printk("xprt=%p addr=%s flags=%s wakeup-us=%lu",
 -                      __entry->xprt, __get_str(addr),
 -                      show_svc_xprt_flags(__entry->flags),
 -                      __entry->wakeup)
 +      TP_printk("addr=%s flags=%s wakeup-us=%lu", __get_str(addr),
 +              show_svc_xprt_flags(__entry->flags), __entry->wakeup)
  );
  
  TRACE_EVENT(svc_wake_up,
@@@ -1361,18 -1492,21 +1588,18 @@@ TRACE_EVENT(svc_handle_xprt
        TP_ARGS(xprt, len),
  
        TP_STRUCT__entry(
 -              __field(struct svc_xprt *, xprt)
                __field(int, len)
                __field(unsigned long, flags)
                __string(addr, xprt->xpt_remotebuf)
        ),
  
        TP_fast_assign(
 -              __entry->xprt = xprt;
                __entry->len = len;
                __entry->flags = xprt->xpt_flags;
                __assign_str(addr, xprt->xpt_remotebuf);
        ),
  
 -      TP_printk("xprt=%p addr=%s len=%d flags=%s",
 -              __entry->xprt, __get_str(addr),
 +      TP_printk("addr=%s len=%d flags=%s", __get_str(addr),
                __entry->len, show_svc_xprt_flags(__entry->flags))
  );
  
@@@ -1406,221 -1540,27 +1633,221 @@@ DECLARE_EVENT_CLASS(svc_deferred_event
        TP_ARGS(dr),
  
        TP_STRUCT__entry(
 +              __field(const void *, dr)
                __field(u32, xid)
                __string(addr, dr->xprt->xpt_remotebuf)
        ),
  
        TP_fast_assign(
 +              __entry->dr = dr;
                __entry->xid = be32_to_cpu(*(__be32 *)(dr->args +
                                                       (dr->xprt_hlen>>2)));
                __assign_str(addr, dr->xprt->xpt_remotebuf);
        ),
  
 -      TP_printk("addr=%s xid=0x%08x", __get_str(addr), __entry->xid)
 +      TP_printk("addr=%s dr=%p xid=0x%08x", __get_str(addr), __entry->dr,
 +              __entry->xid)
  );
 +
  #define DEFINE_SVC_DEFERRED_EVENT(name) \
 -      DEFINE_EVENT(svc_deferred_event, svc_##name##_deferred, \
 +      DEFINE_EVENT(svc_deferred_event, svc_defer_##name, \
                        TP_PROTO( \
                                const struct svc_deferred_req *dr \
                        ), \
                        TP_ARGS(dr))
  
  DEFINE_SVC_DEFERRED_EVENT(drop);
 -DEFINE_SVC_DEFERRED_EVENT(revisit);
 +DEFINE_SVC_DEFERRED_EVENT(queue);
 +DEFINE_SVC_DEFERRED_EVENT(recv);
 +
 +TRACE_EVENT(svcsock_new_socket,
 +      TP_PROTO(
 +              const struct socket *socket
 +      ),
 +
 +      TP_ARGS(socket),
 +
 +      TP_STRUCT__entry(
 +              __field(unsigned long, type)
 +              __field(unsigned long, family)
 +              __field(bool, listener)
 +      ),
 +
 +      TP_fast_assign(
 +              __entry->type = socket->type;
 +              __entry->family = socket->sk->sk_family;
 +              __entry->listener = (socket->sk->sk_state == TCP_LISTEN);
 +      ),
 +
 +      TP_printk("type=%s family=%s%s",
 +              show_socket_type(__entry->type),
 +              rpc_show_address_family(__entry->family),
 +              __entry->listener ? " (listener)" : ""
 +      )
 +);
 +
 +TRACE_EVENT(svcsock_marker,
 +      TP_PROTO(
 +              const struct svc_xprt *xprt,
 +              __be32 marker
 +      ),
 +
 +      TP_ARGS(xprt, marker),
 +
 +      TP_STRUCT__entry(
 +              __field(unsigned int, length)
 +              __field(bool, last)
 +              __string(addr, xprt->xpt_remotebuf)
 +      ),
 +
 +      TP_fast_assign(
 +              __entry->length = be32_to_cpu(marker) & RPC_FRAGMENT_SIZE_MASK;
 +              __entry->last = be32_to_cpu(marker) & RPC_LAST_STREAM_FRAGMENT;
 +              __assign_str(addr, xprt->xpt_remotebuf);
 +      ),
 +
 +      TP_printk("addr=%s length=%u%s", __get_str(addr),
 +              __entry->length, __entry->last ? " (last)" : "")
 +);
 +
 +DECLARE_EVENT_CLASS(svcsock_class,
 +      TP_PROTO(
 +              const struct svc_xprt *xprt,
 +              ssize_t result
 +      ),
 +
 +      TP_ARGS(xprt, result),
 +
 +      TP_STRUCT__entry(
 +              __field(ssize_t, result)
 +              __field(unsigned long, flags)
 +              __string(addr, xprt->xpt_remotebuf)
 +      ),
 +
 +      TP_fast_assign(
 +              __entry->result = result;
 +              __entry->flags = xprt->xpt_flags;
 +              __assign_str(addr, xprt->xpt_remotebuf);
 +      ),
 +
 +      TP_printk("addr=%s result=%zd flags=%s", __get_str(addr),
 +              __entry->result, show_svc_xprt_flags(__entry->flags)
 +      )
 +);
 +
 +#define DEFINE_SVCSOCK_EVENT(name) \
 +      DEFINE_EVENT(svcsock_class, svcsock_##name, \
 +                      TP_PROTO( \
 +                              const struct svc_xprt *xprt, \
 +                              ssize_t result \
 +                      ), \
 +                      TP_ARGS(xprt, result))
 +
 +DEFINE_SVCSOCK_EVENT(udp_send);
 +DEFINE_SVCSOCK_EVENT(udp_recv);
 +DEFINE_SVCSOCK_EVENT(udp_recv_err);
 +DEFINE_SVCSOCK_EVENT(tcp_send);
 +DEFINE_SVCSOCK_EVENT(tcp_recv);
 +DEFINE_SVCSOCK_EVENT(tcp_recv_eagain);
 +DEFINE_SVCSOCK_EVENT(tcp_recv_err);
 +DEFINE_SVCSOCK_EVENT(data_ready);
 +DEFINE_SVCSOCK_EVENT(write_space);
 +
 +TRACE_EVENT(svcsock_tcp_recv_short,
 +      TP_PROTO(
 +              const struct svc_xprt *xprt,
 +              u32 expected,
 +              u32 received
 +      ),
 +
 +      TP_ARGS(xprt, expected, received),
 +
 +      TP_STRUCT__entry(
 +              __field(u32, expected)
 +              __field(u32, received)
 +              __field(unsigned long, flags)
 +              __string(addr, xprt->xpt_remotebuf)
 +      ),
 +
 +      TP_fast_assign(
 +              __entry->expected = expected;
 +              __entry->received = received;
 +              __entry->flags = xprt->xpt_flags;
 +              __assign_str(addr, xprt->xpt_remotebuf);
 +      ),
 +
 +      TP_printk("addr=%s flags=%s expected=%u received=%u",
 +              __get_str(addr), show_svc_xprt_flags(__entry->flags),
 +              __entry->expected, __entry->received
 +      )
 +);
 +
 +TRACE_EVENT(svcsock_tcp_state,
 +      TP_PROTO(
 +              const struct svc_xprt *xprt,
 +              const struct socket *socket
 +      ),
 +
 +      TP_ARGS(xprt, socket),
 +
 +      TP_STRUCT__entry(
 +              __field(unsigned long, socket_state)
 +              __field(unsigned long, sock_state)
 +              __field(unsigned long, flags)
 +              __string(addr, xprt->xpt_remotebuf)
 +      ),
 +
 +      TP_fast_assign(
 +              __entry->socket_state = socket->state;
 +              __entry->sock_state = socket->sk->sk_state;
 +              __entry->flags = xprt->xpt_flags;
 +              __assign_str(addr, xprt->xpt_remotebuf);
 +      ),
 +
 +      TP_printk("addr=%s state=%s sk_state=%s flags=%s", __get_str(addr),
 +              rpc_show_socket_state(__entry->socket_state),
 +              rpc_show_sock_state(__entry->sock_state),
 +              show_svc_xprt_flags(__entry->flags)
 +      )
 +);
 +
 +DECLARE_EVENT_CLASS(svcsock_accept_class,
 +      TP_PROTO(
 +              const struct svc_xprt *xprt,
 +              const char *service,
 +              long status
 +      ),
 +
 +      TP_ARGS(xprt, service, status),
 +
 +      TP_STRUCT__entry(
 +              __field(long, status)
 +              __string(service, service)
 +              __array(unsigned char, addr, sizeof(struct sockaddr_in6))
 +      ),
 +
 +      TP_fast_assign(
 +              __entry->status = status;
 +              __assign_str(service, service);
 +              memcpy(__entry->addr, &xprt->xpt_local, sizeof(__entry->addr));
 +      ),
 +
 +      TP_printk("listener=%pISpc service=%s status=%ld",
 +              __entry->addr, __get_str(service), __entry->status
 +      )
 +);
 +
 +#define DEFINE_ACCEPT_EVENT(name) \
 +      DEFINE_EVENT(svcsock_accept_class, svcsock_##name##_err, \
 +                      TP_PROTO( \
 +                              const struct svc_xprt *xprt, \
 +                              const char *service, \
 +                              long status \
 +                      ), \
 +                      TP_ARGS(xprt, service, status))
 +
 +DEFINE_ACCEPT_EVENT(accept);
 +DEFINE_ACCEPT_EVENT(getpeername);
  
  DECLARE_EVENT_CLASS(cache_event,
        TP_PROTO(
@@@ -1655,86 -1595,6 +1882,86 @@@ DEFINE_CACHE_EVENT(cache_entry_update)
  DEFINE_CACHE_EVENT(cache_entry_make_negative);
  DEFINE_CACHE_EVENT(cache_entry_no_listener);
  
 +DECLARE_EVENT_CLASS(register_class,
 +      TP_PROTO(
 +              const char *program,
 +              const u32 version,
 +              const int family,
 +              const unsigned short protocol,
 +              const unsigned short port,
 +              int error
 +      ),
 +
 +      TP_ARGS(program, version, family, protocol, port, error),
 +
 +      TP_STRUCT__entry(
 +              __field(u32, version)
 +              __field(unsigned long, family)
 +              __field(unsigned short, protocol)
 +              __field(unsigned short, port)
 +              __field(int, error)
 +              __string(program, program)
 +      ),
 +
 +      TP_fast_assign(
 +              __entry->version = version;
 +              __entry->family = family;
 +              __entry->protocol = protocol;
 +              __entry->port = port;
 +              __entry->error = error;
 +              __assign_str(program, program);
 +      ),
 +
 +      TP_printk("program=%sv%u proto=%s port=%u family=%s error=%d",
 +              __get_str(program), __entry->version,
 +              __entry->protocol == IPPROTO_UDP ? "udp" : "tcp",
 +              __entry->port, rpc_show_address_family(__entry->family),
 +              __entry->error
 +      )
 +);
 +
 +#define DEFINE_REGISTER_EVENT(name) \
 +      DEFINE_EVENT(register_class, svc_##name, \
 +                      TP_PROTO( \
 +                              const char *program, \
 +                              const u32 version, \
 +                              const int family, \
 +                              const unsigned short protocol, \
 +                              const unsigned short port, \
 +                              int error \
 +                      ), \
 +                      TP_ARGS(program, version, family, protocol, \
 +                              port, error))
 +
 +DEFINE_REGISTER_EVENT(register);
 +DEFINE_REGISTER_EVENT(noregister);
 +
 +TRACE_EVENT(svc_unregister,
 +      TP_PROTO(
 +              const char *program,
 +              const u32 version,
 +              int error
 +      ),
 +
 +      TP_ARGS(program, version, error),
 +
 +      TP_STRUCT__entry(
 +              __field(u32, version)
 +              __field(int, error)
 +              __string(program, program)
 +      ),
 +
 +      TP_fast_assign(
 +              __entry->version = version;
 +              __entry->error = error;
 +              __assign_str(program, program);
 +      ),
 +
 +      TP_printk("program=%sv%u error=%d",
 +              __get_str(program), __entry->version, __entry->error
 +      )
 +);
 +
  #endif /* _TRACE_SUNRPC_H */
  
  #include <trace/define_trace.h>
diff --combined net/sunrpc/svc_xprt.c
@@@ -153,7 -153,6 +153,7 @@@ static void svc_xprt_free(struct kref *
                xprt_put(xprt->xpt_bc_xprt);
        if (xprt->xpt_bc_xps)
                xprt_switch_put(xprt->xpt_bc_xps);
 +      trace_svc_xprt_free(xprt);
        xprt->xpt_ops->xpo_free(xprt);
        module_put(owner);
  }
@@@ -207,7 -206,6 +207,7 @@@ static struct svc_xprt *__svc_xpo_creat
                .sin6_port              = htons(port),
        };
  #endif
 +      struct svc_xprt *xprt;
        struct sockaddr *sap;
        size_t len;
  
                return ERR_PTR(-EAFNOSUPPORT);
        }
  
 -      return xcl->xcl_ops->xpo_create(serv, net, sap, len, flags);
 +      xprt = xcl->xcl_ops->xpo_create(serv, net, sap, len, flags);
 +      if (IS_ERR(xprt))
 +              trace_svc_xprt_create_err(serv->sv_program->pg_name,
 +                                        xcl->xcl_name, sap, xprt);
 +      return xprt;
  }
  
  /*
@@@ -310,11 -304,15 +310,11 @@@ int svc_create_xprt(struct svc_serv *se
  {
        int err;
  
 -      dprintk("svc: creating transport %s[%d]\n", xprt_name, port);
        err = _svc_create_xprt(serv, xprt_name, net, family, port, flags, cred);
        if (err == -EPROTONOSUPPORT) {
                request_module("svc%s", xprt_name);
                err = _svc_create_xprt(serv, xprt_name, net, family, port, flags, cred);
        }
 -      if (err < 0)
 -              dprintk("svc: transport %s not found, err %d\n",
 -                      xprt_name, -err);
        return err;
  }
  EXPORT_SYMBOL_GPL(svc_create_xprt);
@@@ -782,6 -780,7 +782,6 @@@ static int svc_handle_xprt(struct svc_r
        int len = 0;
  
        if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) {
 -              dprintk("svc_recv: found XPT_CLOSE\n");
                if (test_and_clear_bit(XPT_KILL_TEMP, &xprt->xpt_flags))
                        xprt->xpt_ops->xpo_kill_temp_xprt(xprt);
                svc_delete_xprt(xprt);
                if (newxpt) {
                        newxpt->xpt_cred = get_cred(xprt->xpt_cred);
                        svc_add_new_temp_xprt(serv, newxpt);
 +                      trace_svc_xprt_accept(newxpt, serv->sv_name);
                } else
                        module_put(xprt->xpt_class->xcl_owner);
        } else if (svc_xprt_reserve_slot(rqstp, xprt)) {
                else
                        len = xprt->xpt_ops->xpo_recvfrom(rqstp);
                if (len > 0)
-                       trace_svc_recvfrom(&rqstp->rq_arg);
+                       trace_svc_xdr_recvfrom(rqstp, &rqstp->rq_arg);
                rqstp->rq_stime = ktime_get();
                rqstp->rq_reserved = serv->sv_max_mesg;
                atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
@@@ -837,6 -835,14 +837,6 @@@ int svc_recv(struct svc_rqst *rqstp, lo
        struct svc_serv         *serv = rqstp->rq_server;
        int                     len, err;
  
 -      dprintk("svc: server %p waiting for data (to = %ld)\n",
 -              rqstp, timeout);
 -
 -      if (rqstp->rq_xprt)
 -              printk(KERN_ERR
 -                      "svc_recv: service %p, transport not NULL!\n",
 -                       rqstp);
 -
        err = svc_alloc_arg(rqstp);
        if (err)
                goto out;
@@@ -884,6 -890,7 +884,6 @@@ EXPORT_SYMBOL_GPL(svc_recv)
  void svc_drop(struct svc_rqst *rqstp)
  {
        trace_svc_drop(rqstp);
 -      dprintk("svc: xprt %p dropped request\n", rqstp->rq_xprt);
        svc_xprt_release(rqstp);
  }
  EXPORT_SYMBOL_GPL(svc_drop);
@@@ -906,11 -913,17 +906,11 @@@ int svc_send(struct svc_rqst *rqstp
        xb->len = xb->head[0].iov_len +
                xb->page_len +
                xb->tail[0].iov_len;
-       trace_svc_sendto(xb);
+       trace_svc_xdr_sendto(rqstp, xb);
 -
 -      /* Grab mutex to serialize outgoing data. */
 -      mutex_lock(&xprt->xpt_mutex);
        trace_svc_stats_latency(rqstp);
 -      if (test_bit(XPT_DEAD, &xprt->xpt_flags)
 -                      || test_bit(XPT_CLOSE, &xprt->xpt_flags))
 -              len = -ENOTCONN;
 -      else
 -              len = xprt->xpt_ops->xpo_sendto(rqstp);
 -      mutex_unlock(&xprt->xpt_mutex);
 +
 +      len = xprt->xpt_ops->xpo_sendto(rqstp);
 +
        trace_svc_send(rqstp, len);
        svc_xprt_release(rqstp);
  
@@@ -1018,10 -1031,11 +1018,10 @@@ static void svc_delete_xprt(struct svc_
        struct svc_serv *serv = xprt->xpt_server;
        struct svc_deferred_req *dr;
  
 -      /* Only do this once */
        if (test_and_set_bit(XPT_DEAD, &xprt->xpt_flags))
 -              BUG();
 +              return;
  
 -      dprintk("svc: svc_delete_xprt(%p)\n", xprt);
 +      trace_svc_xprt_detach(xprt);
        xprt->xpt_ops->xpo_detach(xprt);
        if (xprt->xpt_bc_xprt)
                xprt->xpt_bc_xprt->ops->close(xprt->xpt_bc_xprt);
  
  void svc_close_xprt(struct svc_xprt *xprt)
  {
 +      trace_svc_xprt_close(xprt);
        set_bit(XPT_CLOSE, &xprt->xpt_flags);
        if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags))
                /* someone else will have to effect the close */
@@@ -1145,15 -1158,16 +1145,15 @@@ static void svc_revisit(struct cache_de
        set_bit(XPT_DEFERRED, &xprt->xpt_flags);
        if (too_many || test_bit(XPT_DEAD, &xprt->xpt_flags)) {
                spin_unlock(&xprt->xpt_lock);
 -              dprintk("revisit canceled\n");
 +              trace_svc_defer_drop(dr);
                svc_xprt_put(xprt);
 -              trace_svc_drop_deferred(dr);
                kfree(dr);
                return;
        }
 -      dprintk("revisit queued\n");
        dr->xprt = NULL;
        list_add(&dr->handle.recent, &xprt->xpt_deferred);
        spin_unlock(&xprt->xpt_lock);
 +      trace_svc_defer_queue(dr);
        svc_xprt_enqueue(xprt);
        svc_xprt_put(xprt);
  }
@@@ -1199,24 -1213,22 +1199,24 @@@ static struct cache_deferred_req *svc_d
                memcpy(dr->args, rqstp->rq_arg.head[0].iov_base - skip,
                       dr->argslen << 2);
        }
 +      trace_svc_defer(rqstp);
        svc_xprt_get(rqstp->rq_xprt);
        dr->xprt = rqstp->rq_xprt;
        set_bit(RQ_DROPME, &rqstp->rq_flags);
  
        dr->handle.revisit = svc_revisit;
 -      trace_svc_defer(rqstp);
        return &dr->handle;
  }
  
  /*
   * recv data from a deferred request into an active one
   */
 -static int svc_deferred_recv(struct svc_rqst *rqstp)
 +static noinline int svc_deferred_recv(struct svc_rqst *rqstp)
  {
        struct svc_deferred_req *dr = rqstp->rq_deferred;
  
 +      trace_svc_defer_recv(dr);
 +
        /* setup iov_base past transport header */
        rqstp->rq_arg.head[0].iov_base = dr->args + (dr->xprt_hlen>>2);
        /* The iov_len does not include the transport header bytes */
@@@ -1247,6 -1259,7 +1247,6 @@@ static struct svc_deferred_req *svc_def
                                struct svc_deferred_req,
                                handle.recent);
                list_del_init(&dr->handle.recent);
 -              trace_svc_revisit_deferred(dr);
        } else
                clear_bit(XPT_DEFERRED, &xprt->xpt_flags);
        spin_unlock(&xprt->xpt_lock);