[PATCH -rt] speed up nanosleep on early expire

From: Steven Rostedt
Date: Tue Feb 14 2006 - 05:00:07 EST



Here's a revisit of the problem of nanosleep waking up the softirq to wake
itself up when the timer has already expired. As mentioned in my last
patch, this causes large latencies to nanosleep. But the last patch was
sloppy and introduced too much ugly code.

I should have noticed this the first time, but here's a much cleaner
patch. As the hrtimer_interrupt checks the data field to determine to
wake the process up directly or to wake up the softirq, I noticed that the
nanosleep doesn't even need the softirq. So instead of waking up the
softirq in enqueue_hrtimer, I do the same work as the hrtimer_interrupt
does, and that is to wake up the process directly if there is no function
associated with the timer.

I also saved a few microseconds by checking in schedule_hrtimer if current
is already running don't call schedule.

This patch is much cleaner than the last patch, and gives pretty much the
same result.

-- Steve

Signed-off-by: Steven Rostedt <rostedt@xxxxxxxxxxx>

Index: linux-2.6.15-rt16/kernel/hrtimer.c
===================================================================
--- linux-2.6.15-rt16.orig/kernel/hrtimer.c 2006-02-10 09:53:53.000000000 -0500
+++ linux-2.6.15-rt16/kernel/hrtimer.c 2006-02-14 04:30:43.000000000 -0500
@@ -578,9 +578,18 @@
* and schedule the softirq.
*/
if (hrtimer_hres_active && hrtimer_reprogram(timer, base)) {
- list_add_tail(&timer->list, &base->expired);
- timer->state = HRTIMER_PENDING_CALLBACK;
- raise_softirq(HRTIMER_SOFTIRQ);
+ /*
+ * Only wake up the hrtimer softirq if it is needed,
+ * otherwise wake up the process waiting for this timer.
+ */
+ if (!timer->function) {
+ wake_up_process(timer->data);
+ timer->state = HRTIMER_EXPIRED;
+ } else {
+ list_add_tail(&timer->list, &base->expired);
+ timer->state = HRTIMER_PENDING_CALLBACK;
+ raise_softirq(HRTIMER_SOFTIRQ);
+ }
return;
}
#endif
@@ -1029,7 +1038,13 @@

hrtimer_start(timer, timer->expires, mode);

- schedule();
+ /*
+ * the timer could have arleady expired, in which
+ * case current would be running. Don't bother calling
+ * schedule.
+ */
+ if (likely(current->state))
+ schedule();
hrtimer_cancel(timer);

/* Return the remaining time: */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/