The generic implementation of refcount_t should be good enough for everybody, so remove ARCH_HAS_REFCOUNT and REFCOUNT_FULL entirely, leaving the generic implementation enabled unconditionally.
Showing the changes to include/linux (1 of 11 files). Show all
Unified · Split
| @@ -1,64 +1,4 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | #ifndef _LINUX_REFCOUNT_H | ||
| 3 | #define _LINUX_REFCOUNT_H | ||
| 4 | |||
| 5 | #include <linux/atomic.h> | ||
| 6 | #include <linux/compiler.h> | ||
| 7 | #include <linux/limits.h> | ||
| 8 | #include <linux/spinlock_types.h> | ||
| 9 | |||
| 10 | struct mutex; | ||
| 11 | |||
| 12 | /** | ||
| 13 | * struct refcount_t - variant of atomic_t specialized for reference counts | ||
| 14 | * @refs: atomic_t counter field | ||
| 15 | * | ||
| 16 | * The counter saturates at REFCOUNT_SATURATED and will not move once | ||
| 17 | * there. This avoids wrapping the counter and causing 'spurious' | ||
| 18 | * use-after-free bugs. | ||
| 19 | */ | ||
| 20 | typedef struct refcount_struct { | ||
| 21 | atomic_t refs; | ||
| 22 | } refcount_t; | ||
| 23 | |||
| 24 | #define REFCOUNT_INIT(n) { .refs = ATOMIC_INIT(n), } | ||
| 25 | #define REFCOUNT_MAX INT_MAX | ||
| 26 | #define REFCOUNT_SATURATED (INT_MIN / 2) | ||
| 27 | |||
| 28 | enum refcount_saturation_type { | ||
| 29 | REFCOUNT_ADD_NOT_ZERO_OVF, | ||
| 30 | REFCOUNT_ADD_OVF, | ||
| 31 | REFCOUNT_ADD_UAF, | ||
| 32 | REFCOUNT_SUB_UAF, | ||
| 33 | REFCOUNT_DEC_LEAK, | ||
| 34 | }; | ||
| 35 | |||
| 36 | void refcount_warn_saturate(refcount_t *r, enum refcount_saturation_type t); | ||
| 37 | |||
| 38 | /** | ||
| 39 | * refcount_set - set a refcount's value | ||
| 40 | * @r: the refcount | ||
| 41 | * @n: value to which the refcount will be set | ||
| 42 | */ | ||
| 43 | static inline void refcount_set(refcount_t *r, int n) | ||
| 44 | { | ||
| 45 | atomic_set(&r->refs, n); | ||
| 46 | } | ||
| 47 | |||
| 48 | /** | ||
| 49 | * refcount_read - get a refcount's value | ||
| 50 | * @r: the refcount | ||
| 51 | * | ||
| 52 | * Return: the refcount's value | ||
| 53 | */ | ||
| 54 | static inline unsigned int refcount_read(const refcount_t *r) | ||
| 55 | { | ||
| 56 | return atomic_read(&r->refs); | ||
| 57 | } | ||
| 58 | |||
| 59 | #ifdef CONFIG_REFCOUNT_FULL | ||
| 60 | #include <linux/bug.h> | ||
| 61 | |||
| 62 | /* | 2 | /* |
| 63 | * Variant of atomic_t specialized for reference counts. | 3 | * Variant of atomic_t specialized for reference counts. |
| 64 | * | 4 | * |
| @@ -136,6 +76,64 @@ static inline unsigned int refcount_read(const refcount_t *r) · 71 unmodified lines | |||
| 136 | * | 76 | * |
| 137 | */ | 77 | */ |
| 138 | 78 | ||
| 79 | #ifndef _LINUX_REFCOUNT_H | ||
| 80 | #define _LINUX_REFCOUNT_H | ||
| 81 | |||
| 82 | #include <linux/atomic.h> | ||
| 83 | #include <linux/bug.h> | ||
| 84 | #include <linux/compiler.h> | ||
| 85 | #include <linux/limits.h> | ||
| 86 | #include <linux/spinlock_types.h> | ||
| 87 | |||
| 88 | struct mutex; | ||
| 89 | |||
| 90 | /** | ||
| 91 | * struct refcount_t - variant of atomic_t specialized for reference counts | ||
| 92 | * @refs: atomic_t counter field | ||
| 93 | * | ||
| 94 | * The counter saturates at REFCOUNT_SATURATED and will not move once | ||
| 95 | * there. This avoids wrapping the counter and causing 'spurious' | ||
| 96 | * use-after-free bugs. | ||
| 97 | */ | ||
| 98 | typedef struct refcount_struct { | ||
| 99 | atomic_t refs; | ||
| 100 | } refcount_t; | ||
| 101 | |||
| 102 | #define REFCOUNT_INIT(n) { .refs = ATOMIC_INIT(n), } | ||
| 103 | #define REFCOUNT_MAX INT_MAX | ||
| 104 | #define REFCOUNT_SATURATED (INT_MIN / 2) | ||
| 105 | |||
| 106 | enum refcount_saturation_type { | ||
| 107 | REFCOUNT_ADD_NOT_ZERO_OVF, | ||
| 108 | REFCOUNT_ADD_OVF, | ||
| 109 | REFCOUNT_ADD_UAF, | ||
| 110 | REFCOUNT_SUB_UAF, | ||
| 111 | REFCOUNT_DEC_LEAK, | ||
| 112 | }; | ||
| 113 | |||
| 114 | void refcount_warn_saturate(refcount_t *r, enum refcount_saturation_type t); | ||
| 115 | |||
| 116 | /** | ||
| 117 | * refcount_set - set a refcount's value | ||
| 118 | * @r: the refcount | ||
| 119 | * @n: value to which the refcount will be set | ||
| 120 | */ | ||
| 121 | static inline void refcount_set(refcount_t *r, int n) | ||
| 122 | { | ||
| 123 | atomic_set(&r->refs, n); | ||
| 124 | } | ||
| 125 | |||
| 126 | /** | ||
| 127 | * refcount_read - get a refcount's value | ||
| 128 | * @r: the refcount | ||
| 129 | * | ||
| 130 | * Return: the refcount's value | ||
| 131 | */ | ||
| 132 | static inline unsigned int refcount_read(const refcount_t *r) | ||
| 133 | { | ||
| 134 | return atomic_read(&r->refs); | ||
| 135 | } | ||
| 136 | |||
| 139 | /** | 137 | /** |
| 140 | * refcount_add_not_zero - add a value to a refcount unless it is 0 | 138 | * refcount_add_not_zero - add a value to a refcount unless it is 0 |
| 141 | * @i: the value to add to the refcount | 139 | * @i: the value to add to the refcount |
| @@ -298,46 +296,6 @@ static inline void refcount_dec(refcount_t *r) · 156 unmodified lines | |||
| 298 | if (unlikely(atomic_fetch_sub_release(1, &r->refs) <= 1)) | 296 | if (unlikely(atomic_fetch_sub_release(1, &r->refs) <= 1)) |
| 299 | refcount_warn_saturate(r, REFCOUNT_DEC_LEAK); | 297 | refcount_warn_saturate(r, REFCOUNT_DEC_LEAK); |
| 300 | } | 298 | } |
| 301 | #else /* CONFIG_REFCOUNT_FULL */ | ||
| 302 | # ifdef CONFIG_ARCH_HAS_REFCOUNT | ||
| 303 | # include <asm/refcount.h> | ||
| 304 | # else | ||
| 305 | static inline __must_check bool refcount_add_not_zero(int i, refcount_t *r) | ||
| 306 | { | ||
| 307 | return atomic_add_unless(&r->refs, i, 0); | ||
| 308 | } | ||
| 309 | |||
| 310 | static inline void refcount_add(int i, refcount_t *r) | ||
| 311 | { | ||
| 312 | atomic_add(i, &r->refs); | ||
| 313 | } | ||
| 314 | |||
| 315 | static inline __must_check bool refcount_inc_not_zero(refcount_t *r) | ||
| 316 | { | ||
| 317 | return atomic_add_unless(&r->refs, 1, 0); | ||
| 318 | } | ||
| 319 | |||
| 320 | static inline void refcount_inc(refcount_t *r) | ||
| 321 | { | ||
| 322 | atomic_inc(&r->refs); | ||
| 323 | } | ||
| 324 | |||
| 325 | static inline __must_check bool refcount_sub_and_test(int i, refcount_t *r) | ||
| 326 | { | ||
| 327 | return atomic_sub_and_test(i, &r->refs); | ||
| 328 | } | ||
| 329 | |||
| 330 | static inline __must_check bool refcount_dec_and_test(refcount_t *r) | ||
| 331 | { | ||
| 332 | return atomic_dec_and_test(&r->refs); | ||
| 333 | } | ||
| 334 | |||
| 335 | static inline void refcount_dec(refcount_t *r) | ||
| 336 | { | ||
| 337 | atomic_dec(&r->refs); | ||
| 338 | } | ||
| 339 | # endif /* !CONFIG_ARCH_HAS_REFCOUNT */ | ||
| 340 | #endif /* !CONFIG_REFCOUNT_FULL */ | ||
| 341 | 299 | ||
| 342 | extern __must_check bool refcount_dec_if_one(refcount_t *r); | 300 | extern __must_check bool refcount_dec_if_one(refcount_t *r); |
| 343 | extern __must_check bool refcount_dec_not_one(refcount_t *r); | 301 | extern __must_check bool refcount_dec_not_one(refcount_t *r); |