* [PATCH v3] USB: HID: random timeout failures tackle try.
@ 2020-02-04 13:15 Lauri Jakku
2020-02-04 13:53 ` Greg KH
2020-02-04 16:52 ` kbuild test robot
0 siblings, 2 replies; 3+ messages in thread
From: Lauri Jakku @ 2020-02-04 13:15 UTC (permalink / raw)
To: oneukum, benjamin.tissoires
Cc: jikos, linux-input, gregkh, linux-usb, Lauri Jakku
There is multiple reports of random behaviour of USB HID devices.
I have mouse that acts sometimes quite randomly, I debugged with
logs others have published: that there is HW timeouts that leave
device in state that it is errorneus.
To fix this, I introduce retry mechanism in root of USB HID drivers.
Fix does not slow down operations at all if there is no -ETIMEDOUT
got from control message sending.
If there is one, then sleep 20ms and try again. Retry count is 20
witch translates maximium of 400ms before giving up. If the 400ms
boundary is reached the HW is really bad.
JUST to be clear:
This does not make USB HID devices to sleep anymore than
before, if all is golden and no timeouts are got.
Why modify usb-hid-core: No need to modify driver by driver.
At this time i do not know all the USB HID devices that timeouts,
but what i've researched, there are issues.
Timeout given is divided by 100, but taken care that it is always
at least 10ms.
so total time in common worst-case-scenario is:
sleep of 20ms + common timeout divided by 100 (50ms) makes
70ms per loop, 20 loops => 1.4sec .
Signed-off-by: Lauri Jakku <lja@iki.fi>
---
drivers/usb/core/message.c | 55 ++++++++++++++++++++++++++++++++++----
1 file changed, 50 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 5adf489428aa..614c762989ab 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -20,6 +20,7 @@
#include <linux/usb/hcd.h> /* for usbcore internals */
#include <linux/usb/of.h>
#include <asm/byteorder.h>
+#include <linux/errno.h>
#include "usb.h"
@@ -137,7 +138,10 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
__u16 size, int timeout)
{
struct usb_ctrlrequest *dr;
- int ret;
+ int ret = -ETIMEDOUT;
+
+ /* retry_cnt * 20ms, max retry time set to 400ms */
+ int retry_cnt = 20;
dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
if (!dr)
@@ -149,11 +153,52 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
dr->wIndex = cpu_to_le16(index);
dr->wLength = cpu_to_le16(size);
- ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
+ do {
+ ret = usb_internal_control_msg(dev,
+ pipe,
+ dr,
+ data,
+ size,
+ timeout);
+
+ /*
+ * Linger a bit, prior to the next control message
+ * or if return value is timeout, but do try few
+ * times (max 400ms) before quitting. Adapt timeout
+ * to be smaller when we have timeout'd first time.
+ */
+ if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG)
+ msleep(200);
+ else if (ret == -ETIMEDOUT) {
+ static timeout_happened = 0;
+
+ if ( ! timeout_happened ) {
+ timeout_happened = 1;
+
+ /*
+ * If timeout is given, divide it
+ * by 100, if not, put 10ms timeout.
+ *
+ * Then safeguard: if timeout is under
+ * 10ms, make timeout to be 10ms.
+ */
+
+ if (timeout > 0)
+ timeout /= 100;
+ else
+ timeout = 10;
+
+ if (timeout < 10)
+ timeout = 10;
+
+ }
+
+ msleep(20);
+ }
+
+ /* Loop while timeout, max loops: retry_cnt times. */
+ } while ((retry_cnt-- > 0) && (ret == -ETIMEDOUT));
- /* Linger a bit, prior to the next control message. */
- if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG)
- msleep(200);
kfree(dr);
--
2.25.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v3] USB: HID: random timeout failures tackle try.
2020-02-04 13:15 [PATCH v3] USB: HID: random timeout failures tackle try Lauri Jakku
@ 2020-02-04 13:53 ` Greg KH
2020-02-04 16:52 ` kbuild test robot
1 sibling, 0 replies; 3+ messages in thread
From: Greg KH @ 2020-02-04 13:53 UTC (permalink / raw)
To: Lauri Jakku; +Cc: oneukum, benjamin.tissoires, jikos, linux-input, linux-usb
On Tue, Feb 04, 2020 at 03:15:56PM +0200, Lauri Jakku wrote:
> There is multiple reports of random behaviour of USB HID devices.
>
> I have mouse that acts sometimes quite randomly, I debugged with
> logs others have published: that there is HW timeouts that leave
> device in state that it is errorneus.
>
> To fix this, I introduce retry mechanism in root of USB HID drivers.
>
> Fix does not slow down operations at all if there is no -ETIMEDOUT
> got from control message sending.
>
> If there is one, then sleep 20ms and try again. Retry count is 20
> witch translates maximium of 400ms before giving up. If the 400ms
> boundary is reached the HW is really bad.
>
> JUST to be clear:
> This does not make USB HID devices to sleep anymore than
> before, if all is golden and no timeouts are got.
>
> Why modify usb-hid-core: No need to modify driver by driver.
> At this time i do not know all the USB HID devices that timeouts,
> but what i've researched, there are issues.
>
> Timeout given is divided by 100, but taken care that it is always
> at least 10ms.
>
> so total time in common worst-case-scenario is:
>
> sleep of 20ms + common timeout divided by 100 (50ms) makes
> 70ms per loop, 20 loops => 1.4sec .
>
> Signed-off-by: Lauri Jakku <lja@iki.fi>
> ---
> drivers/usb/core/message.c | 55 ++++++++++++++++++++++++++++++++++----
> 1 file changed, 50 insertions(+), 5 deletions(-)
What changed from v1 and v2?
That always has to be described below the --- line, as documented, to
give us a chance to understand what is happening here and why this is a
new version.
Please fix up and send a v4.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v3] USB: HID: random timeout failures tackle try.
2020-02-04 13:15 [PATCH v3] USB: HID: random timeout failures tackle try Lauri Jakku
2020-02-04 13:53 ` Greg KH
@ 2020-02-04 16:52 ` kbuild test robot
1 sibling, 0 replies; 3+ messages in thread
From: kbuild test robot @ 2020-02-04 16:52 UTC (permalink / raw)
To: Lauri Jakku
Cc: kbuild-all, oneukum, benjamin.tissoires, jikos, linux-input,
gregkh, linux-usb, Lauri Jakku
[-- Attachment #1: Type: text/plain, Size: 4857 bytes --]
Hi Lauri,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on usb/usb-testing]
[also build test ERROR on v5.5 next-20200204]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Lauri-Jakku/USB-HID-random-timeout-failures-tackle-try/20200204-232348
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
config: x86_64-defconfig (attached as .config)
compiler: gcc-7 (Debian 7.5.0-3) 7.5.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
drivers/usb/core/message.c: In function 'usb_control_msg':
>> drivers/usb/core/message.c:173:11: error: type defaults to 'int' in declaration of 'timeout_happened' [-Werror=implicit-int]
static timeout_happened = 0;
^~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +173 drivers/usb/core/message.c
108
109 /**
110 * usb_control_msg - Builds a control urb, sends it off and waits for completion
111 * @dev: pointer to the usb device to send the message to
112 * @pipe: endpoint "pipe" to send the message to
113 * @request: USB message request value
114 * @requesttype: USB message request type value
115 * @value: USB message value
116 * @index: USB message index value
117 * @data: pointer to the data to send
118 * @size: length in bytes of the data to send
119 * @timeout: time in msecs to wait for the message to complete before timing
120 * out (if 0 the wait is forever)
121 *
122 * Context: !in_interrupt ()
123 *
124 * This function sends a simple control message to a specified endpoint and
125 * waits for the message to complete, or timeout.
126 *
127 * Don't use this function from within an interrupt context. If you need
128 * an asynchronous message, or need to send a message from within interrupt
129 * context, use usb_submit_urb(). If a thread in your driver uses this call,
130 * make sure your disconnect() method can wait for it to complete. Since you
131 * don't have a handle on the URB used, you can't cancel the request.
132 *
133 * Return: If successful, the number of bytes transferred. Otherwise, a negative
134 * error number.
135 */
136 int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
137 __u8 requesttype, __u16 value, __u16 index, void *data,
138 __u16 size, int timeout)
139 {
140 struct usb_ctrlrequest *dr;
141 int ret = -ETIMEDOUT;
142
143 /* retry_cnt * 20ms, max retry time set to 400ms */
144 int retry_cnt = 20;
145
146 dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
147 if (!dr)
148 return -ENOMEM;
149
150 dr->bRequestType = requesttype;
151 dr->bRequest = request;
152 dr->wValue = cpu_to_le16(value);
153 dr->wIndex = cpu_to_le16(index);
154 dr->wLength = cpu_to_le16(size);
155
156 do {
157 ret = usb_internal_control_msg(dev,
158 pipe,
159 dr,
160 data,
161 size,
162 timeout);
163
164 /*
165 * Linger a bit, prior to the next control message
166 * or if return value is timeout, but do try few
167 * times (max 400ms) before quitting. Adapt timeout
168 * to be smaller when we have timeout'd first time.
169 */
170 if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG)
171 msleep(200);
172 else if (ret == -ETIMEDOUT) {
> 173 static timeout_happened = 0;
174
175 if ( ! timeout_happened ) {
176 timeout_happened = 1;
177
178 /*
179 * If timeout is given, divide it
180 * by 100, if not, put 10ms timeout.
181 *
182 * Then safeguard: if timeout is under
183 * 10ms, make timeout to be 10ms.
184 */
185
186 if (timeout > 0)
187 timeout /= 100;
188 else
189 timeout = 10;
190
191 if (timeout < 10)
192 timeout = 10;
193
194 }
195
196 msleep(20);
197 }
198
199 /* Loop while timeout, max loops: retry_cnt times. */
200 } while ((retry_cnt-- > 0) && (ret == -ETIMEDOUT));
201
202
203 kfree(dr);
204
205 return ret;
206 }
207 EXPORT_SYMBOL_GPL(usb_control_msg);
208
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28831 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-02-04 16:52 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-04 13:15 [PATCH v3] USB: HID: random timeout failures tackle try Lauri Jakku
2020-02-04 13:53 ` Greg KH
2020-02-04 16:52 ` kbuild test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).