Loading include/trace/events/sunrpc.h +67 −0 Original line number Diff line number Diff line Loading @@ -254,6 +254,73 @@ TRACE_EVENT(rpc_stats_latency, __entry->backlog, __entry->rtt, __entry->execute) ); TRACE_EVENT(rpc_xdr_overflow, TP_PROTO( const struct xdr_stream *xdr, size_t requested ), TP_ARGS(xdr, requested), TP_STRUCT__entry( __field(unsigned int, task_id) __field(unsigned int, client_id) __field(int, version) __field(size_t, requested) __field(const void *, end) __field(const void *, p) __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, len) __string(progname, xdr->rqst->rq_task->tk_client->cl_program->name) __string(procedure, xdr->rqst->rq_task->tk_msg.rpc_proc->p_name) ), TP_fast_assign( if (xdr->rqst) { const struct rpc_task *task = xdr->rqst->rq_task; __entry->task_id = task->tk_pid; __entry->client_id = task->tk_client->cl_clid; __assign_str(progname, task->tk_client->cl_program->name) __entry->version = task->tk_client->cl_vers; __assign_str(procedure, task->tk_msg.rpc_proc->p_name) } else { __entry->task_id = 0; __entry->client_id = 0; __assign_str(progname, "unknown") __entry->version = 0; __assign_str(procedure, "unknown") } __entry->requested = requested; __entry->end = xdr->end; __entry->p = xdr->p; __entry->head_base = xdr->buf->head[0].iov_base, __entry->head_len = xdr->buf->head[0].iov_len, __entry->page_len = xdr->buf->page_len, __entry->tail_base = xdr->buf->tail[0].iov_base, __entry->tail_len = xdr->buf->tail[0].iov_len, __entry->len = xdr->buf->len; ), TP_printk( "task:%u@%u %sv%d %s requested=%zu p=%p end=%p xdr=[%p,%zu]/%u/[%p,%zu]/%u\n", __entry->task_id, __entry->client_id, __get_str(progname), __entry->version, __get_str(procedure), __entry->requested, __entry->p, __entry->end, __entry->head_base, __entry->head_len, __entry->page_len, __entry->tail_base, __entry->tail_len, __entry->len ) ); /* * First define the enums in the below macros to be exported to userspace * via TRACE_DEFINE_ENUM(). Loading net/sunrpc/xdr.c +17 −7 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/sunrpc/xdr.h> #include <linux/sunrpc/msg_prot.h> #include <linux/bvec.h> #include <trace/events/sunrpc.h> /* * XDR functions for basic NFS types Loading Loading @@ -554,9 +555,9 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, int frag1bytes, frag2bytes; if (nbytes > PAGE_SIZE) return NULL; /* Bigger buffers require special handling */ goto out_overflow; /* Bigger buffers require special handling */ if (xdr->buf->len + nbytes > xdr->buf->buflen) return NULL; /* Sorry, we're totally out of space */ goto out_overflow; /* Sorry, we're totally out of space */ frag1bytes = (xdr->end - xdr->p) << 2; frag2bytes = nbytes - frag1bytes; if (xdr->iov) Loading Loading @@ -585,6 +586,9 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, xdr->buf->page_len += frag2bytes; xdr->buf->len += nbytes; return p; out_overflow: trace_rpc_xdr_overflow(xdr, nbytes); return NULL; } /** Loading Loading @@ -902,20 +906,23 @@ static __be32 *xdr_copy_to_scratch(struct xdr_stream *xdr, size_t nbytes) size_t cplen = (char *)xdr->end - (char *)xdr->p; if (nbytes > xdr->scratch.iov_len) return NULL; goto out_overflow; p = __xdr_inline_decode(xdr, cplen); if (p == NULL) return NULL; memcpy(cpdest, p, cplen); if (!xdr_set_next_buffer(xdr)) goto out_overflow; cpdest += cplen; nbytes -= cplen; if (!xdr_set_next_buffer(xdr)) return NULL; p = __xdr_inline_decode(xdr, nbytes); if (p == NULL) return NULL; memcpy(cpdest, p, nbytes); return xdr->scratch.iov_base; out_overflow: trace_rpc_xdr_overflow(xdr, nbytes); return NULL; } /** Loading @@ -932,14 +939,17 @@ __be32 * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) { __be32 *p; if (nbytes == 0) if (unlikely(nbytes == 0)) return xdr->p; if (xdr->p == xdr->end && !xdr_set_next_buffer(xdr)) return NULL; goto out_overflow; p = __xdr_inline_decode(xdr, nbytes); if (p != NULL) return p; return xdr_copy_to_scratch(xdr, nbytes); out_overflow: trace_rpc_xdr_overflow(xdr, nbytes); return NULL; } EXPORT_SYMBOL_GPL(xdr_inline_decode); Loading Loading
include/trace/events/sunrpc.h +67 −0 Original line number Diff line number Diff line Loading @@ -254,6 +254,73 @@ TRACE_EVENT(rpc_stats_latency, __entry->backlog, __entry->rtt, __entry->execute) ); TRACE_EVENT(rpc_xdr_overflow, TP_PROTO( const struct xdr_stream *xdr, size_t requested ), TP_ARGS(xdr, requested), TP_STRUCT__entry( __field(unsigned int, task_id) __field(unsigned int, client_id) __field(int, version) __field(size_t, requested) __field(const void *, end) __field(const void *, p) __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, len) __string(progname, xdr->rqst->rq_task->tk_client->cl_program->name) __string(procedure, xdr->rqst->rq_task->tk_msg.rpc_proc->p_name) ), TP_fast_assign( if (xdr->rqst) { const struct rpc_task *task = xdr->rqst->rq_task; __entry->task_id = task->tk_pid; __entry->client_id = task->tk_client->cl_clid; __assign_str(progname, task->tk_client->cl_program->name) __entry->version = task->tk_client->cl_vers; __assign_str(procedure, task->tk_msg.rpc_proc->p_name) } else { __entry->task_id = 0; __entry->client_id = 0; __assign_str(progname, "unknown") __entry->version = 0; __assign_str(procedure, "unknown") } __entry->requested = requested; __entry->end = xdr->end; __entry->p = xdr->p; __entry->head_base = xdr->buf->head[0].iov_base, __entry->head_len = xdr->buf->head[0].iov_len, __entry->page_len = xdr->buf->page_len, __entry->tail_base = xdr->buf->tail[0].iov_base, __entry->tail_len = xdr->buf->tail[0].iov_len, __entry->len = xdr->buf->len; ), TP_printk( "task:%u@%u %sv%d %s requested=%zu p=%p end=%p xdr=[%p,%zu]/%u/[%p,%zu]/%u\n", __entry->task_id, __entry->client_id, __get_str(progname), __entry->version, __get_str(procedure), __entry->requested, __entry->p, __entry->end, __entry->head_base, __entry->head_len, __entry->page_len, __entry->tail_base, __entry->tail_len, __entry->len ) ); /* * First define the enums in the below macros to be exported to userspace * via TRACE_DEFINE_ENUM(). Loading
net/sunrpc/xdr.c +17 −7 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/sunrpc/xdr.h> #include <linux/sunrpc/msg_prot.h> #include <linux/bvec.h> #include <trace/events/sunrpc.h> /* * XDR functions for basic NFS types Loading Loading @@ -554,9 +555,9 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, int frag1bytes, frag2bytes; if (nbytes > PAGE_SIZE) return NULL; /* Bigger buffers require special handling */ goto out_overflow; /* Bigger buffers require special handling */ if (xdr->buf->len + nbytes > xdr->buf->buflen) return NULL; /* Sorry, we're totally out of space */ goto out_overflow; /* Sorry, we're totally out of space */ frag1bytes = (xdr->end - xdr->p) << 2; frag2bytes = nbytes - frag1bytes; if (xdr->iov) Loading Loading @@ -585,6 +586,9 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, xdr->buf->page_len += frag2bytes; xdr->buf->len += nbytes; return p; out_overflow: trace_rpc_xdr_overflow(xdr, nbytes); return NULL; } /** Loading Loading @@ -902,20 +906,23 @@ static __be32 *xdr_copy_to_scratch(struct xdr_stream *xdr, size_t nbytes) size_t cplen = (char *)xdr->end - (char *)xdr->p; if (nbytes > xdr->scratch.iov_len) return NULL; goto out_overflow; p = __xdr_inline_decode(xdr, cplen); if (p == NULL) return NULL; memcpy(cpdest, p, cplen); if (!xdr_set_next_buffer(xdr)) goto out_overflow; cpdest += cplen; nbytes -= cplen; if (!xdr_set_next_buffer(xdr)) return NULL; p = __xdr_inline_decode(xdr, nbytes); if (p == NULL) return NULL; memcpy(cpdest, p, nbytes); return xdr->scratch.iov_base; out_overflow: trace_rpc_xdr_overflow(xdr, nbytes); return NULL; } /** Loading @@ -932,14 +939,17 @@ __be32 * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) { __be32 *p; if (nbytes == 0) if (unlikely(nbytes == 0)) return xdr->p; if (xdr->p == xdr->end && !xdr_set_next_buffer(xdr)) return NULL; goto out_overflow; p = __xdr_inline_decode(xdr, nbytes); if (p != NULL) return p; return xdr_copy_to_scratch(xdr, nbytes); out_overflow: trace_rpc_xdr_overflow(xdr, nbytes); return NULL; } EXPORT_SYMBOL_GPL(xdr_inline_decode); Loading