Commit | Line | Data |
---|---|---|
2874c5fd | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
40ef8cbc PM |
2 | /* |
3 | * Spin and read/write lock operations. | |
4 | * | |
5 | * Copyright (C) 2001-2004 Paul Mackerras <paulus@au.ibm.com>, IBM | |
6 | * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM | |
7 | * Copyright (C) 2002 Dave Engebretsen <engebret@us.ibm.com>, IBM | |
8 | * Rework to support virtual processors | |
40ef8cbc PM |
9 | */ |
10 | ||
40ef8cbc PM |
11 | #include <linux/kernel.h> |
12 | #include <linux/spinlock.h> | |
4b16f8e2 | 13 | #include <linux/export.h> |
734d6524 | 14 | #include <linux/smp.h> |
40ef8cbc PM |
15 | |
16 | /* waiting for a spinlock... */ | |
f5339277 | 17 | #if defined(CONFIG_PPC_SPLPAR) |
40ef8cbc | 18 | #include <asm/hvcall.h> |
2249ca9d | 19 | #include <asm/smp.h> |
40ef8cbc | 20 | |
31391ff7 | 21 | void splpar_spin_yield(arch_spinlock_t *lock) |
40ef8cbc PM |
22 | { |
23 | unsigned int lock_value, holder_cpu, yield_count; | |
40ef8cbc PM |
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); | |
7ffcf8ec | 30 | yield_count = be32_to_cpu(lppaca_of(holder_cpu).yield_count); |
40ef8cbc PM |
31 | if ((yield_count & 1) == 0) |
32 | return; /* virtual cpu is currently running */ | |
33 | rmb(); | |
34 | if (lock->slock != lock_value) | |
35 | return; /* something has changed */ | |
f5339277 SR |
36 | plpar_hcall_norets(H_CONFER, |
37 | get_hard_smp_processor_id(holder_cpu), yield_count); | |
40ef8cbc | 38 | } |
31391ff7 | 39 | EXPORT_SYMBOL_GPL(splpar_spin_yield); |
40ef8cbc PM |
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 | */ | |
31391ff7 | 46 | void splpar_rw_yield(arch_rwlock_t *rw) |
40ef8cbc PM |
47 | { |
48 | int lock_value; | |
49 | unsigned int holder_cpu, yield_count; | |
40ef8cbc PM |
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); | |
7ffcf8ec | 56 | yield_count = be32_to_cpu(lppaca_of(holder_cpu).yield_count); |
40ef8cbc PM |
57 | if ((yield_count & 1) == 0) |
58 | return; /* virtual cpu is currently running */ | |
59 | rmb(); | |
60 | if (rw->lock != lock_value) | |
61 | return; /* something has changed */ | |
f5339277 SR |
62 | plpar_hcall_norets(H_CONFER, |
63 | get_hard_smp_processor_id(holder_cpu), yield_count); | |
40ef8cbc PM |
64 | } |
65 | #endif |