Skip to contentSkip to conversation

powerpc: Fix WARN_ON in decrementer_check_overflow

PATCH In review Benjamin Herrenschmidt 2 participants 3 messages Feb 9, 2012 PowerPC

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 powerpc: Fix WARN_ON in decrementer_check_overflow

We use __get_cpu_var() which triggers a false positive warning in smp_processor_id() thinking interrupts are enabled (at this point, they are soft-enabled but hard-disabled).

---

I was initially planning to fix that with a more in-depth rework of how we do lazy irq disabling on powerpc, but that patch is becoming too complex for this release so I'll apply this as a stop-gap and leave the full rework for -next

arch/powerpc/kernel/irq.c +5 -1
index 701d4ac..01e2877 100644
@@ -118,10 +118,14 @@ static inline notrace void set_soft_enabled(unsigned long enable)
 static inline notrace void decrementer_check_overflow(void)
 {
 	u64 now = get_tb_or_rtc();
-	u64 *next_tb = &__get_cpu_var(decrementers_next_tb);
+	u64 *next_tb;
+
+	preempt_disable();
+	next_tb = &__get_cpu_var(decrementers_next_tb);
 
 	if (now >= *next_tb)
 		set_dec(1);
+	preempt_enable();
 }
 
 notrace void arch_local_irq_restore(unsigned long en)
#1 lore raw
Quoted 11 lines · Benjamin Herrenschmidt

We use __get_cpu_var() which triggers a false positive warning in smp_processor_id() thinking interrupts are enabled (at this point, they are soft-enabled but hard-disabled).

---

I was initially planning to fix that with a more in-depth rework of how we do lazy irq disabling on powerpc, but that patch is becoming too complex for this release so I'll apply this as a stop-gap and leave the full rework for -next

Okay, thanks for the update, that's equivalent to the get_cpu_var plus put_cpu_var patch I had generally been running with successfully.

(I was not at all confident that it was a sufficient fix, and have to say "generally" above because one time I got something that looked like recursive calls overflowing the stack, and IIRC something "irq" did appear in each frame of the trace. But probably no connection, never seen again, and I don't recall even which -rc or -next it was.)

Hugh

Quoted 21 lines
arch/powerpc/kernel/irq.c +5 -1
index 701d4ac..01e2877 100644
@@ -118,10 +118,14 @@ static inline notrace void set_soft_enabled(unsigned long enable)
 static inline notrace void decrementer_check_overflow(void)
 {
 	u64 now = get_tb_or_rtc();
-	u64 *next_tb = &__get_cpu_var(decrementers_next_tb);
+	u64 *next_tb;
+
+	preempt_disable();
+	next_tb = &__get_cpu_var(decrementers_next_tb);
 
 	if (now >= *next_tb)
 		set_dec(1);
+	preempt_enable();
 }
 
 notrace void arch_local_irq_restore(unsigned long en)
#2 lore raw
Quoted 9 lines · Hugh Dickins

Okay, thanks for the update, that's equivalent to the get_cpu_var plus put_cpu_var patch I had generally been running with successfully.

(I was not at all confident that it was a sufficient fix, and have to say "generally" above because one time I got something that looked like recursive calls overflowing the stack, and IIRC something "irq" did appear in each frame of the trace. But probably no connection, never seen again, and I don't recall even which -rc or -next it was.)

If you ever see that again, please shoot me the log !

Cheers,
Ben.