aboutsummaryrefslogtreecommitdiff
path: root/sys/compat/linuxkpi/common/include/linux
diff options
context:
space:
mode:
authorVladimir Kondratyev <wulf@FreeBSD.org>2021-07-05 00:19:01 +0000
committerVladimir Kondratyev <wulf@FreeBSD.org>2021-07-05 00:19:01 +0000
commitc77ec79b57aa92b428b940ed550a4a14ed44da48 (patch)
treee46a20c445c48318c2383080f144e96cf757d160 /sys/compat/linuxkpi/common/include/linux
parent78a02d8b332cd46e26e1a8088cd0ba5220cd1f18 (diff)
downloadsrc-c77ec79b57aa92b428b940ed550a4a14ed44da48.tar.gz
src-c77ec79b57aa92b428b940ed550a4a14ed44da48.zip
LinuxKPI: Change flags parameter type of atomic_dec_and_lock_irqsave
On Linux atomic_dec_and_lock_irqsave is a wrapper macro which provides a reference to third parameter rather than parameter value itself to implementation routine called _atomic_dec_and_lock_irqsave [1]. While here, implement a fast path. [1] https://github.com/torvalds/linux/blob/master/include/linux/spinlock.h#L476 Reviewed by: hselasky Differential revision: https://reviews.freebsd.org/D30781
Diffstat (limited to 'sys/compat/linuxkpi/common/include/linux')
-rw-r--r--sys/compat/linuxkpi/common/include/linux/spinlock.h17
1 files changed, 11 insertions, 6 deletions
diff --git a/sys/compat/linuxkpi/common/include/linux/spinlock.h b/sys/compat/linuxkpi/common/include/linux/spinlock.h
index ca51fd23434c..46b1f8b9a180 100644
--- a/sys/compat/linuxkpi/common/include/linux/spinlock.h
+++ b/sys/compat/linuxkpi/common/include/linux/spinlock.h
@@ -163,15 +163,20 @@ spin_lock_destroy(spinlock_t *lock)
mtx_assert(&(_l)->m, MA_OWNED); \
} while (0)
+#define atomic_dec_and_lock_irqsave(cnt, lock, flags) \
+ _atomic_dec_and_lock_irqsave(cnt, lock, &(flags))
static inline int
-atomic_dec_and_lock_irqsave(atomic_t *cnt, spinlock_t *lock,
- unsigned long flags)
+_atomic_dec_and_lock_irqsave(atomic_t *cnt, spinlock_t *lock,
+ unsigned long *flags)
{
- spin_lock_irqsave(lock, flags);
+ if (atomic_add_unless(cnt, -1, 1))
+ return (0);
+
+ spin_lock_irqsave(lock, *flags);
if (atomic_dec_and_test(cnt))
- return 1;
- spin_unlock_irqrestore(lock, flags);
- return 0;
+ return (1);
+ spin_unlock_irqrestore(lock, *flags);
+ return (0);
}
#endif /* _LINUX_SPINLOCK_H_ */