Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1693150 > unrolled thread

[PATCH] drivers: cpuidle: Disable preemption before get_lppaca function call in pseries_idle_probe function

Started byVictor Aoqui <victora@linux.vnet.ibm.com>
First post2017-07-20 20:00 +0200
Last post2017-07-20 23:30 +0200
Articles 2 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH] drivers: cpuidle: Disable preemption before get_lppaca function call in pseries_idle_probe function Victor Aoqui <victora@linux.vnet.ibm.com> - 2017-07-20 20:00 +0200
    Re: [PATCH] drivers: cpuidle: Disable preemption before get_lppaca  function call in pseries_idle_probe function Benjamin Herrenschmidt <benh@kernel.crashing.org> - 2017-07-20 23:30 +0200

#1693150 — [PATCH] drivers: cpuidle: Disable preemption before get_lppaca function call in pseries_idle_probe function

FromVictor Aoqui <victora@linux.vnet.ibm.com>
Date2017-07-20 20:00 +0200
Subject[PATCH] drivers: cpuidle: Disable preemption before get_lppaca function call in pseries_idle_probe function
Message-ID<u5nTY-29Y-21@gated-at.bofh.it>
When CONFIG_PREEMPT=y, the following warning shows up:

BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1
caller is pseries_processor_idle_init+0x58/0x21c

This warning shows up because preemption cannot occur when using
get_paca(), otherwise the paca_struct it points to may be the wrong one
just after.

For this reason, preemption needs to be disabled before
lppaca_shared_proc(get_lppaca()).

Signed-off-by: Victor Aoqui <victora@linux.vnet.ibm.com>
---
 drivers/cpuidle/cpuidle-pseries.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c
index e9b3853..d6dda8c 100644
--- a/drivers/cpuidle/cpuidle-pseries.c
+++ b/drivers/cpuidle/cpuidle-pseries.c
@@ -233,12 +233,16 @@ static int pseries_cpuidle_driver_init(void)
  */
 static int pseries_idle_probe(void)
 {
+	int retval;
 
 	if (cpuidle_disable != IDLE_NO_OVERRIDE)
 		return -ENODEV;
 
 	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
-		if (lppaca_shared_proc(get_lppaca())) {
+		preempt_disable();
+		retval = lppaca_shared_proc(get_lppaca());
+		preempt_enable();
+		if (retval) {
 			cpuidle_state_table = shared_states;
 			max_idle_state = ARRAY_SIZE(shared_states);
 		} else {
-- 
1.8.3.1

[toc] | [next] | [standalone]


#1693239 — Re: [PATCH] drivers: cpuidle: Disable preemption before get_lppaca function call in pseries_idle_probe function

FromBenjamin Herrenschmidt <benh@kernel.crashing.org>
Date2017-07-20 23:30 +0200
SubjectRe: [PATCH] drivers: cpuidle: Disable preemption before get_lppaca function call in pseries_idle_probe function
Message-ID<u5rbc-4jX-17@gated-at.bofh.it>
In reply to#1693150
On Thu, 2017-07-20 at 14:57 -0300, Victor Aoqui wrote:
> When CONFIG_PREEMPT=y, the following warning shows up:
> 
> BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1
> caller is pseries_processor_idle_init+0x58/0x21c
> 
> This warning shows up because preemption cannot occur when using
> get_paca(), otherwise the paca_struct it points to may be the wrong one
> just after.
> 
> For this reason, preemption needs to be disabled before
> lppaca_shared_proc(get_lppaca()).

Also chekc the generated assembly. We had all sort of interesting
issues where gcc would copy the paca pointer or the lppaca pointer
to a GPR *outside* of the preempt disabled section...

In that specific case it's not a big deal but overall, I am not
comfortable with PREEMPT on powerpc until we do something a bit
more drastic...

I would like to remove all such direct accesses to paca, instead have a
"new" get_paca() written in asm that does the preempt disable then
returns the PACA in a GPR (not directly use r13, hide that from gcc),
and which is paired with a put_paca().

The few places where we want to directly access r13 should be hand
written in asm too to hide r13 from gcc, for accessing the irq_happened
in the fast path of local_irq_enable/disable/... we should do the same
with lock tokens.

Ben.

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web