On Thu, 6 Feb 2025 at 22:29, Bart Van Assche <bvanassche@xxxxxxx> wrote: > > On 2/6/25 10:10 AM, Marco Elver wrote: > > @@ -243,15 +243,18 @@ const volatile void * __must_check_fn(const volatile void *val) > > #define DEFINE_CLASS(_name, _type, _exit, _init, _init_args...) \ > > typedef _type class_##_name##_t; \ > > static inline void class_##_name##_destructor(_type *p) \ > > + __no_capability_analysis \ > > { _type _T = *p; _exit; } \ > > static inline _type class_##_name##_constructor(_init_args) \ > > + __no_capability_analysis \ > > { _type t = _init; return t; } > > guard() uses the constructor and destructor functions defined by > DEFINE_GUARD(). The DEFINE_GUARD() implementation uses DEFINE_CLASS(). > Here is an example that I found in <linux/mutex.h>: > > DEFINE_GUARD(mutex, struct mutex *, mutex_lock(_T), mutex_unlock(_T)) > > For this example, how is the compiler told that mutex _T is held around > the code protected by guard()? DEFINE_GUARD is the generic variant usable for more than just locking primitives. DEFINE_LOCK_GUARD_X is a specialization of DEFINE_GUARD intended for locking primitives, all of which should be capability-enabled. So I added automatic support for DEFINE_LOCK_GUARD_1 (keeping in mind the limitations as described in the commit message). All later patches that introduce support for a locking primitive that had been using DEFINE_GUARD are switched over to DEFINE_LOCK_GUARD. There's no additional runtime cost (_T is just a struct containing _T->lock). For example, the change for mutex [1] switches it to use DEFINE_LOCK_GUARD_1. [1] https://lore.kernel.org/all/20250206181711.1902989-12-elver@xxxxxxxxxx/ (For every primitive added I have added tests in test_capability-analysis.c, including testing that the scoped guard() helpers work and do not produce false positives.) The RCU patch [15/24] also makes it work for LOCK_GUARD_0, by simply adding an optional helper macro to declare the attributes for lock and unlock. There's no need for additional variants of DEFINE_LOCK_GUARD_X. Should the need arise to add add annotations for DEFINE_GUARD, we can introduce DECLARE_GUARD_ATTRS(), similar to DECLARE_LOCK_GUARD_0_ATTRS() introduced in [15/24]. But it's omitted because DEFINE_GUARD() can be replaced by DEFINE_LOCK_GUARD for locking primitives. In general I wanted to keep the current interface for defining guards untouched, and keeping it simpler.