aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2010-07-30 01:12:20 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 17:35:44 -0400
commit021bff9179c2d19c26599dc3e9134d04cf1c8a3a (patch)
tree99c7dba0d83e607a2ca9d12e50bd8ee7bad56181 /drivers/usb
parentc6ba1c2af2da31ffb57949edbd1dba34f97d1d4b (diff)
USB: xhci: Performance - move functions that find ep ring.
I've been using perf to measure the top symbols while transferring 1GB of data on a USB 3.0 drive with dd. This is using the raw disk with /dev/sdb, with a block size of 1K. During performance testing, the top symbol was xhci_triad_to_transfer_ring(), a function that should return immediately if streams are not enabled for an endpoint. It turned out that the functions to find the endpoint ring was defined in xhci-mem.c and used in xhci-ring.c and xhci-hcd.c. I moved a copy of xhci_triad_to_transfer_ring() and xhci_urb_to_transfer_ring() into xhci-ring.c and declared them static. I also made a static version of xhci_urb_to_transfer_ring() in xhci.c. This improved throughput on a 1GB read of the raw disk with dd from 186MB/s to 195MB/s, and perf reported sampling the xhci_triad_to_transfer_ring() 0.06% of the time, rather than 9.26% of the time. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/xhci-mem.c43
-rw-r--r--drivers/usb/host/xhci-ring.c44
-rw-r--r--drivers/usb/host/xhci.c41
-rw-r--r--drivers/usb/host/xhci.h5
4 files changed, 85 insertions, 48 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 7d60d1f4debb..ac57f538f957 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -391,49 +391,6 @@ struct xhci_ring *xhci_stream_id_to_ring(
391 return ep->stream_info->stream_rings[stream_id]; 391 return ep->stream_info->stream_rings[stream_id];
392} 392}
393 393
394struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci,
395 unsigned int slot_id, unsigned int ep_index,
396 unsigned int stream_id)
397{
398 struct xhci_virt_ep *ep;
399
400 ep = &xhci->devs[slot_id]->eps[ep_index];
401 /* Common case: no streams */
402 if (!(ep->ep_state & EP_HAS_STREAMS))
403 return ep->ring;
404
405 if (stream_id == 0) {
406 xhci_warn(xhci,
407 "WARN: Slot ID %u, ep index %u has streams, "
408 "but URB has no stream ID.\n",
409 slot_id, ep_index);
410 return NULL;
411 }
412
413 if (stream_id < ep->stream_info->num_streams)
414 return ep->stream_info->stream_rings[stream_id];
415
416 xhci_warn(xhci,
417 "WARN: Slot ID %u, ep index %u has "
418 "stream IDs 1 to %u allocated, "
419 "but stream ID %u is requested.\n",
420 slot_id, ep_index,
421 ep->stream_info->num_streams - 1,
422 stream_id);
423 return NULL;
424}
425
426/* Get the right ring for the given URB.
427 * If the endpoint supports streams, boundary check the URB's stream ID.
428 * If the endpoint doesn't support streams, return the singular endpoint ring.
429 */
430struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci,
431 struct urb *urb)
432{
433 return xhci_triad_to_transfer_ring(xhci, urb->dev->slot_id,
434 xhci_get_endpoint_index(&urb->ep->desc), urb->stream_id);
435}
436
437#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING 394#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
438static int xhci_test_radix_tree(struct xhci_hcd *xhci, 395static int xhci_test_radix_tree(struct xhci_hcd *xhci,
439 unsigned int num_streams, 396 unsigned int num_streams,
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index da3519e76e2b..7f1c54585b63 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -419,6 +419,50 @@ static struct xhci_segment *find_trb_seg(
419 return cur_seg; 419 return cur_seg;
420} 420}
421 421
422
423static struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci,
424 unsigned int slot_id, unsigned int ep_index,
425 unsigned int stream_id)
426{
427 struct xhci_virt_ep *ep;
428
429 ep = &xhci->devs[slot_id]->eps[ep_index];
430 /* Common case: no streams */
431 if (!(ep->ep_state & EP_HAS_STREAMS))
432 return ep->ring;
433
434 if (stream_id == 0) {
435 xhci_warn(xhci,
436 "WARN: Slot ID %u, ep index %u has streams, "
437 "but URB has no stream ID.\n",
438 slot_id, ep_index);
439 return NULL;
440 }
441
442 if (stream_id < ep->stream_info->num_streams)
443 return ep->stream_info->stream_rings[stream_id];
444
445 xhci_warn(xhci,
446 "WARN: Slot ID %u, ep index %u has "
447 "stream IDs 1 to %u allocated, "
448 "but stream ID %u is requested.\n",
449 slot_id, ep_index,
450 ep->stream_info->num_streams - 1,
451 stream_id);
452 return NULL;
453}
454
455/* Get the right ring for the given URB.
456 * If the endpoint supports streams, boundary check the URB's stream ID.
457 * If the endpoint doesn't support streams, return the singular endpoint ring.
458 */
459static struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci,
460 struct urb *urb)
461{
462 return xhci_triad_to_transfer_ring(xhci, urb->dev->slot_id,
463 xhci_get_endpoint_index(&urb->ep->desc), urb->stream_id);
464}
465
422/* 466/*
423 * Move the xHC's endpoint ring dequeue pointer past cur_td. 467 * Move the xHC's endpoint ring dequeue pointer past cur_td.
424 * Record the new state of the xHC's endpoint ring dequeue segment, 468 * Record the new state of the xHC's endpoint ring dequeue segment,
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 89ac48534099..f5e0b00cbb83 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -916,6 +916,47 @@ dying:
916 return -ESHUTDOWN; 916 return -ESHUTDOWN;
917} 917}
918 918
919/* Get the right ring for the given URB.
920 * If the endpoint supports streams, boundary check the URB's stream ID.
921 * If the endpoint doesn't support streams, return the singular endpoint ring.
922 */
923static struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci,
924 struct urb *urb)
925{
926 unsigned int slot_id;
927 unsigned int ep_index;
928 unsigned int stream_id;
929 struct xhci_virt_ep *ep;
930
931 slot_id = urb->dev->slot_id;
932 ep_index = xhci_get_endpoint_index(&urb->ep->desc);
933 stream_id = urb->stream_id;
934 ep = &xhci->devs[slot_id]->eps[ep_index];
935 /* Common case: no streams */
936 if (!(ep->ep_state & EP_HAS_STREAMS))
937 return ep->ring;
938
939 if (stream_id == 0) {
940 xhci_warn(xhci,
941 "WARN: Slot ID %u, ep index %u has streams, "
942 "but URB has no stream ID.\n",
943 slot_id, ep_index);
944 return NULL;
945 }
946
947 if (stream_id < ep->stream_info->num_streams)
948 return ep->stream_info->stream_rings[stream_id];
949
950 xhci_warn(xhci,
951 "WARN: Slot ID %u, ep index %u has "
952 "stream IDs 1 to %u allocated, "
953 "but stream ID %u is requested.\n",
954 slot_id, ep_index,
955 ep->stream_info->num_streams - 1,
956 stream_id);
957 return NULL;
958}
959
919/* 960/*
920 * Remove the URB's TD from the endpoint ring. This may cause the HC to stop 961 * Remove the URB's TD from the endpoint ring. This may cause the HC to stop
921 * USB transfers, potentially stopping in the middle of a TRB buffer. The HC 962 * USB transfers, potentially stopping in the middle of a TRB buffer. The HC
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index e1383d91468b..9fe95c4e2a56 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1344,11 +1344,6 @@ void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci,
1344struct xhci_ring *xhci_dma_to_transfer_ring( 1344struct xhci_ring *xhci_dma_to_transfer_ring(
1345 struct xhci_virt_ep *ep, 1345 struct xhci_virt_ep *ep,
1346 u64 address); 1346 u64 address);
1347struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci,
1348 struct urb *urb);
1349struct xhci_ring *xhci_triad_to_transfer_ring(struct xhci_hcd *xhci,
1350 unsigned int slot_id, unsigned int ep_index,
1351 unsigned int stream_id);
1352struct xhci_ring *xhci_stream_id_to_ring( 1347struct xhci_ring *xhci_stream_id_to_ring(
1353 struct xhci_virt_device *dev, 1348 struct xhci_virt_device *dev,
1354 unsigned int ep_index, 1349 unsigned int ep_index,