| From 200abe368c59bdfe1fce263d7700e04efb0b7ef3 Mon Sep 17 00:00:00 2001 |
| From: Lu Baolu <baolu.lu@linux.intel.com> |
| Date: Fri, 7 Apr 2017 17:57:02 +0300 |
| Subject: [PATCH 188/286] usb: xhci: add xhci_log_ring trace events |
| |
| This patch creates a new event class called xhci_log_ring, and |
| defines the events used for tracing the change of all kinds of |
| rings used by an xhci host. An xHCI ring is basically a memory |
| block shared between software and hardware. By tracing changes |
| of rings, it makes the life easier for debugging hardware or |
| software problems. |
| |
| This info can be used, later, to print, in a human readable way, |
| the life cycle of an xHCI ring using the trace-cmd tool and the |
| appropriate plugin. |
| |
| Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> |
| Reviewed-by: Felipe Balbi <felipe.balbi@linux.intel.com> |
| Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| (cherry picked from commit b2d6edbb95487e90ffc22072879b0865ccb89a80) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/usb/host/xhci-mem.c | 4 ++ |
| drivers/usb/host/xhci-ring.c | 5 +++ |
| drivers/usb/host/xhci-trace.h | 65 ++++++++++++++++++++++++++++++++++++++++++ |
| 3 files changed, 74 insertions(+) |
| |
| --- a/drivers/usb/host/xhci-mem.c |
| +++ b/drivers/usb/host/xhci-mem.c |
| @@ -288,6 +288,8 @@ void xhci_ring_free(struct xhci_hcd *xhc |
| if (!ring) |
| return; |
| |
| + trace_xhci_ring_free(ring); |
| + |
| if (ring->first_seg) { |
| if (ring->type == TYPE_STREAM) |
| xhci_remove_stream_mapping(ring); |
| @@ -400,6 +402,7 @@ static struct xhci_ring *xhci_ring_alloc |
| cpu_to_le32(LINK_TOGGLE); |
| } |
| xhci_initialize_ring_info(ring, cycle_state); |
| + trace_xhci_ring_alloc(ring); |
| return ring; |
| |
| fail: |
| @@ -504,6 +507,7 @@ int xhci_ring_expansion(struct xhci_hcd |
| } |
| |
| xhci_link_rings(xhci, ring, first, last, num_segs); |
| + trace_xhci_ring_expansion(ring); |
| xhci_dbg_trace(xhci, trace_xhci_dbg_ring_expansion, |
| "ring expansion succeed, now has %d segments", |
| ring->num_segs); |
| --- a/drivers/usb/host/xhci-ring.c |
| +++ b/drivers/usb/host/xhci-ring.c |
| @@ -191,6 +191,9 @@ static void inc_deq(struct xhci_hcd *xhc |
| ring->deq_seg = ring->deq_seg->next; |
| ring->dequeue = ring->deq_seg->trbs; |
| } |
| + |
| + trace_xhci_inc_deq(ring); |
| + |
| return; |
| } |
| |
| @@ -259,6 +262,8 @@ static void inc_enq(struct xhci_hcd *xhc |
| ring->enqueue = ring->enq_seg->trbs; |
| next = ring->enqueue; |
| } |
| + |
| + trace_xhci_inc_enq(ring); |
| } |
| |
| /* |
| --- a/drivers/usb/host/xhci-trace.h |
| +++ b/drivers/usb/host/xhci-trace.h |
| @@ -386,6 +386,71 @@ DEFINE_EVENT(xhci_log_slot_ctx, xhci_han |
| TP_ARGS(ctx) |
| ); |
| |
| +DECLARE_EVENT_CLASS(xhci_log_ring, |
| + TP_PROTO(struct xhci_ring *ring), |
| + TP_ARGS(ring), |
| + TP_STRUCT__entry( |
| + __field(u32, type) |
| + __field(void *, ring) |
| + __field(dma_addr_t, enq) |
| + __field(dma_addr_t, deq) |
| + __field(dma_addr_t, enq_seg) |
| + __field(dma_addr_t, deq_seg) |
| + __field(unsigned int, num_segs) |
| + __field(unsigned int, stream_id) |
| + __field(unsigned int, cycle_state) |
| + __field(unsigned int, num_trbs_free) |
| + __field(unsigned int, bounce_buf_len) |
| + ), |
| + TP_fast_assign( |
| + __entry->ring = ring; |
| + __entry->type = ring->type; |
| + __entry->num_segs = ring->num_segs; |
| + __entry->stream_id = ring->stream_id; |
| + __entry->enq_seg = ring->enq_seg->dma; |
| + __entry->deq_seg = ring->deq_seg->dma; |
| + __entry->cycle_state = ring->cycle_state; |
| + __entry->num_trbs_free = ring->num_trbs_free; |
| + __entry->bounce_buf_len = ring->bounce_buf_len; |
| + __entry->enq = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); |
| + __entry->deq = xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); |
| + ), |
| + TP_printk("%s %p: enq %pad(%pad) deq %pad(%pad) segs %d stream %d free_trbs %d bounce %d cycle %d", |
| + xhci_ring_type_string(__entry->type), __entry->ring, |
| + &__entry->enq, &__entry->enq_seg, |
| + &__entry->deq, &__entry->deq_seg, |
| + __entry->num_segs, |
| + __entry->stream_id, |
| + __entry->num_trbs_free, |
| + __entry->bounce_buf_len, |
| + __entry->cycle_state |
| + ) |
| +); |
| + |
| +DEFINE_EVENT(xhci_log_ring, xhci_ring_alloc, |
| + TP_PROTO(struct xhci_ring *ring), |
| + TP_ARGS(ring) |
| +); |
| + |
| +DEFINE_EVENT(xhci_log_ring, xhci_ring_free, |
| + TP_PROTO(struct xhci_ring *ring), |
| + TP_ARGS(ring) |
| +); |
| + |
| +DEFINE_EVENT(xhci_log_ring, xhci_ring_expansion, |
| + TP_PROTO(struct xhci_ring *ring), |
| + TP_ARGS(ring) |
| +); |
| + |
| +DEFINE_EVENT(xhci_log_ring, xhci_inc_enq, |
| + TP_PROTO(struct xhci_ring *ring), |
| + TP_ARGS(ring) |
| +); |
| + |
| +DEFINE_EVENT(xhci_log_ring, xhci_inc_deq, |
| + TP_PROTO(struct xhci_ring *ring), |
| + TP_ARGS(ring) |
| +); |
| #endif /* __XHCI_TRACE_H */ |
| |
| /* this part must be outside header guard */ |