Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Out-of-line refcount functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/refcount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #define REFCOUNT_WARN(str)	WARN_ONCE(1, "refcount_t: " str ".\n")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) void refcount_warn_saturate(refcount_t *r, enum refcount_saturation_type t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 	refcount_set(r, REFCOUNT_SATURATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	switch (t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	case REFCOUNT_ADD_NOT_ZERO_OVF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 		REFCOUNT_WARN("saturated; leaking memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	case REFCOUNT_ADD_OVF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 		REFCOUNT_WARN("saturated; leaking memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	case REFCOUNT_ADD_UAF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 		REFCOUNT_WARN("addition on 0; use-after-free");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	case REFCOUNT_SUB_UAF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		REFCOUNT_WARN("underflow; use-after-free");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	case REFCOUNT_DEC_LEAK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		REFCOUNT_WARN("decrement hit 0; leaking memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		REFCOUNT_WARN("unknown saturation event!?");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) EXPORT_SYMBOL(refcount_warn_saturate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * refcount_dec_if_one - decrement a refcount if it is 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * @r: the refcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * No atomic_t counterpart, it attempts a 1 -> 0 transition and returns the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * success thereof.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * Like all decrement operations, it provides release memory order and provides
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * a control dependency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * It can be used like a try-delete operator; this explicit case is provided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * and not cmpxchg in generic, because that would allow implementing unsafe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * Return: true if the resulting refcount is 0, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) bool refcount_dec_if_one(refcount_t *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	int val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	return atomic_try_cmpxchg_release(&r->refs, &val, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) EXPORT_SYMBOL(refcount_dec_if_one);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * refcount_dec_not_one - decrement a refcount if it is not 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  * @r: the refcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * No atomic_t counterpart, it decrements unless the value is 1, in which case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * it will return false.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * Was often done like: atomic_add_unless(&var, -1, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * Return: true if the decrement operation was successful, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) bool refcount_dec_not_one(refcount_t *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	unsigned int new, val = atomic_read(&r->refs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		if (unlikely(val == REFCOUNT_SATURATED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		if (val == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		new = val - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		if (new > val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 			WARN_ONCE(new > val, "refcount_t: underflow; use-after-free.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	} while (!atomic_try_cmpxchg_release(&r->refs, &val, new));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) EXPORT_SYMBOL(refcount_dec_not_one);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * refcount_dec_and_mutex_lock - return holding mutex if able to decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  *                               refcount to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * @r: the refcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * @lock: the mutex to be locked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  * Similar to atomic_dec_and_mutex_lock(), it will WARN on underflow and fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  * to decrement when saturated at REFCOUNT_SATURATED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  * Provides release memory ordering, such that prior loads and stores are done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  * before, and provides a control dependency such that free() must come after.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  * See the comment on top.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  * Return: true and hold mutex if able to decrement refcount to 0, false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  *         otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	if (refcount_dec_not_one(r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	mutex_lock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	if (!refcount_dec_and_test(r)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		mutex_unlock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) EXPORT_SYMBOL(refcount_dec_and_mutex_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  * refcount_dec_and_lock - return holding spinlock if able to decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  *                         refcount to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * @r: the refcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * @lock: the spinlock to be locked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  * Similar to atomic_dec_and_lock(), it will WARN on underflow and fail to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  * decrement when saturated at REFCOUNT_SATURATED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * Provides release memory ordering, such that prior loads and stores are done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  * before, and provides a control dependency such that free() must come after.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * See the comment on top.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * Return: true and hold spinlock if able to decrement refcount to 0, false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  *         otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) bool refcount_dec_and_lock(refcount_t *r, spinlock_t *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (refcount_dec_not_one(r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	spin_lock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	if (!refcount_dec_and_test(r)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		spin_unlock(lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) EXPORT_SYMBOL(refcount_dec_and_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  * refcount_dec_and_lock_irqsave - return holding spinlock with disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  *                                 interrupts if able to decrement refcount to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  * @r: the refcount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)  * @lock: the spinlock to be locked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)  * @flags: saved IRQ-flags if the is acquired
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  * Same as refcount_dec_and_lock() above except that the spinlock is acquired
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  * with disabled interupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  * Return: true and hold spinlock if able to decrement refcount to 0, false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  *         otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) bool refcount_dec_and_lock_irqsave(refcount_t *r, spinlock_t *lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 				   unsigned long *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	if (refcount_dec_not_one(r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	spin_lock_irqsave(lock, *flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	if (!refcount_dec_and_test(r)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		spin_unlock_irqrestore(lock, *flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) EXPORT_SYMBOL(refcount_dec_and_lock_irqsave);