Thread (12 messages) 12 messages, 5 authors, 2008-08-25

Re: [PATCH 1/2] [RT] hrtimers stuck in waitqueue

From: Thomas Gleixner <hidden>
Date: 2008-08-22 14:42:41

On Mon, 18 Aug 2008, Gilles Carry wrote:
This patch makes hrtimers initialized with hrtimer_init_sleeper
to use another mode and then not be stuck in waitqueues when
hrtimer_interrupt is very busy.

The new mode is HRTIMER_CB_IRQSAFE_NO_RESTART_NO_SOFIRQ.
The above-mentionned timers have been moved from
HRTIMER_CB_IRQSAFE_NO_SOFTIRQ to
HRTIMER_CB_IRQSAFE_NO_RESTART_NO_SOFIRQ.

HRTIMER_CB_IRQSAFE_NO_RESTART_NO_SOFIRQ timers use a slightly different
state machine from HRTIMER_CB_IRQSAFE_NO_SOFTIRQ's as when removing the
timer, __run_hrtimer sets the status to INACTIVE _then_
wakes up the thread. This way, an awakened thread cannot enter
hrtimer_cancel before the timer's status has changed.
NAK. That solution is racy.

     CPU 0                        CPU 1

     timer interrupt runs         signal wakeup for task which sleeps
     timer->state = INACTIVE;

-> Race window start
     base->lock is dropped
				  hrtimer_cancel()
				  data structure on stack is destroyed

     timer function called
     	   data structure access --> POOOF

-> Race window end

     base->lock is locked

The race is extremly narrow and requires an SMI or some other delay
(bus stall, cache miss ...) on CPU 0, but it exists.

Fix below.

Thanks,
	tglx

---------------->
Subject: hrtimer: avoid waitqueue starvation
From: Thomas Gleixner <redacted>
Date: Fri, 22 Aug 2008 16:27:13 +0200

Garry Gilles found that when a hrtimer callback runs in interrupt
context, then the woken up thread might end up on the timer wakequeue,
which might be blocked for a long time due to interrupts, higher
priority threads and no timers in the softirq list.

For timers which run their callback function in the hard irq context
we can safely spin and wait for the state to become inactive. The
waitqueue is only necessary for timers which run their callback
function in softirq context.

Debugged-by: Gilles Carry [off-list ref]
Signed-off-by: Thomas Gleixner <redacted>
---
 kernel/hrtimer.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Index: linux-2.6.24.7/kernel/hrtimer.c
===================================================================
--- linux-2.6.24.7.orig/kernel/hrtimer.c
+++ linux-2.6.24.7/kernel/hrtimer.c
@@ -990,7 +990,14 @@ int hrtimer_cancel(struct hrtimer *timer
 
 		if (ret >= 0)
 			return ret;
-		hrtimer_wait_for_timer(timer);
+		switch (timer->cb_mode) {
+		case HRTIMER_CB_IRQSAFE_NO_SOFTIRQ:
+		case HRTIMER_CB_IRQSAFE_NO_RESTART:
+			cpu_relax();
+			break;
+		default:
+			hrtimer_wait_for_timer(timer);
+		}
 	}
 }
 EXPORT_SYMBOL_GPL(hrtimer_cancel);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help