[patch 14/28] clockevents: prevent multiple init/shutdown

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <linux-kernel@...>, <stable@...>
Cc: Justin Forbes <jmforbes@...>, Zwane Mwaikambo <zwane@...>, Theodore Ts'o <tytso@...>, Randy Dunlap <rdunlap@...>, Dave Jones <davej@...>, Chuck Wolber <chuckw@...>, Chris Wedgwood <reviews@...>, Michael Krufky <mkrufky@...>, Chuck Ebbert <cebbert@...>, Domenico Andreoli <cavokz@...>, Willy Tarreau <w@...>, Rodrigo Rubira Branco <rbranco@...>, Jake Edge <jake@...>, Eugene Teo <eteo@...>, <torvalds@...>, <akpm@...>, <alan@...>, Thomas Gleixner <tglx@...>, Ingo Molnar <mingo@...>
Date: Monday, October 6, 2008 - 7:17 pm

2.6.25-stable review patch.  If anyone has any objections, please let us
know.

------------------
From: Thomas Gleixner <tglx@linutronix.de>

commit 9c17bcda991000351cb2373f78be7e4b1c44caa3 upstream

While chasing the C1E/HPET bugreports I went through the clock events
code inch by inch and found that the broadcast device can be initialized
and shutdown multiple times. Multiple shutdowns are not critical, but
useless waste of time. Multiple initializations are simply broken. Another
CPU might have the device in use already after the first initialization and
the second init could just render it unusable again.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 kernel/time/tick-broadcast.c |   20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -209,7 +209,7 @@ static void tick_do_broadcast_on_off(voi
 	struct clock_event_device *bc, *dev;
 	struct tick_device *td;
 	unsigned long flags, *reason = why;
-	int cpu;
+	int cpu, bc_stopped;
 
 	spin_lock_irqsave(&tick_broadcast_lock, flags);
 
@@ -227,6 +227,8 @@ static void tick_do_broadcast_on_off(voi
 	if (!tick_device_is_functional(dev))
 		goto out;
 
+	bc_stopped = cpus_empty(tick_broadcast_mask);
+
 	switch (*reason) {
 	case CLOCK_EVT_NOTIFY_BROADCAST_ON:
 	case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
@@ -248,9 +250,10 @@ static void tick_do_broadcast_on_off(voi
 		break;
 	}
 
-	if (cpus_empty(tick_broadcast_mask))
-		clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
-	else {
+	if (cpus_empty(tick_broadcast_mask)) {
+		if (!bc_stopped)
+			clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
+	} else if (bc_stopped) {
 		if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
 			tick_broadcast_start_periodic(bc);
 		else
@@ -500,9 +503,12 @@ static void tick_broadcast_clear_oneshot
  */
 void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
 {
-	bc->event_handler = tick_handle_oneshot_broadcast;
-	clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
-	bc->next_event.tv64 = KTIME_MAX;
+	/* Set it up only once ! */
+	if (bc->event_handler != tick_handle_oneshot_broadcast) {
+		bc->event_handler = tick_handle_oneshot_broadcast;
+		clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
+		bc->next_event.tv64 = KTIME_MAX;
+	}
 }
 
 /*

-- 
--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[patch 00/28] 2.6.25-stable review, Greg KH, (Mon Oct 6, 7:16 pm)
[patch 28/28] udp: Fix rcv socket locking, Greg KH, (Mon Oct 6, 7:18 pm)
[patch 24/28] niu: panic on reset, Greg KH, (Mon Oct 6, 7:17 pm)
[patch 14/28] clockevents: prevent multiple init/shutdown, Greg KH, (Mon Oct 6, 7:17 pm)
[patch 09/28] rtc: fix deadlock, Greg KH, (Mon Oct 6, 7:17 pm)
[patch 07/28] ACPI: Fix thermal shutdowns, Greg KH, (Mon Oct 6, 7:17 pm)
[patch 03/28] pxa2xx_spi: chipselect bugfixes, Greg KH, (Mon Oct 6, 7:17 pm)
[patch 02/28] pxa2xx_spi: dma bugfixes, Greg KH, (Mon Oct 6, 7:17 pm)
Re: [patch 02/28] pxa2xx_spi: dma bugfixes, Ned Forrester, (Mon Oct 6, 8:15 pm)
[patch 01/28] USB: fix hcd interrupt disabling, Greg KH, (Mon Oct 6, 7:16 pm)