History

locking/refcount: Consolidate implementations of refcount_t

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.

Will Deacon committed 6 years ago

Commit fb041bb1 parent 65b008511 files · +59 −308Browse files

Showing the changes to include/linux (1 of 11 files). Show all

Unified · Split

include/linux/refcount.h+58−100
@@ -1,64 +1,4 @@
11 /* 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−
622 /*
633 * Variant of atomic_t specialized for reference counts.
644 *
@@ -136,6 +76,64 @@ static inline unsigned int refcount_read(const refcount_t *r) · 71 unmodified lines
13676 *
13777 */
13878
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+
139137 /**
140138 * refcount_add_not_zero - add a value to a refcount unless it is 0
141139 * @i: the value to add to the refcount
@@ -298,46 +296,6 @@ static inline void refcount_dec(refcount_t *r) · 156 unmodified lines
298296 if (unlikely(atomic_fetch_sub_release(1, &r->refs) <= 1))
299297 refcount_warn_saturate(r, REFCOUNT_DEC_LEAK);
300298 }
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 */
341299
342300 extern __must_check bool refcount_dec_if_one(refcount_t *r);
343301 extern __must_check bool refcount_dec_not_one(refcount_t *r);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t