lkml.org 
[lkml]   [2020]   [Jul]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
SubjectRe: [PATCH 6/8] powerpc/pseries: implement paravirt qspinlocks for SPLPAR
From
Date
On 7/2/20 3:48 AM, Nicholas Piggin wrote:
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> arch/powerpc/include/asm/paravirt.h | 23 ++++++++
> arch/powerpc/include/asm/qspinlock.h | 55 +++++++++++++++++++
> arch/powerpc/include/asm/qspinlock_paravirt.h | 5 ++
> arch/powerpc/platforms/pseries/Kconfig | 5 ++
> arch/powerpc/platforms/pseries/setup.c | 6 +-
> include/asm-generic/qspinlock.h | 2 +
> 6 files changed, 95 insertions(+), 1 deletion(-)
> create mode 100644 arch/powerpc/include/asm/qspinlock_paravirt.h
>
> diff --git a/arch/powerpc/include/asm/paravirt.h b/arch/powerpc/include/asm/paravirt.h
> index 7a8546660a63..5fae9dfa6fe9 100644
> --- a/arch/powerpc/include/asm/paravirt.h
> +++ b/arch/powerpc/include/asm/paravirt.h
> @@ -29,6 +29,16 @@ static inline void yield_to_preempted(int cpu, u32 yield_count)
> {
> plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(cpu), yield_count);
> }
> +
> +static inline void prod_cpu(int cpu)
> +{
> + plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu));
> +}
> +
> +static inline void yield_to_any(void)
> +{
> + plpar_hcall_norets(H_CONFER, -1, 0);
> +}
> #else
> static inline bool is_shared_processor(void)
> {
> @@ -45,6 +55,19 @@ static inline void yield_to_preempted(int cpu, u32 yield_count)
> {
> ___bad_yield_to_preempted(); /* This would be a bug */
> }
> +
> +extern void ___bad_yield_to_any(void);
> +static inline void yield_to_any(void)
> +{
> + ___bad_yield_to_any(); /* This would be a bug */
> +}
> +
> +extern void ___bad_prod_cpu(void);
> +static inline void prod_cpu(int cpu)
> +{
> + ___bad_prod_cpu(); /* This would be a bug */
> +}
> +
> #endif
>
> #define vcpu_is_preempted vcpu_is_preempted
> diff --git a/arch/powerpc/include/asm/qspinlock.h b/arch/powerpc/include/asm/qspinlock.h
> index f84da77b6bb7..997a9a32df77 100644
> --- a/arch/powerpc/include/asm/qspinlock.h
> +++ b/arch/powerpc/include/asm/qspinlock.h
> @@ -3,9 +3,36 @@
> #define _ASM_POWERPC_QSPINLOCK_H
>
> #include <asm-generic/qspinlock_types.h>
> +#include <asm/paravirt.h>
>
> #define _Q_PENDING_LOOPS (1 << 9) /* not tuned */
>
> +#ifdef CONFIG_PARAVIRT_SPINLOCKS
> +extern void native_queued_spin_lock_slowpath(struct qspinlock *lock, u32 val);
> +extern void __pv_queued_spin_lock_slowpath(struct qspinlock *lock, u32 val);
> +
> +static __always_inline void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val)
> +{
> + if (!is_shared_processor())
> + native_queued_spin_lock_slowpath(lock, val);
> + else
> + __pv_queued_spin_lock_slowpath(lock, val);
> +}

You may need to match the use of __pv_queued_spin_lock_slowpath() with
the corresponding __pv_queued_spin_unlock(), e.g.

#define queued_spin_unlock queued_spin_unlock
static inline queued_spin_unlock(struct qspinlock *lock)
{
        if (!is_shared_processor())
                smp_store_release(&lock->locked, 0);
        else
                __pv_queued_spin_unlock(lock);
}

Otherwise, pv_kick() will never be called.

Cheers,
Longman

\
 
 \ /
  Last update: 2020-07-02 23:02    [W:0.126 / U:0.520 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site