Re: BUG: using smp_processor_id() during suspend with 2.6.25-rc8

Jiri Kosina
2008-04-07T21:54:31Z

[ CCs added ]

On Mon, 7 Apr 2008, Zdenek Kabelac wrote:

> This has appeared in my kernel log:

The two patches below should fix these, shouldn't they?

> hwsleep-0322 [00] enter_sleep_state : Entering sleep state [S3]
> BUG: using smp_processor_id() in preemptible [00000000] code: pm-suspend/18791
> caller is do_machine_check+0xa9/0x500

From: Jiri Kosina <jkosina@suse.cz>

x86: fix possible race in do_machine_check()

It is not safe to call smp_processor_id() in cases we are not sure someone
will not reschedule us.

Signed-off-by: Jiri Kosina <jkosina@suse.cz>

diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
index 9a699ed..bf92375 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_64.c
@@ -189,6 +189,7 @@ void do_machine_check(struct pt_regs * regs, long error_code)
* error.
*/
int kill_it = 0;
+ unsigned long flags;

atomic_inc(&mce_entry);

@@ -199,6 +200,8 @@ void do_machine_check(struct pt_regs * regs, long error_code)
goto out2;

memset(&m, 0, sizeof(struct mce));
+
+ local_irq_save(flags);
m.cpu = smp_processor_id();
rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus);
/* if the restart IP is not valid, we're done for */
@@ -315,6 +318,7 @@ void do_machine_check(struct pt_regs * regs, long error_code)
wrmsrl(MSR_IA32_MCG_STATUS, 0);
out2:
atomic_dec(&mce_entry);
+ local_irq_restore(flags);
}

#ifdef CONFIG_X86_MCE_INTEL

> Extended CMOS year: 2000
> BUG: using smp_processor_id() in preemptible [00000000] code: pm-suspend/18791
> caller is retrigger_next_event+0x1c/0xf0
> Pid: 18791, comm: pm-suspend Not tainted 2.6.25-rc8 #32

From: Jiri Kosina <jkosina@suse.cz>

hrtimer: fix possible race in retrigger_next_event()

It is not safe to perform per-cpu variable read and use it later in cases
we are not sure someone will not reschedule us.

Signed-off-by: Jiri Kosina <jkosina@suse.cz>

diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 98bee01..c008096 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -486,6 +486,7 @@ static void retrigger_next_event(void *arg)
struct hrtimer_cpu_base *base;
struct timespec realtime_offset;
unsigned long seq;
+ unsigned long flags;

if (!hrtimer_hres_active())
return;
@@ -497,6 +498,7 @@ static void retrigger_next_event(void *arg)
-wall_to_monotonic.tv_nsec);
} while (read_seqretry(&xtime_lock, seq));

+ local_irq_save(flags);
base = &__get_cpu_var(hrtimer_bases);

/* Adjust CLOCK_REALTIME offset */
@@ -506,6 +508,7 @@ static void retrigger_next_event(void *arg)

hrtimer_force_reprogram(base);
spin_unlock(&base->lock);
+ local_irq_restore(flags);
}

/*