2019-05-27 08:55:01 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2005-10-10 22:50:37 +10:00
/*
* Spin and read / write lock operations .
*
* Copyright ( C ) 2001 - 2004 Paul Mackerras < paulus @ au . ibm . com > , IBM
* Copyright ( C ) 2001 Anton Blanchard < anton @ au . ibm . com > , IBM
* Copyright ( C ) 2002 Dave Engebretsen < engebret @ us . ibm . com > , IBM
* Rework to support virtual processors
*/
# include <linux/kernel.h>
# include <linux/spinlock.h>
2011-07-22 18:24:23 -04:00
# include <linux/export.h>
2005-10-31 13:57:01 +11:00
# include <linux/smp.h>
2005-10-10 22:50:37 +10:00
/* waiting for a spinlock... */
2012-03-15 18:18:00 +00:00
# if defined(CONFIG_PPC_SPLPAR)
2005-10-10 22:50:37 +10:00
# include <asm/hvcall.h>
2005-11-07 13:18:13 +11:00
# include <asm/smp.h>
2005-10-10 22:50:37 +10:00
2019-08-12 22:13:13 -05:00
void splpar_spin_yield ( arch_spinlock_t * lock )
2005-10-10 22:50:37 +10:00
{
unsigned int lock_value , holder_cpu , yield_count ;
lock_value = lock - > slock ;
if ( lock_value = = 0 )
return ;
holder_cpu = lock_value & 0xffff ;
BUG_ON ( holder_cpu > = NR_CPUS ) ;
2020-07-24 23:14:18 +10:00
yield_count = yield_count_of ( holder_cpu ) ;
2005-10-10 22:50:37 +10:00
if ( ( yield_count & 1 ) = = 0 )
return ; /* virtual cpu is currently running */
rmb ( ) ;
if ( lock - > slock ! = lock_value )
return ; /* something has changed */
2020-07-24 23:14:18 +10:00
yield_to_preempted ( holder_cpu , yield_count ) ;
2005-10-10 22:50:37 +10:00
}
2019-08-12 22:13:13 -05:00
EXPORT_SYMBOL_GPL ( splpar_spin_yield ) ;
2005-10-10 22:50:37 +10:00
/*
* Waiting for a read lock or a write lock on a rwlock . . .
* This turns out to be the same for read and write locks , since
* we only know the holder if it is write - locked .
*/
2019-08-12 22:13:13 -05:00
void splpar_rw_yield ( arch_rwlock_t * rw )
2005-10-10 22:50:37 +10:00
{
int lock_value ;
unsigned int holder_cpu , yield_count ;
lock_value = rw - > lock ;
if ( lock_value > = 0 )
return ; /* no write lock at present */
holder_cpu = lock_value & 0xffff ;
BUG_ON ( holder_cpu > = NR_CPUS ) ;
2020-07-24 23:14:18 +10:00
yield_count = yield_count_of ( holder_cpu ) ;
2005-10-10 22:50:37 +10:00
if ( ( yield_count & 1 ) = = 0 )
return ; /* virtual cpu is currently running */
rmb ( ) ;
if ( rw - > lock ! = lock_value )
return ; /* something has changed */
2020-07-24 23:14:18 +10:00
yield_to_preempted ( holder_cpu , yield_count ) ;
2005-10-10 22:50:37 +10:00
}
# endif