Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/powerpc/lib/locks.c
26486 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Spin and read/write lock operations.
4
*
5
* Copyright (C) 2001-2004 Paul Mackerras <[email protected]>, IBM
6
* Copyright (C) 2001 Anton Blanchard <[email protected]>, IBM
7
* Copyright (C) 2002 Dave Engebretsen <[email protected]>, IBM
8
* Rework to support virtual processors
9
*/
10
11
#include <linux/kernel.h>
12
#include <linux/spinlock.h>
13
#include <linux/export.h>
14
#include <linux/smp.h>
15
16
/* waiting for a spinlock... */
17
#if defined(CONFIG_PPC_SPLPAR)
18
#include <asm/hvcall.h>
19
#include <asm/smp.h>
20
21
void splpar_spin_yield(arch_spinlock_t *lock)
22
{
23
unsigned int lock_value, holder_cpu, yield_count;
24
25
lock_value = lock->slock;
26
if (lock_value == 0)
27
return;
28
holder_cpu = lock_value & 0xffff;
29
BUG_ON(holder_cpu >= NR_CPUS);
30
31
yield_count = yield_count_of(holder_cpu);
32
if ((yield_count & 1) == 0)
33
return; /* virtual cpu is currently running */
34
rmb();
35
if (lock->slock != lock_value)
36
return; /* something has changed */
37
yield_to_preempted(holder_cpu, yield_count);
38
}
39
EXPORT_SYMBOL_GPL(splpar_spin_yield);
40
41
/*
42
* Waiting for a read lock or a write lock on a rwlock...
43
* This turns out to be the same for read and write locks, since
44
* we only know the holder if it is write-locked.
45
*/
46
void splpar_rw_yield(arch_rwlock_t *rw)
47
{
48
int lock_value;
49
unsigned int holder_cpu, yield_count;
50
51
lock_value = rw->lock;
52
if (lock_value >= 0)
53
return; /* no write lock at present */
54
holder_cpu = lock_value & 0xffff;
55
BUG_ON(holder_cpu >= NR_CPUS);
56
57
yield_count = yield_count_of(holder_cpu);
58
if ((yield_count & 1) == 0)
59
return; /* virtual cpu is currently running */
60
rmb();
61
if (rw->lock != lock_value)
62
return; /* something has changed */
63
yield_to_preempted(holder_cpu, yield_count);
64
}
65
#endif
66
67