From: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
To: Benjamin Herrenschmidt <benh@kernel.crashing.org>,
"Linux PM mailing list <linux-pm@vger.kernel.org>
\"linux-kernel@vger.kernel.org\"" <linux-kernel@vger.kernel.org>,
PowerPC email list <linuxppc-dev@lists.ozlabs.org>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
Paul Mackerras <paulus@samba.org>,
Li Zhong <zhong@linux.vnet.ibm.com>,
"Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com>,
Linux PM mailing list <linux-pm@vger.kernel.org>
Subject: [PATCH v3] cpuidle: (POWER) Replace pseries_notify_cpuidle_add _cpu call with a notifier to fix lockdep problem in start_secondary
Date: Tue, 03 Jul 2012 13:50:16 +0530 [thread overview]
Message-ID: <4FF2AB40.6050701@linux.vnet.ibm.com> (raw)
In-Reply-To: <4FF29219.10608@linux.vnet.ibm.com>
cpuidle: (POWER) Replace pseries_notify_cpuidle_add_cpu call with a notifier to fix lockdep problem in start_secondary
From: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
Currently the call to pseries_notify_cpuidle_add_cpu(), that takes
action on the cpuidle front when a cpu is added/removed
is being made from smp_xics_setup_cpu().
This caused lockdep issues as
reported https://lkml.org/lkml/2012/5/17/2
On addition of each cpu, resources are cleared and re-allocated
each time, all in critical section as part of start_secondary()
call which has interrupts disabled.
To resolve this issue, the pseries_notify_cpuidle_add_cpu() call is
is now being replaced by a hotplug notifier which
would prevent cpuidle resources from being
released and allocated each time cpu is onlined in the critical code path.
Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
Reported-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
---
This patch has in-corporated review comments
received on the earlier version posted.
v1 -> https://lkml.org/lkml/2012/5/18/174
v2 -> https://lkml.org/lkml/2012/7/3/61
This applies on 3.5-rc5
arch/powerpc/include/asm/processor.h | 2 -
arch/powerpc/platforms/pseries/processor_idle.c | 35 ++++++++++++++++++++---
arch/powerpc/platforms/pseries/smp.c | 1 -
3 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 413a5ea..53b6dfa 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -389,10 +389,8 @@ extern int powersave_nap; /* set if nap mode can be used in idle loop */
#ifdef CONFIG_PSERIES_IDLE
extern void update_smt_snooze_delay(int snooze);
-extern int pseries_notify_cpuidle_add_cpu(int cpu);
#else
static inline void update_smt_snooze_delay(int snooze) {}
-static inline int pseries_notify_cpuidle_add_cpu(int cpu) { return 0; }
#endif
extern void flush_instruction_cache(void);
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
index e61483e..da245c0 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -186,17 +186,40 @@ static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = {
.enter = &shared_cede_loop },
};
-int pseries_notify_cpuidle_add_cpu(int cpu)
+static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n,
+ unsigned long action, void *hcpu)
{
+ int hotcpu = (unsigned long)hcpu;
struct cpuidle_device *dev =
- per_cpu_ptr(pseries_cpuidle_devices, cpu);
+ per_cpu_ptr(pseries_cpuidle_devices, hotcpu);
+
if (dev && cpuidle_get_driver()) {
- cpuidle_disable_device(dev);
- cpuidle_enable_device(dev);
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+ cpuidle_pause_and_lock();
+ cpuidle_enable_device(dev);
+ cpuidle_resume_and_unlock();
+ break;
+
+ case CPU_DEAD:
+ case CPU_DEAD_FROZEN:
+ cpuidle_pause_and_lock();
+ cpuidle_disable_device(dev);
+ cpuidle_resume_and_unlock();
+ break;
+
+ default:
+ return NOTIFY_DONE;
+ }
}
- return 0;
+ return NOTIFY_OK;
}
+static struct notifier_block setup_hotplug_notifier = {
+ .notifier_call = pseries_cpuidle_add_cpu_notifier,
+};
+
/*
* pseries_cpuidle_driver_init()
*/
@@ -321,6 +344,7 @@ static int __init pseries_processor_idle_init(void)
return retval;
}
+ register_cpu_notifier(&setup_hotplug_notifier);
printk(KERN_DEBUG "pseries_idle_driver registered\n");
return 0;
@@ -329,6 +353,7 @@ static int __init pseries_processor_idle_init(void)
static void __exit pseries_processor_idle_exit(void)
{
+ unregister_cpu_notifier(&setup_hotplug_notifier);
pseries_idle_devices_uninit();
cpuidle_unregister_driver(&pseries_idle_driver);
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index e16bb8d..71706bc 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -147,7 +147,6 @@ static void __devinit smp_xics_setup_cpu(int cpu)
set_cpu_current_state(cpu, CPU_STATE_ONLINE);
set_default_offline_state(cpu);
#endif
- pseries_notify_cpuidle_add_cpu(cpu);
}
static int __devinit smp_pSeries_kick_cpu(int nr)
Cheers,
Deepthi
WARNING: multiple messages have this Message-ID (diff)
From: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
To: Benjamin Herrenschmidt <benh@kernel.crashing.org>,
"Linux PM mailing list <linux-pm@vger.kernel.org>
\"linux-kernel@vger.kernel.org\"" <linux-kernel@vger.kernel.org>,
PowerPC email list <linuxppc-dev@lists.ozlabs.org>
Cc: Linux PM mailing list <linux-pm@vger.kernel.org>,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
Paul Mackerras <paulus@samba.org>,
"Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com>,
Li Zhong <zhong@linux.vnet.ibm.com>
Subject: [PATCH v3] cpuidle: (POWER) Replace pseries_notify_cpuidle_add _cpu call with a notifier to fix lockdep problem in start_secondary
Date: Tue, 03 Jul 2012 13:50:16 +0530 [thread overview]
Message-ID: <4FF2AB40.6050701@linux.vnet.ibm.com> (raw)
In-Reply-To: <4FF29219.10608@linux.vnet.ibm.com>
cpuidle: (POWER) Replace pseries_notify_cpuidle_add_cpu call with a notifier to fix lockdep problem in start_secondary
From: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
Currently the call to pseries_notify_cpuidle_add_cpu(), that takes
action on the cpuidle front when a cpu is added/removed
is being made from smp_xics_setup_cpu().
This caused lockdep issues as
reported https://lkml.org/lkml/2012/5/17/2
On addition of each cpu, resources are cleared and re-allocated
each time, all in critical section as part of start_secondary()
call which has interrupts disabled.
To resolve this issue, the pseries_notify_cpuidle_add_cpu() call is
is now being replaced by a hotplug notifier which
would prevent cpuidle resources from being
released and allocated each time cpu is onlined in the critical code path.
Signed-off-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>
Reported-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
---
This patch has in-corporated review comments
received on the earlier version posted.
v1 -> https://lkml.org/lkml/2012/5/18/174
v2 -> https://lkml.org/lkml/2012/7/3/61
This applies on 3.5-rc5
arch/powerpc/include/asm/processor.h | 2 -
arch/powerpc/platforms/pseries/processor_idle.c | 35 ++++++++++++++++++++---
arch/powerpc/platforms/pseries/smp.c | 1 -
3 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 413a5ea..53b6dfa 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -389,10 +389,8 @@ extern int powersave_nap; /* set if nap mode can be used in idle loop */
#ifdef CONFIG_PSERIES_IDLE
extern void update_smt_snooze_delay(int snooze);
-extern int pseries_notify_cpuidle_add_cpu(int cpu);
#else
static inline void update_smt_snooze_delay(int snooze) {}
-static inline int pseries_notify_cpuidle_add_cpu(int cpu) { return 0; }
#endif
extern void flush_instruction_cache(void);
diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c
index e61483e..da245c0 100644
--- a/arch/powerpc/platforms/pseries/processor_idle.c
+++ b/arch/powerpc/platforms/pseries/processor_idle.c
@@ -186,17 +186,40 @@ static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = {
.enter = &shared_cede_loop },
};
-int pseries_notify_cpuidle_add_cpu(int cpu)
+static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n,
+ unsigned long action, void *hcpu)
{
+ int hotcpu = (unsigned long)hcpu;
struct cpuidle_device *dev =
- per_cpu_ptr(pseries_cpuidle_devices, cpu);
+ per_cpu_ptr(pseries_cpuidle_devices, hotcpu);
+
if (dev && cpuidle_get_driver()) {
- cpuidle_disable_device(dev);
- cpuidle_enable_device(dev);
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+ cpuidle_pause_and_lock();
+ cpuidle_enable_device(dev);
+ cpuidle_resume_and_unlock();
+ break;
+
+ case CPU_DEAD:
+ case CPU_DEAD_FROZEN:
+ cpuidle_pause_and_lock();
+ cpuidle_disable_device(dev);
+ cpuidle_resume_and_unlock();
+ break;
+
+ default:
+ return NOTIFY_DONE;
+ }
}
- return 0;
+ return NOTIFY_OK;
}
+static struct notifier_block setup_hotplug_notifier = {
+ .notifier_call = pseries_cpuidle_add_cpu_notifier,
+};
+
/*
* pseries_cpuidle_driver_init()
*/
@@ -321,6 +344,7 @@ static int __init pseries_processor_idle_init(void)
return retval;
}
+ register_cpu_notifier(&setup_hotplug_notifier);
printk(KERN_DEBUG "pseries_idle_driver registered\n");
return 0;
@@ -329,6 +353,7 @@ static int __init pseries_processor_idle_init(void)
static void __exit pseries_processor_idle_exit(void)
{
+ unregister_cpu_notifier(&setup_hotplug_notifier);
pseries_idle_devices_uninit();
cpuidle_unregister_driver(&pseries_idle_driver);
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index e16bb8d..71706bc 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -147,7 +147,6 @@ static void __devinit smp_xics_setup_cpu(int cpu)
set_cpu_current_state(cpu, CPU_STATE_ONLINE);
set_default_offline_state(cpu);
#endif
- pseries_notify_cpuidle_add_cpu(cpu);
}
static int __devinit smp_pSeries_kick_cpu(int nr)
Cheers,
Deepthi
next prev parent reply other threads:[~2012-07-03 8:20 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-03 6:32 [PATCH v2] cpuidle: (POWER) Replace pseries_notify_cpuidle_add call with a notifier to fix lockdep problem in start_secondary Deepthi Dharwar
2012-07-03 6:32 ` Deepthi Dharwar
2012-07-03 8:20 ` Deepthi Dharwar [this message]
2012-07-03 8:20 ` [PATCH v3] cpuidle: (POWER) Replace pseries_notify_cpuidle_add _cpu " Deepthi Dharwar
[not found] ` <1341351841.2346.11.camel@pasglop>
2012-07-04 6:07 ` [PATCH] cpuidle:(POWER) Fixes for pseries_idle hotplug notifier Deepthi Dharwar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4FF2AB40.6050701@linux.vnet.ibm.com \
--to=deepthi@linux.vnet.ibm.com \
--cc=benh@kernel.crashing.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=paulmck@linux.vnet.ibm.com \
--cc=paulus@samba.org \
--cc=srivatsa.bhat@linux.vnet.ibm.com \
--cc=zhong@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.