Discussion:
[PATCH] msleep() with hrtimers
Andrew Morton
2007-08-09 07:16:40 UTC
Permalink
Here's the second (and probably final) posting of the msleep() with
hrtimers patch. The problem being addressed here is that the current
msleep() will stop for a minimum of two jiffies, meaning that, on a
HZ=100 system, msleep(1) delays for for about 20ms. In a driver with
one such delay for each of 150 or so register setting operations, the
extra time adds up to a few seconds.
This patch addresses the situation by using hrtimers. On tickless
systems with working timers, msleep(1) now sleeps for 1ms, even with
HZ=100.
Most comments last time were favorable. The one dissenter was Roman,
who worries about the overhead of using hrtimers for this operation; my
understanding is that he would rather see a really_msleep() function for
those who actually want millisecond resolution. I'm not sure how to
characterize what the cost could be, but it can only be buried by the
fact that every call sleeps for some number of milliseconds. On my
system, the several hundred total msleep() calls can't cause any real
overhead, and almost all happen at initialization time.
I still think it would be useful for msleep() to do what it says it does
and not vastly oversleep with small arguments. A quick grep turns up
450 msleep(1) calls in the current mainline. Andrew, if you agree, can
you drop this into -mm? If not, I guess I'll let it go.
jon
---
Use hrtimers so that msleep() sleeps for the requested time
Current msleep() snoozes for at least two jiffies, causing msleep(1) to
sleep for at least 20ms on HZ=100 systems. Using hrtimers allows
msleep() to sleep for something much closer to the requested time.
--- 2.6.23-rc1/kernel/timer.c.orig 2007-08-02 13:45:20.000000000 -0600
+++ 2.6.23-rc1/kernel/timer.c 2007-08-03 12:34:48.000000000 -0600
@@ -1349,18 +1349,43 @@ void __init init_timers(void)
open_softirq(TIMER_SOFTIRQ, run_timer_softirq, NULL);
}
+
+
+
+static void do_msleep(unsigned int msecs, struct hrtimer_sleeper *sleeper,
+ int sigs)
+{
+ enum hrtimer_mode mode = HRTIMER_MODE_REL;
+ int state = sigs ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
+
+ /*
+ * This is really just a reworked and simplified version
+ * of do_nanosleep().
+ */
+ hrtimer_init(&sleeper->timer, CLOCK_MONOTONIC, mode);
+ sleeper->timer.expires = ktime_set(0, msecs*NSEC_PER_MSEC);
+ hrtimer_init_sleeper(sleeper, current);
+
+ do {
+ set_current_state(state);
+ hrtimer_start(&sleeper->timer, sleeper->timer.expires, mode);
+ if (sleeper->task)
+ schedule();
+ hrtimer_cancel(&sleeper->timer);
+ mode = HRTIMER_MODE_ABS;
+ } while (sleeper->task && !(sigs && signal_pending(current)));
+}
+
/**
* msleep - sleep safely even with waitqueue interruptions
*/
void msleep(unsigned int msecs)
{
- unsigned long timeout = msecs_to_jiffies(msecs) + 1;
+ struct hrtimer_sleeper sleeper;
- while (timeout)
- timeout = schedule_timeout_uninterruptible(timeout);
+ do_msleep(msecs, &sleeper, 0);
}
-
EXPORT_SYMBOL(msleep);
/**
@@ -1369,11 +1394,15 @@ EXPORT_SYMBOL(msleep);
*/
unsigned long msleep_interruptible(unsigned int msecs)
{
- unsigned long timeout = msecs_to_jiffies(msecs) + 1;
+ struct hrtimer_sleeper sleeper;
+ ktime_t left;
- while (timeout && !signal_pending(current))
- timeout = schedule_timeout_interruptible(timeout);
- return jiffies_to_msecs(timeout);
-}
+ do_msleep(msecs, &sleeper, 1);
+ if (!sleeper.task)
+ return 0;
+ left = ktime_sub(sleeper.timer.expires,
+ sleeper.timer.base->get_time());
+ return max(((long) ktime_to_ns(left))/NSEC_PER_MSEC, 1L);
+}
EXPORT_SYMBOL(msleep_interruptible);
This failed the Vaio test. I guess it triggered a USB bug.

With this patch applied, when I hotplug my wireless mouse, the little LED
on the mouse comes on for a second or so then goes out and no pointy clicky
for me.

It says:

[ 152.481522] usb 1-1: new low speed USB device using uhci_hcd and address 2


Without this patch applied, I get

[ 195.935445] usb 2-1: new low speed USB device using uhci_hcd and address 2
[ 196.116183] usb 2-1: configuration #1 chosen from 1 choice
[ 196.198362] input: Microsoft Microsoft Wireless Optical Mouse 1.00 as /class/input/input7
[ 196.223724] input: USB HID v1.11 Mouse [Microsoft Microsoft Wireless Optical Mouse 1.00] on usb-0000:00:1d.1-1
[ 196.224570] usb 2-1: new device found, idVendor=045e, idProduct=00e1
[ 196.224579] usb 2-1: new device strings: Mfr=1, Product=2, SerialNumber=0
[ 196.224585] usb 2-1: Product: Microsoft Wireless Optical Mouse 1.00
[ 196.224590] usb 2-1: Manufacturer: Microsoft

and lots of pointy clickiness.

I would assume that there is some msleep() in USB which is too short, and
the present wild rounding-up which msleep() does covered up the
incorrectly-chosen sleep duration.

I'm using HZ=250 (http://userweb.kernel.org/~akpm/config-sony.txt) and it
could well be that the mouse would fail just by going to HZ=1000, but I
didn't bother testing that.

Could one of the USB developers please suggest which msleep()(s) I should
start looking at?

Thanks.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
linux-usb-***@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
Alan Stern
2007-08-09 15:08:03 UTC
Permalink
Post by Andrew Morton
This failed the Vaio test. I guess it triggered a USB bug.
With this patch applied, when I hotplug my wireless mouse, the little LED
on the mouse comes on for a second or so then goes out and no pointy clicky
for me.
[ 152.481522] usb 1-1: new low speed USB device using uhci_hcd and address 2
Without this patch applied, I get
[ 195.935445] usb 2-1: new low speed USB device using uhci_hcd and address 2
[ 196.116183] usb 2-1: configuration #1 chosen from 1 choice
[ 196.198362] input: Microsoft Microsoft Wireless Optical Mouse 1.00 as /class/input/input7
[ 196.223724] input: USB HID v1.11 Mouse [Microsoft Microsoft Wireless Optical Mouse 1.00] on usb-0000:00:1d.1-1
[ 196.224570] usb 2-1: new device found, idVendor=045e, idProduct=00e1
[ 196.224579] usb 2-1: new device strings: Mfr=1, Product=2, SerialNumber=0
[ 196.224585] usb 2-1: Product: Microsoft Wireless Optical Mouse 1.00
[ 196.224590] usb 2-1: Manufacturer: Microsoft
and lots of pointy clickiness.
I would assume that there is some msleep() in USB which is too short, and
the present wild rounding-up which msleep() does covered up the
incorrectly-chosen sleep duration.
I'm using HZ=250 (http://userweb.kernel.org/~akpm/config-sony.txt) and it
could well be that the mouse would fail just by going to HZ=1000, but I
didn't bother testing that.
Could one of the USB developers please suggest which msleep()(s) I should
start looking at?
It could be one of the calls in drivers/usb/core/hub.c, however almost
all of them are at least 10 ms already. There's a 0-ms msleep near the
start of hub_port_wait_reset() which might cause problems.

It will be easier to pin down the culprit if you turn on
CONFIG_USB_DEBUG.

Alan Stern


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
linux-usb-***@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
David Brownell
2008-01-07 21:38:08 UTC
Permalink
Post by Andrew Morton
Here's the second (and probably final) posting of the msleep() with
hrtimers patch. The problem being addressed here is that the current
msleep() will stop for a minimum of two jiffies, meaning that, on a
HZ=100 system, msleep(1) delays for for about 20ms. In a driver with
one such delay for each of 150 or so register setting operations, the
extra time adds up to a few seconds.
This patch addresses the situation by using hrtimers. On tickless
systems with working timers, msleep(1) now sleeps for 1ms, even with
HZ=100.
For what it's worth, I've been using this on a variety of systems since
August, without even one observed problem. I rather like the idea of
an msleep() that really does what it claims to do, instead of wasting
extra time!
Post by Andrew Morton
...
This failed the Vaio test. I guess it triggered a USB bug.
Does it still fail?
Post by Andrew Morton
With this patch applied, when I hotplug my wireless mouse, the little LED
on the mouse comes on for a second or so then goes out and no pointy clicky
for me.
[ 152.481522] usb 1-1: new low speed USB device using uhci_hcd and address 2
Without this patch applied, I get
[ 195.935445] usb 2-1: new low speed USB device using uhci_hcd and address 2
[ 196.116183] usb 2-1: configuration #1 chosen from 1 choice
[ 196.198362] input: Microsoft Microsoft Wireless Optical Mouse 1.00 as /class/input/input7
i ...
and lots of pointy clickiness.
In short, the enumeration of this device broke. That's all handled
by khubd in usbcore. But without enabing USB_DEBUG we can't very
well know *how* it broke.

Now one reason this failure is interesting is that there are other
cases with mysterious enumeration failures ... often involving EHCI
for some reason. And my brain couples many of these to bugfixes we
made in the enumeration logic a long time ago, which involved changing
timings (and some other stuff). We started to get a lot more reports
about such failures about a release after those fixes...

Which makes me suspect that once this particular enumeration timing
problem got fixed, some other stuff might behave better too. And if
it didn't behave better, then we'd at least have a better handle on
which enumeration delays seem to trigger problematic device behavior.
Post by Andrew Morton
I would assume that there is some msleep() in USB which is too short, and
the present wild rounding-up which msleep() does covered up the
incorrectly-chosen sleep duration.
I'm using HZ=250 (http://userweb.kernel.org/~akpm/config-sony.txt) and it
could well be that the mouse would fail just by going to HZ=1000, but I
didn't bother testing that.
Could one of the USB developers please suggest which msleep()(s) I should
start looking at?
If there was followup to the "what do the logs show with CONFIG_USB_DEBUG"
response, I didn't see it.

- Dave


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
linux-usb-***@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
Andrew Morton
2008-01-07 22:03:03 UTC
Permalink
On Mon, 7 Jan 2008 13:38:08 -0800
Post by David Brownell
Post by Andrew Morton
Here's the second (and probably final) posting of the msleep() with
hrtimers patch. The problem being addressed here is that the current
msleep() will stop for a minimum of two jiffies, meaning that, on a
HZ=100 system, msleep(1) delays for for about 20ms. In a driver with
one such delay for each of 150 or so register setting operations, the
extra time adds up to a few seconds.
This patch addresses the situation by using hrtimers. On tickless
systems with working timers, msleep(1) now sleeps for 1ms, even with
HZ=100.
For what it's worth, I've been using this on a variety of systems since
August, without even one observed problem. I rather like the idea of
an msleep() that really does what it claims to do, instead of wasting
extra time!
Post by Andrew Morton
...
This failed the Vaio test. I guess it triggered a USB bug.
Does it still fail?
It did on 28 Nov: http://lkml.org/lkml/2007/11/28/65
Post by David Brownell
If there was followup to the "what do the logs show with CONFIG_USB_DEBUG"
response, I didn't see it.
Sigh. Will add it to the todo list (after the 852 emails in my to-apply
folder) but I'll probably need reminding.


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
linux-usb-***@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
David Brownell
2008-01-07 22:51:31 UTC
Permalink
Post by Andrew Morton
Post by David Brownell
Post by Andrew Morton
This failed the Vaio test. I guess it triggered a USB bug.
Does it still fail?
It did on 28 Nov: http://lkml.org/lkml/2007/11/28/65
Which, I see, has a patch adding set_current_state(TASK_RUNNING) ...
I'll merge that into my copy, just in case.
Post by Andrew Morton
Post by David Brownell
If there was followup to the "what do the logs show with CONFIG_USB_DEBUG"
response, I didn't see it.
Sigh. Will add it to the todo list (after the 852 emails in my to-apply
folder) but I'll probably need reminding.
Only 852 patches-to-apply? Everyone really *did* go on vacation
last month. Though somehow the thought of that large a patch queue
doesn't seem entirely like an incentive ... ;)

One of the perils of USB is that so many of the failures never seem
to kick in on hardware that the developers have ready access to.
That gets frustrating all around.

And no doubt by the time your Viao-of-Death works well with everything,
likely some other system will show up as a Source Of Many Problems!

- Dave

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
linux-usb-***@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
Andrew Morton
2008-01-07 22:56:46 UTC
Permalink
On Mon, 7 Jan 2008 14:51:31 -0800
Post by David Brownell
And no doubt by the time your Viao-of-Death works well with everything,
likely some other system will show up as a Source Of Many Problems!
My new thinkpad t61p has so many failures I hate to even start
thinking about it.

- random usb hotplugging failures
- continuous and varied suspend-to-ram failures
- ditto suspend-to-disk
- really slow suspend (and getting slower afaict)
- various scroggages of video display
- various alsa failures
- recently-busted backlight brightness control
- other stuff I've forgotten about

it is quite unimpressive. Surely I'm not the only person who
is seeing all of this :(

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
linux-usb-***@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Loading...