From: Christopher M. Riedl <hidden> Date: 2019-07-28 13:03:24
Fixes an oops when calling the shared-processor spinlock implementation
from a non-SP LPAR. Also take this opportunity to refactor
SHARED_PROCESSOR a bit.
Reference: https://github.com/linuxppc/issues/issues/229
Christopher M. Riedl (3):
powerpc/spinlocks: Refactor SHARED_PROCESSOR
powerpc/spinlocks: Rename SPLPAR-only spinlocks
powerpc/spinlocks: Fix oops in shared-processor spinlocks
arch/powerpc/include/asm/spinlock.h | 59 ++++++++++++++++++++---------
arch/powerpc/lib/locks.c | 6 +--
2 files changed, 45 insertions(+), 20 deletions(-)
--
2.22.0
From: Christopher M. Riedl <hidden> Date: 2019-07-28 13:01:09
The __rw_yield and __spin_yield locks only pertain to SPLPAR mode.
Rename them to make this relationship obvious.
Signed-off-by: Christopher M. Riedl <redacted>
---
arch/powerpc/include/asm/spinlock.h | 6 ++++--
arch/powerpc/lib/locks.c | 6 +++---
2 files changed, 7 insertions(+), 5 deletions(-)
@@ -101,8 +101,10 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)#if defined(CONFIG_PPC_SPLPAR)/* We only yield to the hypervisor if we are in shared processor mode */-externvoid__spin_yield(arch_spinlock_t*lock);-externvoid__rw_yield(arch_rwlock_t*lock);+voidsplpar_spin_yield(arch_spinlock_t*lock);+voidsplpar_rw_yield(arch_rwlock_t*lock);+#define __spin_yield(x) splpar_spin_yield(x)+#define __rw_yield(x) splpar_rw_yield(x)#else /* SPLPAR */#define __spin_yield(x) barrier()#define __rw_yield(x) barrier()
From: Christopher M. Riedl <hidden> Date: 2019-07-28 13:06:07
Determining if a processor is in shared processor mode is not a constant
so don't hide it behind a #define.
Signed-off-by: Christopher M. Riedl <redacted>
---
arch/powerpc/include/asm/spinlock.h | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
@@ -101,15 +101,24 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)#if defined(CONFIG_PPC_SPLPAR)/* We only yield to the hypervisor if we are in shared processor mode */-#define SHARED_PROCESSOR (lppaca_shared_proc(local_paca->lppaca_ptr))externvoid__spin_yield(arch_spinlock_t*lock);externvoid__rw_yield(arch_rwlock_t*lock);#else /* SPLPAR */#define __spin_yield(x) barrier()#define __rw_yield(x) barrier()-#define SHARED_PROCESSOR 0#endif+staticinlineboolis_shared_processor(void)+{+/* Only server processors have an lppaca struct */+#ifdef CONFIG_PPC_BOOK3S+return(IS_ENABLED(CONFIG_PPC_SPLPAR)&&+lppaca_shared_proc(local_paca->lppaca_ptr));+#else+returnfalse;+#endif+}+staticinlinevoidarch_spin_lock(arch_spinlock_t*lock){while(1){
@@ -103,11 +103,9 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)/* We only yield to the hypervisor if we are in shared processor mode */voidsplpar_spin_yield(arch_spinlock_t*lock);voidsplpar_rw_yield(arch_rwlock_t*lock);-#define __spin_yield(x) splpar_spin_yield(x)-#define __rw_yield(x) splpar_rw_yield(x)#else /* SPLPAR */-#define __spin_yield(x) barrier()-#define __rw_yield(x) barrier()+#define splpar_spin_yield(lock)+#define splpar_rw_yield(lock)#endifstaticinlineboolis_shared_processor(void)
Determining if a processor is in shared processor mode is not a constant
so don't hide it behind a #define.
Signed-off-by: Christopher M. Riedl <redacted>
---
arch/powerpc/include/asm/spinlock.h | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
@@ -101,15 +101,24 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)#if defined(CONFIG_PPC_SPLPAR)/* We only yield to the hypervisor if we are in shared processor mode */-#define SHARED_PROCESSOR (lppaca_shared_proc(local_paca->lppaca_ptr))externvoid__spin_yield(arch_spinlock_t*lock);externvoid__rw_yield(arch_rwlock_t*lock);#else /* SPLPAR */#define __spin_yield(x) barrier()#define __rw_yield(x) barrier()-#define SHARED_PROCESSOR 0#endif+staticinlineboolis_shared_processor(void)+{+/* Only server processors have an lppaca struct */+#ifdef CONFIG_PPC_BOOK3S+return(IS_ENABLED(CONFIG_PPC_SPLPAR)&&+lppaca_shared_proc(local_paca->lppaca_ptr));+#else+returnfalse;+#endif+}+
CONFIG_PPC_SPLPAR depends on CONFIG_PPC_PSERIES, which depends on
CONFIG_PPC_BOOK3S so the #ifdef above is unnecessary:
if CONFIG_PPC_BOOK3S is unset then CONFIG_PPC_SPLPAR will be unset as
well and the return expression should short-circuit to false.
--
Thiago Jung Bauermann
IBM Linux Technology Center
From: Christopher M Riedl <hidden> Date: 2019-07-30 23:33:35
On July 30, 2019 at 4:31 PM Thiago Jung Bauermann [off-list ref] wrote:
Christopher M. Riedl [off-list ref] writes:
quoted
Determining if a processor is in shared processor mode is not a constant
so don't hide it behind a #define.
Signed-off-by: Christopher M. Riedl <redacted>
---
arch/powerpc/include/asm/spinlock.h | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
@@ -101,15 +101,24 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)#if defined(CONFIG_PPC_SPLPAR)/* We only yield to the hypervisor if we are in shared processor mode */-#define SHARED_PROCESSOR (lppaca_shared_proc(local_paca->lppaca_ptr))externvoid__spin_yield(arch_spinlock_t*lock);externvoid__rw_yield(arch_rwlock_t*lock);#else /* SPLPAR */#define __spin_yield(x) barrier()#define __rw_yield(x) barrier()-#define SHARED_PROCESSOR 0#endif+staticinlineboolis_shared_processor(void)+{+/* Only server processors have an lppaca struct */+#ifdef CONFIG_PPC_BOOK3S+return(IS_ENABLED(CONFIG_PPC_SPLPAR)&&+lppaca_shared_proc(local_paca->lppaca_ptr));+#else+returnfalse;+#endif+}+
CONFIG_PPC_SPLPAR depends on CONFIG_PPC_PSERIES, which depends on
CONFIG_PPC_BOOK3S so the #ifdef above is unnecessary:
if CONFIG_PPC_BOOK3S is unset then CONFIG_PPC_SPLPAR will be unset as
well and the return expression should short-circuit to false.
Agreed, but the #ifdef is necessary to compile platforms which include
this header but do not implement lppaca_shared_proc(...) and friends.
I can reword the comment if that helps.
--
Thiago Jung Bauermann
IBM Linux Technology Center
On July 30, 2019 at 4:31 PM Thiago Jung Bauermann [off-list ref] wrote:
Christopher M. Riedl [off-list ref] writes:
quoted
Determining if a processor is in shared processor mode is not a constant
so don't hide it behind a #define.
Signed-off-by: Christopher M. Riedl <redacted>
---
arch/powerpc/include/asm/spinlock.h | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
@@ -101,15 +101,24 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)#if defined(CONFIG_PPC_SPLPAR)/* We only yield to the hypervisor if we are in shared processor mode */-#define SHARED_PROCESSOR (lppaca_shared_proc(local_paca->lppaca_ptr))externvoid__spin_yield(arch_spinlock_t*lock);externvoid__rw_yield(arch_rwlock_t*lock);#else /* SPLPAR */#define __spin_yield(x) barrier()#define __rw_yield(x) barrier()-#define SHARED_PROCESSOR 0#endif+staticinlineboolis_shared_processor(void)+{+/* Only server processors have an lppaca struct */+#ifdef CONFIG_PPC_BOOK3S+return(IS_ENABLED(CONFIG_PPC_SPLPAR)&&+lppaca_shared_proc(local_paca->lppaca_ptr));+#else+returnfalse;+#endif+}+
CONFIG_PPC_SPLPAR depends on CONFIG_PPC_PSERIES, which depends on
CONFIG_PPC_BOOK3S so the #ifdef above is unnecessary:
if CONFIG_PPC_BOOK3S is unset then CONFIG_PPC_SPLPAR will be unset as
well and the return expression should short-circuit to false.
Agreed, but the #ifdef is necessary to compile platforms which include
this header but do not implement lppaca_shared_proc(...) and friends.
I can reword the comment if that helps.
Ah, indeed. Yes, if you could mention that in the commit I think it
would help. These #ifdefs are becoming démodé so it's good to know why
they're there.
Another alternative is to provide a dummy lppaca_shared_proc() which
always returns false when CONFIG_PPC_BOOK3S isn't set (just mentioning
it, I don't have a preference).
--
Thiago Jung Bauermann
IBM Linux Technology Center
From: Christopher M Riedl <hidden> Date: 2019-07-31 02:38:05
On July 30, 2019 at 7:11 PM Thiago Jung Bauermann [off-list ref] wrote:
Christopher M Riedl [off-list ref] writes:
quoted
quoted
On July 30, 2019 at 4:31 PM Thiago Jung Bauermann [off-list ref] wrote:
Christopher M. Riedl [off-list ref] writes:
quoted
Determining if a processor is in shared processor mode is not a constant
so don't hide it behind a #define.
Signed-off-by: Christopher M. Riedl <redacted>
---
arch/powerpc/include/asm/spinlock.h | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
@@ -101,15 +101,24 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)#if defined(CONFIG_PPC_SPLPAR)/* We only yield to the hypervisor if we are in shared processor mode */-#define SHARED_PROCESSOR (lppaca_shared_proc(local_paca->lppaca_ptr))externvoid__spin_yield(arch_spinlock_t*lock);externvoid__rw_yield(arch_rwlock_t*lock);#else /* SPLPAR */#define __spin_yield(x) barrier()#define __rw_yield(x) barrier()-#define SHARED_PROCESSOR 0#endif+staticinlineboolis_shared_processor(void)+{+/* Only server processors have an lppaca struct */+#ifdef CONFIG_PPC_BOOK3S+return(IS_ENABLED(CONFIG_PPC_SPLPAR)&&+lppaca_shared_proc(local_paca->lppaca_ptr));+#else+returnfalse;+#endif+}+
CONFIG_PPC_SPLPAR depends on CONFIG_PPC_PSERIES, which depends on
CONFIG_PPC_BOOK3S so the #ifdef above is unnecessary:
if CONFIG_PPC_BOOK3S is unset then CONFIG_PPC_SPLPAR will be unset as
well and the return expression should short-circuit to false.
Agreed, but the #ifdef is necessary to compile platforms which include
this header but do not implement lppaca_shared_proc(...) and friends.
I can reword the comment if that helps.
Ah, indeed. Yes, if you could mention that in the commit I think it
would help. These #ifdefs are becoming démodé so it's good to know why
they're there.
Another alternative is to provide a dummy lppaca_shared_proc() which
always returns false when CONFIG_PPC_BOOK3S isn't set (just mentioning
it, I don't have a preference).
Yeah, I tried that first, but the declaration and definition for lppaca_shared_proc()
and arguments are nested within several includes and arch/platform #ifdefs that I
decided the #ifdef in is_shared_processor() is simpler.
I am not sure if unraveling all that makes sense for implementing this fix, maybe
someone can convince me hah.
In any case, next version will have an improved commit message and comment.
--
Thiago Jung Bauermann
IBM Linux Technology Center
From: Andrew Donnellan <hidden> Date: 2019-08-01 03:23:05
On 28/7/19 10:54 pm, Christopher M. Riedl wrote:
Determining if a processor is in shared processor mode is not a constant
so don't hide it behind a #define.
Signed-off-by: Christopher M. Riedl <redacted>
This seems aesthetically more right.
Reviewed-by: Andrew Donnellan <redacted>
@@ -101,15 +101,24 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)#if defined(CONFIG_PPC_SPLPAR)/* We only yield to the hypervisor if we are in shared processor mode */-#define SHARED_PROCESSOR (lppaca_shared_proc(local_paca->lppaca_ptr))externvoid__spin_yield(arch_spinlock_t*lock);externvoid__rw_yield(arch_rwlock_t*lock);#else /* SPLPAR */#define __spin_yield(x) barrier()#define __rw_yield(x) barrier()-#define SHARED_PROCESSOR 0#endif+staticinlineboolis_shared_processor(void)+{+/* Only server processors have an lppaca struct */+#ifdef CONFIG_PPC_BOOK3S+return(IS_ENABLED(CONFIG_PPC_SPLPAR)&&+lppaca_shared_proc(local_paca->lppaca_ptr));+#else+returnfalse;+#endif+}+staticinlinevoidarch_spin_lock(arch_spinlock_t*lock){while(1){
From: Andrew Donnellan <hidden> Date: 2019-08-01 03:29:24
On 28/7/19 10:54 pm, Christopher M. Riedl wrote:
The __rw_yield and __spin_yield locks only pertain to SPLPAR mode.
Rename them to make this relationship obvious.
Signed-off-by: Christopher M. Riedl <redacted>
@@ -101,8 +101,10 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)#if defined(CONFIG_PPC_SPLPAR)/* We only yield to the hypervisor if we are in shared processor mode */-externvoid__spin_yield(arch_spinlock_t*lock);-externvoid__rw_yield(arch_rwlock_t*lock);+voidsplpar_spin_yield(arch_spinlock_t*lock);+voidsplpar_rw_yield(arch_rwlock_t*lock);+#define __spin_yield(x) splpar_spin_yield(x)+#define __rw_yield(x) splpar_rw_yield(x)#else /* SPLPAR */#define __spin_yield(x) barrier()#define __rw_yield(x) barrier()
@@ -103,11 +103,9 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock)/* We only yield to the hypervisor if we are in shared processor mode */voidsplpar_spin_yield(arch_spinlock_t*lock);voidsplpar_rw_yield(arch_rwlock_t*lock);-#define __spin_yield(x) splpar_spin_yield(x)-#define __rw_yield(x) splpar_rw_yield(x)#else /* SPLPAR */-#define __spin_yield(x) barrier()-#define __rw_yield(x) barrier()+#define splpar_spin_yield(lock)+#define splpar_rw_yield(lock)
I prefer using #ifdef on the function definition and declaring an
alternative function with an empty body for the !SPLPAR case, seeing an
empty #define just feels a bit weird