Skip to content

Commit 85be6d8

Browse files
Peter ZijlstraIngo Molnar
authored andcommitted
cleanup: Make no_free_ptr() __must_check
recent discussion brought about the realization that it makes sense for no_free_ptr() to have __must_check semantics in order to avoid leaking the resource. Additionally, add a few comments to clarify why/how things work. All credit to Linus on how to combine __must_check and the stmt-expression. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent f66c538 commit 85be6d8

File tree

1 file changed

+36
-3
lines changed

1 file changed

+36
-3
lines changed

include/linux/cleanup.h

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
/*
88
* DEFINE_FREE(name, type, free):
99
* simple helper macro that defines the required wrapper for a __free()
10-
* based cleanup function. @free is an expression using '_T' to access
11-
* the variable.
10+
* based cleanup function. @free is an expression using '_T' to access the
11+
* variable. @free should typically include a NULL test before calling a
12+
* function, see the example below.
1213
*
1314
* __free(name):
1415
* variable attribute to add a scoped based cleanup to the variable.
@@ -17,13 +18,18 @@
1718
* like a non-atomic xchg(var, NULL), such that the cleanup function will
1819
* be inhibited -- provided it sanely deals with a NULL value.
1920
*
21+
* NOTE: this has __must_check semantics so that it is harder to accidentally
22+
* leak the resource.
23+
*
2024
* return_ptr(p):
2125
* returns p while inhibiting the __free().
2226
*
2327
* Ex.
2428
*
2529
* DEFINE_FREE(kfree, void *, if (_T) kfree(_T))
2630
*
31+
* void *alloc_obj(...)
32+
* {
2733
* struct obj *p __free(kfree) = kmalloc(...);
2834
* if (!p)
2935
* return NULL;
@@ -32,15 +38,42 @@
3238
* return NULL;
3339
*
3440
* return_ptr(p);
41+
* }
42+
*
43+
* NOTE: the DEFINE_FREE()'s @free expression includes a NULL test even though
44+
* kfree() is fine to be called with a NULL value. This is on purpose. This way
45+
* the compiler sees the end of our alloc_obj() function as:
46+
*
47+
* tmp = p;
48+
* p = NULL;
49+
* if (p)
50+
* kfree(p);
51+
* return tmp;
52+
*
53+
* And through the magic of value-propagation and dead-code-elimination, it
54+
* eliminates the actual cleanup call and compiles into:
55+
*
56+
* return p;
57+
*
58+
* Without the NULL test it turns into a mess and the compiler can't help us.
3559
*/
3660

3761
#define DEFINE_FREE(_name, _type, _free) \
3862
static inline void __free_##_name(void *p) { _type _T = *(_type *)p; _free; }
3963

4064
#define __free(_name) __cleanup(__free_##_name)
4165

66+
#define __get_and_null_ptr(p) \
67+
({ __auto_type __ptr = &(p); \
68+
__auto_type __val = *__ptr; \
69+
*__ptr = NULL; __val; })
70+
71+
static inline __must_check
72+
const volatile void * __must_check_fn(const volatile void *val)
73+
{ return val; }
74+
4275
#define no_free_ptr(p) \
43-
({ __auto_type __ptr = (p); (p) = NULL; __ptr; })
76+
((typeof(p)) __must_check_fn(__get_and_null_ptr(p)))
4477

4578
#define return_ptr(p) return no_free_ptr(p)
4679

0 commit comments

Comments
 (0)