diff options
author | Vladimir Kondratyev <wulf@FreeBSD.org> | 2021-07-05 00:19:01 +0000 |
---|---|---|
committer | Vladimir Kondratyev <wulf@FreeBSD.org> | 2021-07-05 00:19:01 +0000 |
commit | c77ec79b57aa92b428b940ed550a4a14ed44da48 (patch) | |
tree | e46a20c445c48318c2383080f144e96cf757d160 /sys/compat/linuxkpi | |
parent | 78a02d8b332cd46e26e1a8088cd0ba5220cd1f18 (diff) | |
download | src-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')
-rw-r--r-- | sys/compat/linuxkpi/common/include/linux/spinlock.h | 17 |
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_ */ |