.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
---|
1 | 2 | /* |
---|
2 | 3 | * Queued spinlock |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License as published by |
---|
6 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
7 | | - * (at your option) any later version. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope that it will be useful, |
---|
10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | | - * GNU General Public License for more details. |
---|
13 | 4 | * |
---|
14 | 5 | * (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P. |
---|
15 | 6 | * (C) Copyright 2015 Hewlett-Packard Enterprise Development LP |
---|
.. | .. |
---|
20 | 11 | #define __ASM_GENERIC_QSPINLOCK_H |
---|
21 | 12 | |
---|
22 | 13 | #include <asm-generic/qspinlock_types.h> |
---|
| 14 | +#include <linux/atomic.h> |
---|
23 | 15 | |
---|
| 16 | +#ifndef queued_spin_is_locked |
---|
24 | 17 | /** |
---|
25 | 18 | * queued_spin_is_locked - is the spinlock locked? |
---|
26 | 19 | * @lock: Pointer to queued spinlock structure |
---|
.. | .. |
---|
34 | 27 | */ |
---|
35 | 28 | return atomic_read(&lock->val); |
---|
36 | 29 | } |
---|
| 30 | +#endif |
---|
37 | 31 | |
---|
38 | 32 | /** |
---|
39 | 33 | * queued_spin_value_unlocked - is the spinlock structure unlocked? |
---|
.. | .. |
---|
66 | 60 | */ |
---|
67 | 61 | static __always_inline int queued_spin_trylock(struct qspinlock *lock) |
---|
68 | 62 | { |
---|
69 | | - if (!atomic_read(&lock->val) && |
---|
70 | | - (atomic_cmpxchg_acquire(&lock->val, 0, _Q_LOCKED_VAL) == 0)) |
---|
71 | | - return 1; |
---|
72 | | - return 0; |
---|
| 63 | + u32 val = atomic_read(&lock->val); |
---|
| 64 | + |
---|
| 65 | + if (unlikely(val)) |
---|
| 66 | + return 0; |
---|
| 67 | + |
---|
| 68 | + return likely(atomic_try_cmpxchg_acquire(&lock->val, &val, _Q_LOCKED_VAL)); |
---|
73 | 69 | } |
---|
74 | 70 | |
---|
75 | 71 | extern void queued_spin_lock_slowpath(struct qspinlock *lock, u32 val); |
---|
76 | 72 | |
---|
| 73 | +#ifndef queued_spin_lock |
---|
77 | 74 | /** |
---|
78 | 75 | * queued_spin_lock - acquire a queued spinlock |
---|
79 | 76 | * @lock: Pointer to queued spinlock structure |
---|
80 | 77 | */ |
---|
81 | 78 | static __always_inline void queued_spin_lock(struct qspinlock *lock) |
---|
82 | 79 | { |
---|
83 | | - u32 val; |
---|
| 80 | + u32 val = 0; |
---|
84 | 81 | |
---|
85 | | - val = atomic_cmpxchg_acquire(&lock->val, 0, _Q_LOCKED_VAL); |
---|
86 | | - if (likely(val == 0)) |
---|
| 82 | + if (likely(atomic_try_cmpxchg_acquire(&lock->val, &val, _Q_LOCKED_VAL))) |
---|
87 | 83 | return; |
---|
| 84 | + |
---|
88 | 85 | queued_spin_lock_slowpath(lock, val); |
---|
89 | 86 | } |
---|
| 87 | +#endif |
---|
90 | 88 | |
---|
91 | 89 | #ifndef queued_spin_unlock |
---|
92 | 90 | /** |
---|