1. 28 12月, 2020 1 次提交
  2. 09 12月, 2020 1 次提交
    • T
      usb: xhci: Use temporary buffer to consolidate SG · 2017a1e5
      Tejas Joglekar 提交于
      The Synopsys xHC has an internal TRB cache of size TRB_CACHE_SIZE for
      each endpoint. The default value for TRB_CACHE_SIZE is 16 for SS and 8
      for HS. The controller loads and updates the TRB cache from the transfer
      ring in system memory whenever the driver issues a start transfer or
      update transfer command.
      
      For chained TRBs, the Synopsys xHC requires that the total amount of
      bytes for all TRBs loaded in the TRB cache be greater than or equal to 1
      MPS. Or the chain ends within the TRB cache (with a last TRB).
      
      If this requirement is not met, the controller will not be able to send
      or receive a packet and it will hang causing a driver timeout and error.
      
      This can be a problem if a class driver queues SG requests with many
      small-buffer entries. The XHCI driver will create a chained TRB for each
      entry which may trigger this issue.
      
      This patch adds logic to the XHCI driver to detect and prevent this from
      happening.
      
      For every (TRB_CACHE_SIZE - 2), we check the total buffer size of
      the SG list and if the last window of (TRB_CACHE_SIZE - 2) SG list length
      and we don't make up at least 1 MPS, we create a temporary buffer to
      consolidate full SG list into the buffer.
      
      We check at (TRB_CACHE_SIZE - 2) window because it is possible that there
      would be a link and/or event data TRB that take up to 2 of the cache
      entries.
      
      We discovered this issue with devices on other platforms but have not
      yet come across any device that triggers this on Linux. But it could be
      a real problem now or in the future. All it takes is N number of small
      chained TRBs. And other instances of the Synopsys IP may have smaller
      values for the TRB_CACHE_SIZE which would exacerbate the problem.
      Signed-off-by: NTejas Joglekar <joglekar@synopsys.com>
      Signed-off-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Link: https://lore.kernel.org/r/20201208092912.1773650-3-mathias.nyman@linux.intel.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      2017a1e5
  3. 29 10月, 2020 1 次提交
  4. 28 10月, 2020 1 次提交
  5. 20 9月, 2020 3 次提交
  6. 24 8月, 2020 1 次提交
  7. 23 8月, 2020 1 次提交
  8. 09 7月, 2020 1 次提交
  9. 24 6月, 2020 3 次提交
  10. 21 4月, 2020 1 次提交
  11. 13 3月, 2020 1 次提交
  12. 11 12月, 2019 2 次提交
  13. 16 11月, 2019 1 次提交
    • S
      usb: host: xhci: Support running urb giveback in tasklet context · 36dc0165
      Suwan Kim 提交于
      Patch "USB: HCD: support giveback of URB in tasklet context"[1]
      introduced giveback of urb in tasklet context. [1] This patch was
      applied to ehci but not xhci. [2] This patch significantly reduces
      the hard irq time of xhci. Especially for uvc driver, the hard irq
      including the uvc completion function runs quite long but applying
      this patch reduces the hard irq time of xhci.
      
      I have tested four SS devices to check if performance degradation
      occurs when urb completion functions run in the tasklet context.
      
      As a result of the test, all devices works well and shows very
      similar performance with the upstream kernel. Moreover, usb ethernet
      adapter show better performance than the upstream kernel about 5% for
      RX and 2% for TX. Four SS devices is as follows.
      
      SS devices for test
      
      1. WD My Passport 2TB (external hard drive)
      2. Sandisk Ultra Flair USB 3.0 32GB
      3. Logitech Brio webcam
      4. Iptime 1gigabit ethernet adapter (Mediatek RTL8153)
      
      Test description
      
      1. Mass storage (hard drive) performance test
      - run below command 10 times and compute the average performance
      
          dd if=/dev/sdN iflag=direct of=/dev/null bs=1G count=1
      
      2. Mass storage (flash memory) performance test
      - run below command 10 times and compute the average performance
      
          dd if=/dev/sdN iflag=direct of=/dev/null bs=1G count=1
      
      3. Webcam streaming performance test
      - run simple capture program and get the average frame rate per second
      - capture 1500 frames
      - program link
      
          https://github.com/asfaca/Webcam-performance-analyzing-tool
      
      - video resolution : 4096 X 2160 (4K) at 30 or 24 fps
      - device (Logitech Brio) spec url for the highest resolution and fps
      
          https://support.logitech.com/en_gb/product/brio-stream/specs
      
      4. USB Ethernet adapter performance test
      - directly connect two linux machines with ethernet cable
      - run pktgen of linux kernel and send 1500 bytes packets
      - run vnstat to measure the network bandwidth for 180 seconds
      
      Test machine
      
      - CPU : Intel i5-7600 @ 3.5GHz
      
      Test results
      
      1. Mass storage (hard drive) performance test
      
                  WD My Passport 2TB (external hard drive)
      --------------------------------------------------------------------
          xhci without tasklet        |          xhci with tasklet
      --------------------------------------------------------------------
               103.667MB/s            |            103.692MB/s
      --------------------------------------------------------------------
      
      2. Mass storage (flash memory) performance test
      
                     Sandisk Ultra Flair USB 3.0 32GB
      --------------------------------------------------------------------
          xhci without tasklet        |          xhci with tasklet
      --------------------------------------------------------------------
               129.727MB/s            |            130.2MB/s
      --------------------------------------------------------------------
      
      3. Webcam streaming performance test
      
                           Logitech Brio webcam
      --------------------------------------------------------------------
          xhci without tasklet        |          xhci with tasklet
      --------------------------------------------------------------------
                26.4451 fps           |            26.3949 fps
      --------------------------------------------------------------------
      
      4. USB Ethernet adapter performance test
      
            Iptime 1gigabit ethernet adapter (Mediatek RTL8153)
      --------------------------------------------------------------------
          xhci without tasklet        |          xhci with tasklet
      --------------------------------------------------------------------
      RX      933.86 Mbit/s           |            983.86 Mbit/s
      --------------------------------------------------------------------
      TX      830.18 Mbit/s           |            882.75 Mbit/s
      --------------------------------------------------------------------
      
      [1], https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=94dfd7edfd5c9b605caf7b562de7a813d216e011
      [2], https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=428aac8a81058e2303677a8fbf26670229e51d3aSigned-off-by: NSuwan Kim <suwan.kim027@gmail.com>
      Signed-off-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Link: https://lore.kernel.org/r/1573836603-10871-4-git-send-email-mathias.nyman@linux.intel.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      36dc0165
  14. 29 10月, 2019 1 次提交
  15. 04 10月, 2019 7 次提交
  16. 03 9月, 2019 1 次提交
  17. 22 8月, 2019 1 次提交
  18. 03 8月, 2019 1 次提交
  19. 19 6月, 2019 2 次提交
    • M
      xhci: detect USB 3.2 capable host controllers correctly · ddd57980
      Mathias Nyman 提交于
      USB 3.2 capability in a host can be detected from the
      xHCI Supported Protocol Capability major and minor revision fields.
      
      If major is 0x3 and minor 0x20 then the host is USB 3.2 capable.
      
      For USB 3.2 capable hosts set the root hub lane count to 2.
      
      The Major Revision and Minor Revision fields contain a BCD version number.
      The value of the Major Revision field is JJh and the value of the Minor
      Revision field is MNh for version JJ.M.N, where JJ = major revision number,
      M - minor version number, N = sub-minor version number,
      e.g. version 3.1 is represented with a value of 0310h.
      
      Also fix the extra whitespace printed out when announcing regular
      SuperSpeed hosts.
      
      Cc: <stable@vger.kernel.org> # v4.18+
      Signed-off-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      ddd57980
    • M
      usb: xhci: Don't try to recover an endpoint if port is in error state. · b8c3b718
      Mathias Nyman 提交于
      A USB3 device needs to be reset and re-enumarated if the port it
      connects to goes to a error state, with link state inactive.
      
      There is no use in trying to recover failed transactions by resetting
      endpoints at this stage. Tests show that in rare cases, after multiple
      endpoint resets of a roothub port the whole host controller might stop
      completely.
      
      Several retries to recover from transaction error can happen as
      it can take a long time before the hub thread discovers the USB3
      port error and inactive link.
      
      We can't reliably detect the port error from slot or endpoint context
      due to a limitation in xhci, see xhci specs section 4.8.3:
      "There are several cases where the EP State field in the Output
      Endpoint Context may not reflect the current state of an endpoint"
      and
      "Software should maintain an accurate value for EP State, by tracking it
      with an internal variable that is driven by Events and Doorbell accesses"
      
      Same appears to be true for slot state.
      
      set a flag to the corresponding slot if a USB3 roothub port link goes
      inactive to prevent both queueing new URBs and resetting endpoints.
      Reported-by: NRapolu Chiranjeevi <chiranjeevi.rapolu@intel.com>
      Tested-by: NRapolu Chiranjeevi <chiranjeevi.rapolu@intel.com>
      Cc: <stable@vger.kernel.org>
      Signed-off-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      b8c3b718
  20. 05 6月, 2019 2 次提交
    • J
      usb: xhci: Add Clear_TT_Buffer · ef513be0
      Jim Lin 提交于
      USB 2.0 specification chapter 11.17.5 says "as part of endpoint halt
      processing for full-/low-speed endpoints connected via a TT, the host
      software must use the Clear_TT_Buffer request to the TT to ensure
      that the buffer is not in the busy state".
      
      In our case, a full-speed speaker (ConferenceCam) is behind a high-
      speed hub (ConferenceCam Connect), sometimes once we get STALL on a
      request we may continue to get STALL with the folllowing requests,
      like Set_Interface.
      
      Here we invoke usb_hub_clear_tt_buffer() to send Clear_TT_Buffer
      request to the hub of the device for the following Set_Interface
      requests to the device to get ACK successfully.
      Signed-off-by: NJim Lin <jilin@nvidia.com>
      Acked-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      ef513be0
    • J
      usb: Add devaddr in struct usb_device · 4998f1ef
      Jim Lin 提交于
      The Clear_TT_Buffer request sent to the hub includes the address of
      the LS/FS child device in wValue field. usb_hub_clear_tt_buffer()
      uses udev->devnum to set the address wValue. This won't work for
      devices connected to xHC.
      
      For other host controllers udev->devnum is the same as the address of
      the usb device, chosen and set by usb core. With xHC the controller
      hardware assigns the address, and won't be the same as devnum.
      
      Here we add devaddr in "struct usb_device" for
      usb_hub_clear_tt_buffer() to use.
      Signed-off-by: NJim Lin <jilin@nvidia.com>
      Acked-by: NAlan Stern <stern@rowland.harvard.edu>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      4998f1ef
  21. 22 5月, 2019 2 次提交
    • A
      xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic() · f7fac17c
      Andrey Smirnov 提交于
      Xhci_handshake() implements the algorithm already captured by
      readl_poll_timeout_atomic(). Convert the former to use the latter to
      avoid repetition.
      
      Turned out this patch also fixes a bug on the AMD Stoneyridge platform
      where usleep(1) sometimes takes over 10ms.
      This means a 5 second timeout can easily take over 15 seconds which will
      trigger the watchdog and reboot the system.
      
      [Add info about patch fixing a bug to commit message -Mathias]
      Signed-off-by: NAndrey Smirnov <andrew.smirnov@gmail.com>
      Tested-by: NRaul E Rangel <rrangel@chromium.org>
      Reviewed-by: NRaul E Rangel <rrangel@chromium.org>
      Cc: <stable@vger.kernel.org>
      Signed-off-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f7fac17c
    • C
      usb: xhci: avoid null pointer deref when bos field is NULL · 7aa1bb2f
      Carsten Schmid 提交于
      With defective USB sticks we see the following error happen:
      usb 1-3: new high-speed USB device number 6 using xhci_hcd
      usb 1-3: device descriptor read/64, error -71
      usb 1-3: device descriptor read/64, error -71
      usb 1-3: new high-speed USB device number 7 using xhci_hcd
      usb 1-3: device descriptor read/64, error -71
      usb 1-3: unable to get BOS descriptor set
      usb 1-3: New USB device found, idVendor=0781, idProduct=5581
      usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
      ...
      BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
      
      This comes from the following place:
      [ 1660.215380] IP: xhci_set_usb2_hardware_lpm+0xdf/0x3d0 [xhci_hcd]
      [ 1660.222092] PGD 0 P4D 0
      [ 1660.224918] Oops: 0000 [#1] PREEMPT SMP NOPTI
      [ 1660.425520] CPU: 1 PID: 38 Comm: kworker/1:1 Tainted: P     U  W  O    4.14.67-apl #1
      [ 1660.434277] Workqueue: usb_hub_wq hub_event [usbcore]
      [ 1660.439918] task: ffffa295b6ae4c80 task.stack: ffffad4580150000
      [ 1660.446532] RIP: 0010:xhci_set_usb2_hardware_lpm+0xdf/0x3d0 [xhci_hcd]
      [ 1660.453821] RSP: 0018:ffffad4580153c70 EFLAGS: 00010046
      [ 1660.459655] RAX: 0000000000000000 RBX: ffffa295b4d7c000 RCX: 0000000000000002
      [ 1660.467625] RDX: 0000000000000002 RSI: ffffffff984a55b2 RDI: ffffffff984a55b2
      [ 1660.475586] RBP: ffffad4580153cc8 R08: 0000000000d6520a R09: 0000000000000001
      [ 1660.483556] R10: ffffad4580a004a0 R11: 0000000000000286 R12: ffffa295b4d7c000
      [ 1660.491525] R13: 0000000000010648 R14: ffffa295a84e1800 R15: 0000000000000000
      [ 1660.499494] FS:  0000000000000000(0000) GS:ffffa295bfc80000(0000) knlGS:0000000000000000
      [ 1660.508530] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [ 1660.514947] CR2: 0000000000000008 CR3: 000000025a114000 CR4: 00000000003406a0
      [ 1660.522917] Call Trace:
      [ 1660.525657]  usb_set_usb2_hardware_lpm+0x3d/0x70 [usbcore]
      [ 1660.531792]  usb_disable_device+0x242/0x260 [usbcore]
      [ 1660.537439]  usb_disconnect+0xc1/0x2b0 [usbcore]
      [ 1660.542600]  hub_event+0x596/0x18f0 [usbcore]
      [ 1660.547467]  ? trace_preempt_on+0xdf/0x100
      [ 1660.552040]  ? process_one_work+0x1c1/0x410
      [ 1660.556708]  process_one_work+0x1d2/0x410
      [ 1660.561184]  ? preempt_count_add.part.3+0x21/0x60
      [ 1660.566436]  worker_thread+0x2d/0x3f0
      [ 1660.570522]  kthread+0x122/0x140
      [ 1660.574123]  ? process_one_work+0x410/0x410
      [ 1660.578792]  ? kthread_create_on_node+0x60/0x60
      [ 1660.583849]  ret_from_fork+0x3a/0x50
      [ 1660.587839] Code: 00 49 89 c3 49 8b 84 24 50 16 00 00 8d 4a ff 48 8d 04 c8 48 89 ca 4c 8b 10 45 8b 6a 04 48 8b 00 48 89 45 c0 49 8b 86 80 03 00 00 <48> 8b 40 08 8b 40 03 0f 1f 44 00 00 45 85 ff 0f 84 81 01 00 00
      [ 1660.608980] RIP: xhci_set_usb2_hardware_lpm+0xdf/0x3d0 [xhci_hcd] RSP: ffffad4580153c70
      [ 1660.617921] CR2: 0000000000000008
      
      Tracking this down shows that udev->bos is NULL in the following code:
      (xhci.c, in xhci_set_usb2_hardware_lpm)
      	field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);  <<<<<<< here
      
      	xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n",
      			enable ? "enable" : "disable", port_num + 1);
      
      	if (enable) {
      		/* Host supports BESL timeout instead of HIRD */
      		if (udev->usb2_hw_lpm_besl_capable) {
      			/* if device doesn't have a preferred BESL value use a
      			 * default one which works with mixed HIRD and BESL
      			 * systems. See XHCI_DEFAULT_BESL definition in xhci.h
      			 */
      			if ((field & USB_BESL_SUPPORT) &&
      			    (field & USB_BESL_BASELINE_VALID))
      				hird = USB_GET_BESL_BASELINE(field);
      			else
      				hird = udev->l1_params.besl;
      
      The failing case is when disabling LPM. So it is sufficient to avoid
      access to udev->bos by moving the instruction into the "enable" clause.
      
      Cc: Stable <stable@vger.kernel.org>
      Signed-off-by: NCarsten Schmid <carsten_schmid@mentor.com>
      Signed-off-by: NMathias Nyman <mathias.nyman@linux.intel.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      7aa1bb2f
  22. 27 4月, 2019 4 次提交
  23. 18 1月, 2019 1 次提交
    • G
      xhci: Use struct_size() in kzalloc() · da79ff6e
      Gustavo A. R. Silva 提交于
      One of the more common cases of allocation size calculations is finding the
      size of a structure that has a zero-sized array at the end, along with memory
      for some number of elements for that array. For example:
      
      struct foo {
          int stuff;
          void *entry[];
      };
      
      instance = kzalloc(sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL);
      
      Instead of leaving these open-coded and prone to type mistakes, we can now
      use the new struct_size() helper:
      
      instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL);
      
      This code was detected with the help of Coccinelle.
      Signed-off-by: NGustavo A. R. Silva <gustavo@embeddedor.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      da79ff6e