]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
usb: xhci: add xhci_log_ring trace events
authorLu Baolu <baolu.lu@linux.intel.com>
Fri, 7 Apr 2017 14:57:02 +0000 (17:57 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 8 Apr 2017 10:17:41 +0000 (12:17 +0200)
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>
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci-trace.h

index 032a7020a6b0bfc6266f9fc35705169d39e34ed3..c9701078242192a70a0cff12756a34210967b748 100644 (file)
@@ -288,6 +288,8 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring)
        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(struct xhci_hcd *xhci,
                        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, struct xhci_ring *ring,
        }
 
        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);
index c8910fd9b34c5a0c8e255f5edcdd61aa7b397857..28ea69338ed1c687183bfcca69159f96f6d14f7e 100644 (file)
@@ -191,6 +191,9 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)
                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 *xhci, struct xhci_ring *ring,
                ring->enqueue = ring->enq_seg->trbs;
                next = ring->enqueue;
        }
+
+       trace_xhci_inc_enq(ring);
 }
 
 /*
index 7baeab9446c753a625db345626bf37468ae74b7d..8ce96de10e8a1cb0adbb1eb61b7abe3e5b084573 100644 (file)
@@ -388,6 +388,71 @@ DEFINE_EVENT(xhci_log_slot_ctx, xhci_handle_cmd_set_deq,
        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 */