lkml.org 
[lkml]   [2004]   [Sep]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
SubjectRE: [ACPI] Re: [PATCH] Oops and panic while unloading holder of pm_idle
Date
From
On Thursday, September 09, 2004, Zwane Mwaikambo wrote:
>Hello Shaohua,
>
>> + /* Wait the idle thread to read the new value,
>> + * otherwise we Oops.
>> + */
>
>I should have mentioned this earlier, but the comment needs work,
>something like this;
>
>"We are about to unload the current idle thread pm callback (pm_idle),
> Wait for all processors to update cached/local copies of pm_idle
before
> proceeding."
>
>> + /* If pm_idle is in a module and is preempted,
>> + * oops occurs. Disable preempt.
>> + */
>
>"Mark this as an RCU critical section so that synchronize_kernel() in
the
> unload path waits for our completion."
>
>Then resend the patch, i swear it'll be the last time ;)
Zwane,
It's fine. Here is the updated patch.

Thanks,
Shaohua

Signed-off-by: Li Shaohua <shaohua.li@intel.com>
===== arch/i386/kernel/apm.c 1.67 vs edited =====
--- 1.67/arch/i386/kernel/apm.c 2004-08-24 17:08:47 +08:00
+++ edited/arch/i386/kernel/apm.c 2004-09-09 10:57:16 +08:00
@@ -2362,8 +2362,15 @@ static void __exit apm_exit(void)
{
int error;

- if (set_pm_idle)
+ if (set_pm_idle) {
pm_idle = original_pm_idle;
+ /*
+ * We are about to unload the current idle thread pm
callback
+ * (pm_idle), Wait for all processors to update
cached/local
+ * copies of pm_idle before proceeding.
+ */
+ synchronize_kernel();
+ }
if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0)
&& (apm_info.connection_version > 0x0100)) {
error = apm_engage_power_management(APM_DEVICE_ALL, 0);
===== arch/i386/kernel/process.c 1.75 vs edited =====
--- 1.75/arch/i386/kernel/process.c 2004-08-24 17:08:44 +08:00
+++ edited/arch/i386/kernel/process.c 2004-09-09 10:59:47 +08:00
@@ -142,6 +142,12 @@ void cpu_idle (void)
/* endless idle loop with no priority at all */
while (1) {
while (!need_resched()) {
+ /*
+ * Mark this as an RCU critical section so that
+ * synchronize_kernel() in the unload path waits
+ * for our completion.
+ */
+ rcu_read_lock();
void (*idle)(void) = pm_idle;

if (!idle)
@@ -149,6 +155,7 @@ void cpu_idle (void)

irq_stat[smp_processor_id()].idle_timestamp =
jiffies;
idle();
+ rcu_read_unlock();
}
schedule();
}
===== arch/ia64/kernel/process.c 1.62 vs edited =====
--- 1.62/arch/ia64/kernel/process.c 2004-07-27 13:26:50 +08:00
+++ edited/arch/ia64/kernel/process.c 2004-09-09 11:01:12 +08:00
@@ -228,18 +228,26 @@ cpu_idle (void *unused)

/* endless idle loop with no priority at all */
while (1) {
- void (*idle)(void) = pm_idle;
- if (!idle)
- idle = default_idle;
-
#ifdef CONFIG_SMP
if (!need_resched())
min_xtp();
#endif
while (!need_resched()) {
+ void (*idle)(void);
+
if (mark_idle)
(*mark_idle)(1);
+ /*
+ * Mark this as an RCU critical section so that
+ * synchronize_kernel() in the unload path waits
+ * for our completion.
+ */
+ rcu_read_lock();
+ idle= pm_idle;
+ if (!idle)
+ idle = default_idle;
(*idle)();
+ rcu_read_unlock();
}

if (mark_idle)
===== arch/x86_64/kernel/process.c 1.35 vs edited =====
--- 1.35/arch/x86_64/kernel/process.c 2004-08-24 17:08:44 +08:00
+++ edited/arch/x86_64/kernel/process.c 2004-09-09 11:01:57 +08:00
@@ -130,11 +130,20 @@ void cpu_idle (void)
{
/* endless idle loop with no priority at all */
while (1) {
- void (*idle)(void) = pm_idle;
- if (!idle)
- idle = default_idle;
- while (!need_resched())
+ while (!need_resched()) {
+ void (*idle)(void);
+ /*
+ * Mark this as an RCU critical section so that
+ * synchronize_kernel() in the unload path waits
+ * for our completion.
+ */
+ rcu_read_lock();
+ idle = pm_idle;
+ if (!idle)
+ idle = default_idle;
idle();
+ rcu_read_unlock();
+ }
schedule();
}
}
===== drivers/acpi/processor.c 1.61 vs edited =====
--- 1.61/drivers/acpi/processor.c 2004-08-31 23:27:29 +08:00
+++ edited/drivers/acpi/processor.c 2004-09-09 11:02:56 +08:00
@@ -2419,6 +2419,11 @@ acpi_processor_remove (
/* Unregister the idle handler when processor #0 is removed. */
if (pr->id == 0) {
pm_idle = pm_idle_save;
+ /*
+ * We are about to unload the current idle thread pm
callback
+ * (pm_idle), Wait for all processors to update
cached/local
+ * copies of pm_idle before proceeding.
+ */
synchronize_kernel();
}

<<idle.patch>> [unhandled content-type:application/octet-stream]
\
 
 \ /
  Last update: 2005-03-22 14:06    [W:0.031 / U:0.052 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site