Re: [patch] schedule_timeout()

Andrea Arcangeli (andrea@e-mind.com)
Tue, 20 Oct 1998 12:01:50 +0200 (CEST)


On Mon, 19 Oct 1998, Andrea Arcangeli wrote:

>On Mon, 19 Oct 1998, Andrea Arcangeli wrote:
>
>>I should have cleaned my tree fine now. So now I produced a diff that
>>works fine here (btw, I just fixed all problems I got yesterday night).
>
>Now I fixed also the timer offset problem (thanks to Finn btw).
>
>I just converted my whole kernel to use schedule_timeout(timeout) and
>interruptible_sleep_on_timeout(&wait, TIMEOUT), and I am writing this
>while jiffies has just wrapped on my machine (it started from -120*HZ).
>Everything seems really stable here.

Everything still perfect here (and last night I had a load of 3 for one
hour without problems).

I improved a bit schedule_timeout(). The MAX_SCHEDULE_TIMEOUT exists only
to be more comfortable in the caller code. Really it means infinity so we
don' t need to set the timer and so waste time (or to return the timeout
decreased since infinity - (time passed in schedule_timeout) ==
infinity ;-). For example select() use MAX_SCHEDULE_TIMEOUT when it has to
block indefinitely, so this will eventually decrease select() latency too
(compared to the stock kernel and to my previous diff).

I also made the UNINTERRUPTIBLE case to revert on MAX_SCHEDULE_TIMEOUT
without care of the timeout value passed (better a deadlock than to
return before the time).

I am running with this latest diff applyed and everything seems perfect.

A new jiffies-12... will be out soon (the only difference is this).

Index: linux/kernel/sched.c
diff -u linux/kernel/sched.c:1.1.1.1.14.13 linux/kernel/sched.c:1.1.1.1.14.15
--- linux/kernel/sched.c:1.1.1.1.14.13 Mon Oct 19 22:46:45 1998
+++ linux/kernel/sched.c Tue Oct 20 11:48:47 1998
@@ -457,20 +457,48 @@
* PARANOID.
*/
if (current->state == TASK_UNINTERRUPTIBLE)
+ {
printk(KERN_WARNING "schedule_timeout: task not interrutible "
"from %p\n", __builtin_return_address(0));
- if (timeout < 0)
- {
- printk(KERN_ERR "schedule_timeout: wrong timeout value %lx "
- "from %p\n", timeout, __builtin_return_address(0));
- return timeout;
+ /*
+ * We don' t want to interrupt a not interruptible task
+ * risking to cause corruption. Better a a deadlock ;-).
+ */
+ timeout = MAX_SCHEDULE_TIMEOUT;
}

/*
* Here we start for real.
*/
- if (!timeout)
- goto normal_schedule;
+ switch (timeout)
+ {
+ case 0:
+ case MAX_SCHEDULE_TIMEOUT:
+ /*
+ * These two special cases are useful to be comfortable
+ * in the caller. Nothing more. We could take
+ * MAX_SCHEDULE_TIMEOUT from one of the negative value
+ * but I' d like to return a valid offset (>=0) to allow
+ * the caller to do everything it want with the retval.
+ */
+ schedule();
+ goto out;
+ default:
+ /*
+ * Another bit of PARANOID. Note that the retval will be
+ * 0 since no piece of kernel is supposed to do a check
+ * for a negative retval of schedule_timeout() (since it
+ * should never happens anyway). You just have the printk()
+ * that will tell you if something is gone wrong and where.
+ */
+ if (timeout < 0)
+ {
+ printk(KERN_ERR "schedule_timeout: wrong timeout "
+ "value %lx from %p\n", timeout,
+ __builtin_return_address(0));
+ goto out;
+ }
+ }

expire = timeout + jiffies;

@@ -485,11 +513,8 @@

timeout = expire - jiffies;

+ out:
return timeout < 0 ? 0 : timeout;
-
- normal_schedule:
- schedule();
- return 0;
}

/*

Andrea Arcangeli

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/