aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-09-19 14:17:40 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-09-19 14:17:40 +0000
commit4a43e81118fca43a1a139c6a94ee726ce4fb7b05 (patch)
tree7af04b69fd72631288c061db0084796884114e09
parentf6d42e679369f55c11463ba8d76dc0c1c8b15d07 (diff)
downloadxen-4a43e81118fca43a1a139c6a94ee726ce4fb7b05.tar.gz
xen-4a43e81118fca43a1a139c6a94ee726ce4fb7b05.tar.bz2
xen-4a43e81118fca43a1a139c6a94ee726ce4fb7b05.zip
bitkeeper revision 1.436.1.1 (3f6b10042XNDJJ-K-YoN8Em1IaZzdg)
schedule.c: Fix schedule_timeout to do the right thing with idle domains.
-rw-r--r--xen/common/schedule.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index d28b221c5f..616598a7a3 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -612,10 +612,13 @@ long schedule_timeout(long timeout)
{
struct timer_list timer;
unsigned long expire;
-
+
switch (timeout)
{
case MAX_SCHEDULE_TIMEOUT:
+ /* Sanity! This just wouldn't make sense. */
+ if ( is_idle_task(current) )
+ panic("Arbitrary sleep in idle task!");
/*
* These two special cases are useful to be comfortable in the caller.
* Nothing more. We could take MAX_SCHEDULE_TIMEOUT from one of the
@@ -624,6 +627,7 @@ long schedule_timeout(long timeout)
*/
schedule();
goto out;
+
default:
/*
* Another bit of PARANOID. Note that the retval will be 0 since no
@@ -644,17 +648,34 @@ long schedule_timeout(long timeout)
expire = timeout + jiffies;
- init_timer(&timer);
- timer.expires = expire;
- timer.data = (unsigned long) current;
- timer.function = process_timeout;
-
- add_timer(&timer);
- schedule();
- del_timer_sync(&timer);
-
- timeout = expire - jiffies;
-
+ if ( is_idle_task(current) )
+ {
+ /*
+ * If the idle task is calling in then it shouldn't ever sleep. We
+ * therefore force it to TASK_RUNNING here and busy-wait. We spin on
+ * schedule to give other domains a chance meanwhile.
+ */
+ set_current_state(TASK_RUNNING);
+ do {
+ schedule();
+ timeout = expire - jiffies;
+ }
+ while ( (timeout > 0) && is_idle_task(current) );
+ }
+ else
+ {
+ init_timer(&timer);
+ timer.expires = expire;
+ timer.data = (unsigned long) current;
+ timer.function = process_timeout;
+
+ add_timer(&timer);
+ schedule();
+ del_timer_sync(&timer);
+
+ timeout = expire - jiffies;
+ }
+
out:
return timeout < 0 ? 0 : timeout;
}