diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-09-19 14:17:40 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-09-19 14:17:40 +0000 |
commit | 4a43e81118fca43a1a139c6a94ee726ce4fb7b05 (patch) | |
tree | 7af04b69fd72631288c061db0084796884114e09 | |
parent | f6d42e679369f55c11463ba8d76dc0c1c8b15d07 (diff) | |
download | xen-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.c | 45 |
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; } |