diff --git a/sys/compat/linuxkpi/common/include/linux/kref.h b/sys/compat/linuxkpi/common/include/linux/kref.h index 2c59794f4ddc..3b5645bf139b 100644 --- a/sys/compat/linuxkpi/common/include/linux/kref.h +++ b/sys/compat/linuxkpi/common/include/linux/kref.h @@ -1,131 +1,132 @@ /*- * Copyright (c) 2010 Isilon Systems, Inc. * Copyright (c) 2010 iX Systems, Inc. * Copyright (c) 2010 Panasas, Inc. * Copyright (c) 2013-2015 Mellanox Technologies, Ltd. * Copyright (c) 2013 François Tigeot * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice unmodified, this list of conditions, and the following * disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_KREF_H_ #define _LINUXKPI_LINUX_KREF_H_ #include #include #include #include #include #include #include struct kref { + /* XXX In Linux this is a refcount_t */ atomic_t refcount; }; static inline void kref_init(struct kref *kref) { refcount_init(&kref->refcount.counter, 1); } static inline unsigned int kref_read(const struct kref *kref) { return (atomic_read(&kref->refcount)); } static inline void kref_get(struct kref *kref) { refcount_acquire(&kref->refcount.counter); } static inline int kref_put(struct kref *kref, void (*rel)(struct kref *kref)) { if (refcount_release(&kref->refcount.counter)) { rel(kref); return 1; } return 0; } static inline int kref_put_lock(struct kref *kref, void (*rel)(struct kref *kref), spinlock_t *lock) { if (refcount_release(&kref->refcount.counter)) { spin_lock(lock); rel(kref); return (1); } return (0); } static inline int kref_sub(struct kref *kref, unsigned int count, void (*rel)(struct kref *kref)) { while (count--) { if (refcount_release(&kref->refcount.counter)) { rel(kref); return 1; } } return 0; } static inline int __must_check kref_get_unless_zero(struct kref *kref) { return atomic_add_unless(&kref->refcount, 1, 0); } static inline int kref_put_mutex(struct kref *kref, void (*release)(struct kref *kref), struct mutex *lock) { WARN_ON(release == NULL); if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) { mutex_lock(lock); if (unlikely(!atomic_dec_and_test(&kref->refcount))) { mutex_unlock(lock); return 0; } release(kref); return 1; } return 0; } #endif /* _LINUXKPI_LINUX_KREF_H_ */ diff --git a/sys/compat/linuxkpi/common/include/linux/refcount.h b/sys/compat/linuxkpi/common/include/linux/refcount.h index 7c055fb32029..6a49da530c0a 100644 --- a/sys/compat/linuxkpi/common/include/linux/refcount.h +++ b/sys/compat/linuxkpi/common/include/linux/refcount.h @@ -1,82 +1,93 @@ /*- * Copyright (c) 2020 The FreeBSD Foundation * * This software was developed by Emmanuel Vadot under sponsorship * from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _LINUXKPI_LINUX_REFCOUNT_H #define _LINUXKPI_LINUX_REFCOUNT_H #include struct refcount_linux { atomic_t value; }; typedef struct refcount_linux refcount_t; static inline void refcount_set(refcount_t *ref, unsigned int i) { atomic_set(&ref->value, i); } static inline void refcount_inc(refcount_t *ref) { atomic_inc(&ref->value); } static inline bool refcount_inc_not_zero(refcount_t *ref) { return (atomic_inc_not_zero(&ref->value)); } static inline void refcount_dec(refcount_t *ref) { atomic_dec(&ref->value); } static inline unsigned int refcount_read(refcount_t *ref) { return atomic_read(&ref->value); } static inline bool refcount_dec_and_lock_irqsave(refcount_t *ref, spinlock_t *lock, unsigned long *flags) { if (atomic_dec_and_test(&ref->value) == true) { spin_lock_irqsave(lock, flags); return (true); } return (false); } +/* + * struct kref uses atomic_t and not refcount_t so + * we differ from Linux here. + */ +static inline bool +refcount_dec_and_test(atomic_t *r) +{ + + return (atomic_dec_and_test(r)); +} + #endif /* __LINUXKPI_LINUX_REFCOUNT_H__ */