public inbox for llvm@lists.linux.dev
 help / color / mirror / Atom feed
* [PATCH tip/locking/core] compiler-context-analysis: Add support for multi-argument guarded_by
@ 2026-03-23 15:33 Marco Elver
  2026-03-23 15:39 ` Marco Elver
  2026-03-23 23:28 ` [PATCH tip/locking/core] compiler-context-analysis: Add support for multi-argument guarded_by Nathan Chancellor
  0 siblings, 2 replies; 7+ messages in thread
From: Marco Elver @ 2026-03-23 15:33 UTC (permalink / raw)
  To: elver, Peter Zijlstra
  Cc: Ingo Molnar, Nathan Chancellor, Nick Desaulniers, Bill Wendling,
	Justin Stitt, llvm, Bart Van Assche, linux-kernel

Clang 23 introduces support for multiple arguments in the `guarded_by`
and `pt_guarded_by` attributes [1]. This allows defining variables
protected by multiple context locks, where read access requires holding
at least one lock (shared or exclusive), and write access requires
holding all of them exclusively.

To use the feature while maintaining compatibility with Clang 22, add
the `__guarded_by_any()` and `__pt_guarded_by_any()` macros. On Clang 23
and newer, these expand to the underlying attributes; with older Clang
versions, they fall back to a no-op (false negatives possible).

Link: https://github.com/llvm/llvm-project/pull/186838 [1]
Requested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Marco Elver <elver@google.com>
---
 include/linux/compiler-context-analysis.h | 66 ++++++++++++++++++++---
 init/Kconfig                              |  5 ++
 lib/test_context-analysis.c               | 24 +++++++++
 3 files changed, 87 insertions(+), 8 deletions(-)

diff --git a/include/linux/compiler-context-analysis.h b/include/linux/compiler-context-analysis.h
index 00c074a2ccb0..a0d135e500dd 100644
--- a/include/linux/compiler-context-analysis.h
+++ b/include/linux/compiler-context-analysis.h
@@ -39,8 +39,9 @@
 # define __assumes_shared_ctx_lock(...)	__attribute__((assert_shared_capability(__VA_ARGS__)))
 
 /**
- * __guarded_by - struct member and globals attribute, declares variable
- *                only accessible within active context
+ * __guarded_by() - struct member and globals attribute, declares variable
+ *                  only accessible within active context
+ * @x: context lock instance pointer
  *
  * Declares that the struct member or global variable is only accessible within
  * the context entered by the given context lock. Read operations on the data
@@ -53,11 +54,12 @@
  *		long counter __guarded_by(&lock);
  *	};
  */
-# define __guarded_by(...)		__attribute__((guarded_by(__VA_ARGS__)))
+# define __guarded_by(x)		__attribute__((guarded_by(x)))
 
 /**
- * __pt_guarded_by - struct member and globals attribute, declares pointed-to
- *                   data only accessible within active context
+ * __pt_guarded_by() - struct member and globals attribute, declares pointed-to
+ *                     data only accessible within active context
+ * @x: context lock instance pointer
  *
  * Declares that the data pointed to by the struct member pointer or global
  * pointer is only accessible within the context entered by the given context
@@ -71,7 +73,53 @@
  *		long *counter __pt_guarded_by(&lock);
  *	};
  */
-# define __pt_guarded_by(...)		__attribute__((pt_guarded_by(__VA_ARGS__)))
+# define __pt_guarded_by(x)		__attribute__((pt_guarded_by(x)))
+
+/**
+ * __guarded_by_any() - struct member and globals attribute, declares variable
+ *                      only accessible within active contexts
+ * @...: context lock instance pointers
+ *
+ * Declares that the struct member or global variable is protected by multiple
+ * context locks. Write access requires all listed context locks to be held
+ * exclusively; read access requires at least one of them to be held (shared or
+ * exclusive).
+ *
+ * .. code-block:: c
+ *
+ *	struct some_state {
+ *		spinlock_t lock1, lock2;
+ *		long counter __guarded_by_any(&lock1, &lock2);
+ *	};
+ */
+# ifdef CONFIG_CC_HAS_MULTI_ARG_GUARDED_BY_ATTR
+#  define __guarded_by_any(...)		__attribute__((guarded_by(__VA_ARGS__)))
+# else
+#  define __guarded_by_any(...)
+# endif
+
+/**
+ * __pt_guarded_by_any() - struct member and globals attribute, declares pointed-to
+ *                         data only accessible within active contexts
+ * @...: context lock instance pointers
+ *
+ * Declares that the data pointed to by the struct member pointer or global
+ * pointer is protected by multiple context locks. Write access requires all
+ * listed context locks to be held exclusively; read access requires at least
+ * one of them to be held (shared or exclusive).
+ *
+ * .. code-block:: c
+ *
+ *	struct some_state {
+ *		spinlock_t lock1, lock2;
+ *		long *counter __pt_guarded_by_any(&lock1, &lock2);
+ *	};
+ */
+# ifdef CONFIG_CC_HAS_MULTI_ARG_GUARDED_BY_ATTR
+#  define __pt_guarded_by_any(...)		__attribute__((pt_guarded_by(__VA_ARGS__)))
+# else
+#  define __pt_guarded_by_any(...)
+# endif
 
 /**
  * context_lock_struct() - declare or define a context lock struct
@@ -158,8 +206,10 @@
 # define __assumes_ctx_lock(...)
 # define __assumes_shared_ctx_lock(...)
 # define __returns_ctx_lock(var)
-# define __guarded_by(...)
-# define __pt_guarded_by(...)
+# define __guarded_by(x)
+# define __pt_guarded_by(x)
+# define __guarded_by_any(...)
+# define __pt_guarded_by_any(...)
 # define __excludes_ctx_lock(...)
 # define __requires_ctx_lock(...)
 # define __requires_shared_ctx_lock(...)
diff --git a/init/Kconfig b/init/Kconfig
index 444ce811ea67..9f9a800822ff 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -158,6 +158,11 @@ config CC_HAS_BROKEN_COUNTED_BY_REF
 config CC_HAS_MULTIDIMENSIONAL_NONSTRING
 	def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
 
+config CC_HAS_MULTI_ARG_GUARDED_BY_ATTR
+	# supported since clang 23
+	depends on CC_IS_CLANG
+	def_bool $(success,echo 'typedef int __attribute__((capability("l"))) L; L l1; L l2; int __attribute__((guarded_by(&l1, &l2))) x;' | $(CC) -x c - -c -o /dev/null -Werror)
+
 config LD_CAN_USE_KEEP_IN_OVERLAY
 	# ld.lld prior to 21.0.0 did not support KEEP within an overlay description
 	# https://github.com/llvm/llvm-project/pull/130661
diff --git a/lib/test_context-analysis.c b/lib/test_context-analysis.c
index 06b4a6a028e0..691fb2d6fc45 100644
--- a/lib/test_context-analysis.c
+++ b/lib/test_context-analysis.c
@@ -159,6 +159,10 @@ TEST_SPINLOCK_COMMON(read_lock,
 struct test_mutex_data {
 	struct mutex mtx;
 	int counter __guarded_by(&mtx);
+
+	struct mutex mtx2;
+	int anyread __guarded_by_any(&mtx, &mtx2);
+	int *anyptr __pt_guarded_by_any(&mtx, &mtx2);
 };
 
 static void __used test_mutex_init(struct test_mutex_data *d)
@@ -219,6 +223,26 @@ static void __used test_mutex_cond_guard(struct test_mutex_data *d)
 	}
 }
 
+static void __used test_mutex_multiguard(struct test_mutex_data *d)
+{
+	mutex_lock(&d->mtx);
+	(void)d->anyread;
+	(void)*d->anyptr;
+	mutex_unlock(&d->mtx);
+
+	mutex_lock(&d->mtx2);
+	(void)d->anyread;
+	(void)*d->anyptr;
+	mutex_unlock(&d->mtx2);
+
+	mutex_lock(&d->mtx);
+	mutex_lock(&d->mtx2);
+	d->anyread++;
+	(*d->anyptr)++;
+	mutex_unlock(&d->mtx2);
+	mutex_unlock(&d->mtx);
+}
+
 struct test_seqlock_data {
 	seqlock_t sl;
 	int counter __guarded_by(&sl);
-- 
2.53.0.1018.g2bb0e51243-goog


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH tip/locking/core] compiler-context-analysis: Add support for multi-argument guarded_by
  2026-03-23 15:33 [PATCH tip/locking/core] compiler-context-analysis: Add support for multi-argument guarded_by Marco Elver
@ 2026-03-23 15:39 ` Marco Elver
  2026-03-25 15:20   ` Peter Zijlstra
  2026-03-23 23:28 ` [PATCH tip/locking/core] compiler-context-analysis: Add support for multi-argument guarded_by Nathan Chancellor
  1 sibling, 1 reply; 7+ messages in thread
From: Marco Elver @ 2026-03-23 15:39 UTC (permalink / raw)
  To: elver, Peter Zijlstra
  Cc: Ingo Molnar, Nathan Chancellor, Nick Desaulniers, Bill Wendling,
	Justin Stitt, llvm, Bart Van Assche, linux-kernel

On Mon, 23 Mar 2026 at 16:33, Marco Elver <elver@google.com> wrote:
>
> Clang 23 introduces support for multiple arguments in the `guarded_by`
> and `pt_guarded_by` attributes [1]. This allows defining variables
> protected by multiple context locks, where read access requires holding
> at least one lock (shared or exclusive), and write access requires
> holding all of them exclusively.
>
> To use the feature while maintaining compatibility with Clang 22, add
> the `__guarded_by_any()` and `__pt_guarded_by_any()` macros. On Clang 23
> and newer, these expand to the underlying attributes; with older Clang
> versions, they fall back to a no-op (false negatives possible).
>
> Link: https://github.com/llvm/llvm-project/pull/186838 [1]
> Requested-by: Peter Zijlstra <peterz@infradead.org>
> Signed-off-by: Marco Elver <elver@google.com>

If we want to retain compatibility with Clang 22, we need
__guarded_by_any, which ultimately maps to 'guarded_by' as well if we
have Clang 23+.

The alternative would be to wait a few weeks and then require Context
Analysis to have a Clang 23 compiler. That'd avoid adding the new
__guarded_by_any variant and we can just use __guarded_by as-is.

We likely want to do that when Clang 23.1 is released anyway, because
there were some other fixes (arrays of lock fix:
https://github.com/llvm/llvm-project/pull/148551).

Preferences?

> ---
>  include/linux/compiler-context-analysis.h | 66 ++++++++++++++++++++---
>  init/Kconfig                              |  5 ++
>  lib/test_context-analysis.c               | 24 +++++++++
>  3 files changed, 87 insertions(+), 8 deletions(-)
>
> diff --git a/include/linux/compiler-context-analysis.h b/include/linux/compiler-context-analysis.h
> index 00c074a2ccb0..a0d135e500dd 100644
> --- a/include/linux/compiler-context-analysis.h
> +++ b/include/linux/compiler-context-analysis.h
> @@ -39,8 +39,9 @@
>  # define __assumes_shared_ctx_lock(...)        __attribute__((assert_shared_capability(__VA_ARGS__)))
>
>  /**
> - * __guarded_by - struct member and globals attribute, declares variable
> - *                only accessible within active context
> + * __guarded_by() - struct member and globals attribute, declares variable
> + *                  only accessible within active context
> + * @x: context lock instance pointer
>   *
>   * Declares that the struct member or global variable is only accessible within
>   * the context entered by the given context lock. Read operations on the data
> @@ -53,11 +54,12 @@
>   *             long counter __guarded_by(&lock);
>   *     };
>   */
> -# define __guarded_by(...)             __attribute__((guarded_by(__VA_ARGS__)))
> +# define __guarded_by(x)               __attribute__((guarded_by(x)))
>
>  /**
> - * __pt_guarded_by - struct member and globals attribute, declares pointed-to
> - *                   data only accessible within active context
> + * __pt_guarded_by() - struct member and globals attribute, declares pointed-to
> + *                     data only accessible within active context
> + * @x: context lock instance pointer
>   *
>   * Declares that the data pointed to by the struct member pointer or global
>   * pointer is only accessible within the context entered by the given context
> @@ -71,7 +73,53 @@
>   *             long *counter __pt_guarded_by(&lock);
>   *     };
>   */
> -# define __pt_guarded_by(...)          __attribute__((pt_guarded_by(__VA_ARGS__)))
> +# define __pt_guarded_by(x)            __attribute__((pt_guarded_by(x)))
> +
> +/**
> + * __guarded_by_any() - struct member and globals attribute, declares variable
> + *                      only accessible within active contexts
> + * @...: context lock instance pointers
> + *
> + * Declares that the struct member or global variable is protected by multiple
> + * context locks. Write access requires all listed context locks to be held
> + * exclusively; read access requires at least one of them to be held (shared or
> + * exclusive).
> + *
> + * .. code-block:: c
> + *
> + *     struct some_state {
> + *             spinlock_t lock1, lock2;
> + *             long counter __guarded_by_any(&lock1, &lock2);
> + *     };
> + */
> +# ifdef CONFIG_CC_HAS_MULTI_ARG_GUARDED_BY_ATTR
> +#  define __guarded_by_any(...)                __attribute__((guarded_by(__VA_ARGS__)))
> +# else
> +#  define __guarded_by_any(...)
> +# endif
> +
> +/**
> + * __pt_guarded_by_any() - struct member and globals attribute, declares pointed-to
> + *                         data only accessible within active contexts
> + * @...: context lock instance pointers
> + *
> + * Declares that the data pointed to by the struct member pointer or global
> + * pointer is protected by multiple context locks. Write access requires all
> + * listed context locks to be held exclusively; read access requires at least
> + * one of them to be held (shared or exclusive).
> + *
> + * .. code-block:: c
> + *
> + *     struct some_state {
> + *             spinlock_t lock1, lock2;
> + *             long *counter __pt_guarded_by_any(&lock1, &lock2);
> + *     };
> + */
> +# ifdef CONFIG_CC_HAS_MULTI_ARG_GUARDED_BY_ATTR
> +#  define __pt_guarded_by_any(...)             __attribute__((pt_guarded_by(__VA_ARGS__)))
> +# else
> +#  define __pt_guarded_by_any(...)
> +# endif
>
>  /**
>   * context_lock_struct() - declare or define a context lock struct
> @@ -158,8 +206,10 @@
>  # define __assumes_ctx_lock(...)
>  # define __assumes_shared_ctx_lock(...)
>  # define __returns_ctx_lock(var)
> -# define __guarded_by(...)
> -# define __pt_guarded_by(...)
> +# define __guarded_by(x)
> +# define __pt_guarded_by(x)
> +# define __guarded_by_any(...)
> +# define __pt_guarded_by_any(...)
>  # define __excludes_ctx_lock(...)
>  # define __requires_ctx_lock(...)
>  # define __requires_shared_ctx_lock(...)
> diff --git a/init/Kconfig b/init/Kconfig
> index 444ce811ea67..9f9a800822ff 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -158,6 +158,11 @@ config CC_HAS_BROKEN_COUNTED_BY_REF
>  config CC_HAS_MULTIDIMENSIONAL_NONSTRING
>         def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
>
> +config CC_HAS_MULTI_ARG_GUARDED_BY_ATTR
> +       # supported since clang 23
> +       depends on CC_IS_CLANG
> +       def_bool $(success,echo 'typedef int __attribute__((capability("l"))) L; L l1; L l2; int __attribute__((guarded_by(&l1, &l2))) x;' | $(CC) -x c - -c -o /dev/null -Werror)
> +
>  config LD_CAN_USE_KEEP_IN_OVERLAY
>         # ld.lld prior to 21.0.0 did not support KEEP within an overlay description
>         # https://github.com/llvm/llvm-project/pull/130661
> diff --git a/lib/test_context-analysis.c b/lib/test_context-analysis.c
> index 06b4a6a028e0..691fb2d6fc45 100644
> --- a/lib/test_context-analysis.c
> +++ b/lib/test_context-analysis.c
> @@ -159,6 +159,10 @@ TEST_SPINLOCK_COMMON(read_lock,
>  struct test_mutex_data {
>         struct mutex mtx;
>         int counter __guarded_by(&mtx);
> +
> +       struct mutex mtx2;
> +       int anyread __guarded_by_any(&mtx, &mtx2);
> +       int *anyptr __pt_guarded_by_any(&mtx, &mtx2);
>  };
>
>  static void __used test_mutex_init(struct test_mutex_data *d)
> @@ -219,6 +223,26 @@ static void __used test_mutex_cond_guard(struct test_mutex_data *d)
>         }
>  }
>
> +static void __used test_mutex_multiguard(struct test_mutex_data *d)
> +{
> +       mutex_lock(&d->mtx);
> +       (void)d->anyread;
> +       (void)*d->anyptr;
> +       mutex_unlock(&d->mtx);
> +
> +       mutex_lock(&d->mtx2);
> +       (void)d->anyread;
> +       (void)*d->anyptr;
> +       mutex_unlock(&d->mtx2);
> +
> +       mutex_lock(&d->mtx);
> +       mutex_lock(&d->mtx2);
> +       d->anyread++;
> +       (*d->anyptr)++;
> +       mutex_unlock(&d->mtx2);
> +       mutex_unlock(&d->mtx);
> +}
> +
>  struct test_seqlock_data {
>         seqlock_t sl;
>         int counter __guarded_by(&sl);
> --
> 2.53.0.1018.g2bb0e51243-goog
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH tip/locking/core] compiler-context-analysis: Add support for multi-argument guarded_by
  2026-03-23 15:33 [PATCH tip/locking/core] compiler-context-analysis: Add support for multi-argument guarded_by Marco Elver
  2026-03-23 15:39 ` Marco Elver
@ 2026-03-23 23:28 ` Nathan Chancellor
  1 sibling, 0 replies; 7+ messages in thread
From: Nathan Chancellor @ 2026-03-23 23:28 UTC (permalink / raw)
  To: Marco Elver
  Cc: Peter Zijlstra, Ingo Molnar, Nick Desaulniers, Bill Wendling,
	Justin Stitt, llvm, Bart Van Assche, linux-kernel

On Mon, Mar 23, 2026 at 04:33:32PM +0100, Marco Elver wrote:
> Clang 23 introduces support for multiple arguments in the `guarded_by`
> and `pt_guarded_by` attributes [1]. This allows defining variables
> protected by multiple context locks, where read access requires holding
> at least one lock (shared or exclusive), and write access requires
> holding all of them exclusively.
> 
> To use the feature while maintaining compatibility with Clang 22, add
> the `__guarded_by_any()` and `__pt_guarded_by_any()` macros. On Clang 23
> and newer, these expand to the underlying attributes; with older Clang
> versions, they fall back to a no-op (false negatives possible).
> 
> Link: https://github.com/llvm/llvm-project/pull/186838 [1]
> Requested-by: Peter Zijlstra <peterz@infradead.org>
> Signed-off-by: Marco Elver <elver@google.com>

Reviewed-by: Nathan Chancellor <nathan@kernel.org>

One small comment below.

> ---
>  include/linux/compiler-context-analysis.h | 66 ++++++++++++++++++++---
>  init/Kconfig                              |  5 ++
>  lib/test_context-analysis.c               | 24 +++++++++
>  3 files changed, 87 insertions(+), 8 deletions(-)
> 
> diff --git a/include/linux/compiler-context-analysis.h b/include/linux/compiler-context-analysis.h
> index 00c074a2ccb0..a0d135e500dd 100644
> --- a/include/linux/compiler-context-analysis.h
> +++ b/include/linux/compiler-context-analysis.h
> @@ -39,8 +39,9 @@
>  # define __assumes_shared_ctx_lock(...)	__attribute__((assert_shared_capability(__VA_ARGS__)))
>  
>  /**
> - * __guarded_by - struct member and globals attribute, declares variable
> - *                only accessible within active context
> + * __guarded_by() - struct member and globals attribute, declares variable
> + *                  only accessible within active context
> + * @x: context lock instance pointer
>   *
>   * Declares that the struct member or global variable is only accessible within
>   * the context entered by the given context lock. Read operations on the data
> @@ -53,11 +54,12 @@
>   *		long counter __guarded_by(&lock);
>   *	};
>   */
> -# define __guarded_by(...)		__attribute__((guarded_by(__VA_ARGS__)))
> +# define __guarded_by(x)		__attribute__((guarded_by(x)))
>  
>  /**
> - * __pt_guarded_by - struct member and globals attribute, declares pointed-to
> - *                   data only accessible within active context
> + * __pt_guarded_by() - struct member and globals attribute, declares pointed-to
> + *                     data only accessible within active context
> + * @x: context lock instance pointer
>   *
>   * Declares that the data pointed to by the struct member pointer or global
>   * pointer is only accessible within the context entered by the given context
> @@ -71,7 +73,53 @@
>   *		long *counter __pt_guarded_by(&lock);
>   *	};
>   */
> -# define __pt_guarded_by(...)		__attribute__((pt_guarded_by(__VA_ARGS__)))
> +# define __pt_guarded_by(x)		__attribute__((pt_guarded_by(x)))
> +
> +/**
> + * __guarded_by_any() - struct member and globals attribute, declares variable
> + *                      only accessible within active contexts
> + * @...: context lock instance pointers
> + *
> + * Declares that the struct member or global variable is protected by multiple
> + * context locks. Write access requires all listed context locks to be held
> + * exclusively; read access requires at least one of them to be held (shared or
> + * exclusive).
> + *
> + * .. code-block:: c
> + *
> + *	struct some_state {
> + *		spinlock_t lock1, lock2;
> + *		long counter __guarded_by_any(&lock1, &lock2);
> + *	};
> + */
> +# ifdef CONFIG_CC_HAS_MULTI_ARG_GUARDED_BY_ATTR
> +#  define __guarded_by_any(...)		__attribute__((guarded_by(__VA_ARGS__)))
> +# else
> +#  define __guarded_by_any(...)
> +# endif
> +
> +/**
> + * __pt_guarded_by_any() - struct member and globals attribute, declares pointed-to
> + *                         data only accessible within active contexts
> + * @...: context lock instance pointers
> + *
> + * Declares that the data pointed to by the struct member pointer or global
> + * pointer is protected by multiple context locks. Write access requires all
> + * listed context locks to be held exclusively; read access requires at least
> + * one of them to be held (shared or exclusive).
> + *
> + * .. code-block:: c
> + *
> + *	struct some_state {
> + *		spinlock_t lock1, lock2;
> + *		long *counter __pt_guarded_by_any(&lock1, &lock2);
> + *	};
> + */
> +# ifdef CONFIG_CC_HAS_MULTI_ARG_GUARDED_BY_ATTR
> +#  define __pt_guarded_by_any(...)		__attribute__((pt_guarded_by(__VA_ARGS__)))
> +# else
> +#  define __pt_guarded_by_any(...)
> +# endif
>  
>  /**
>   * context_lock_struct() - declare or define a context lock struct
> @@ -158,8 +206,10 @@
>  # define __assumes_ctx_lock(...)
>  # define __assumes_shared_ctx_lock(...)
>  # define __returns_ctx_lock(var)
> -# define __guarded_by(...)
> -# define __pt_guarded_by(...)
> +# define __guarded_by(x)
> +# define __pt_guarded_by(x)
> +# define __guarded_by_any(...)
> +# define __pt_guarded_by_any(...)
>  # define __excludes_ctx_lock(...)
>  # define __requires_ctx_lock(...)
>  # define __requires_shared_ctx_lock(...)
> diff --git a/init/Kconfig b/init/Kconfig
> index 444ce811ea67..9f9a800822ff 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -158,6 +158,11 @@ config CC_HAS_BROKEN_COUNTED_BY_REF
>  config CC_HAS_MULTIDIMENSIONAL_NONSTRING
>  	def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
>  
> +config CC_HAS_MULTI_ARG_GUARDED_BY_ATTR
> +	# supported since clang 23
> +	depends on CC_IS_CLANG
> +	def_bool $(success,echo 'typedef int __attribute__((capability("l"))) L; L l1; L l2; int __attribute__((guarded_by(&l1, &l2))) x;' | $(CC) -x c - -c -o /dev/null -Werror)

Include $(CLANG_FLAGS) after $(CC) like the test above to harden against
the weird case when $(CC) does not have the host backend enabled (dumb,
I know, but I have seen it).

> +
>  config LD_CAN_USE_KEEP_IN_OVERLAY
>  	# ld.lld prior to 21.0.0 did not support KEEP within an overlay description
>  	# https://github.com/llvm/llvm-project/pull/130661
> diff --git a/lib/test_context-analysis.c b/lib/test_context-analysis.c
> index 06b4a6a028e0..691fb2d6fc45 100644
> --- a/lib/test_context-analysis.c
> +++ b/lib/test_context-analysis.c
> @@ -159,6 +159,10 @@ TEST_SPINLOCK_COMMON(read_lock,
>  struct test_mutex_data {
>  	struct mutex mtx;
>  	int counter __guarded_by(&mtx);
> +
> +	struct mutex mtx2;
> +	int anyread __guarded_by_any(&mtx, &mtx2);
> +	int *anyptr __pt_guarded_by_any(&mtx, &mtx2);
>  };
>  
>  static void __used test_mutex_init(struct test_mutex_data *d)
> @@ -219,6 +223,26 @@ static void __used test_mutex_cond_guard(struct test_mutex_data *d)
>  	}
>  }
>  
> +static void __used test_mutex_multiguard(struct test_mutex_data *d)
> +{
> +	mutex_lock(&d->mtx);
> +	(void)d->anyread;
> +	(void)*d->anyptr;
> +	mutex_unlock(&d->mtx);
> +
> +	mutex_lock(&d->mtx2);
> +	(void)d->anyread;
> +	(void)*d->anyptr;
> +	mutex_unlock(&d->mtx2);
> +
> +	mutex_lock(&d->mtx);
> +	mutex_lock(&d->mtx2);
> +	d->anyread++;
> +	(*d->anyptr)++;
> +	mutex_unlock(&d->mtx2);
> +	mutex_unlock(&d->mtx);
> +}
> +
>  struct test_seqlock_data {
>  	seqlock_t sl;
>  	int counter __guarded_by(&sl);
> -- 
> 2.53.0.1018.g2bb0e51243-goog
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH tip/locking/core] compiler-context-analysis: Add support for multi-argument guarded_by
  2026-03-23 15:39 ` Marco Elver
@ 2026-03-25 15:20   ` Peter Zijlstra
  2026-03-30 14:09     ` [PATCH tip/locking/core] compiler-context-analysis: Bump required Clang version to 23 Marco Elver
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Zijlstra @ 2026-03-25 15:20 UTC (permalink / raw)
  To: Marco Elver
  Cc: Ingo Molnar, Nathan Chancellor, Nick Desaulniers, Bill Wendling,
	Justin Stitt, llvm, Bart Van Assche, linux-kernel

On Mon, Mar 23, 2026 at 04:39:41PM +0100, Marco Elver wrote:
> On Mon, 23 Mar 2026 at 16:33, Marco Elver <elver@google.com> wrote:
> >
> > Clang 23 introduces support for multiple arguments in the `guarded_by`
> > and `pt_guarded_by` attributes [1]. This allows defining variables
> > protected by multiple context locks, where read access requires holding
> > at least one lock (shared or exclusive), and write access requires
> > holding all of them exclusively.
> >
> > To use the feature while maintaining compatibility with Clang 22, add
> > the `__guarded_by_any()` and `__pt_guarded_by_any()` macros. On Clang 23
> > and newer, these expand to the underlying attributes; with older Clang
> > versions, they fall back to a no-op (false negatives possible).
> >
> > Link: https://github.com/llvm/llvm-project/pull/186838 [1]
> > Requested-by: Peter Zijlstra <peterz@infradead.org>
> > Signed-off-by: Marco Elver <elver@google.com>
> 
> If we want to retain compatibility with Clang 22, we need
> __guarded_by_any, which ultimately maps to 'guarded_by' as well if we
> have Clang 23+.
> 
> The alternative would be to wait a few weeks and then require Context
> Analysis to have a Clang 23 compiler. That'd avoid adding the new
> __guarded_by_any variant and we can just use __guarded_by as-is.
> 
> We likely want to do that when Clang 23.1 is released anyway, because
> there were some other fixes (arrays of lock fix:
> https://github.com/llvm/llvm-project/pull/148551).
> 
> Preferences?

I think we'll be okay just upping the requirement now. But I'll sit on
this a little until Debian's clang-23 build is fresh enough to includes
the awesome :-)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH tip/locking/core] compiler-context-analysis: Bump required Clang version to 23
  2026-03-25 15:20   ` Peter Zijlstra
@ 2026-03-30 14:09     ` Marco Elver
  2026-03-30 14:18       ` Nathan Chancellor
  0 siblings, 1 reply; 7+ messages in thread
From: Marco Elver @ 2026-03-30 14:09 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Nathan Chancellor, Nick Desaulniers, Bill Wendling,
	Justin Stitt, llvm, Bart Van Assche, linux-kernel

Clang 23 introduces support for multiple arguments in the `guarded_by`
and `pt_guarded_by` attributes [1]. This allows defining variables
protected by multiple context locks, where read access requires holding
at least one lock (shared or exclusive), and write access requires
holding all of them exclusively.

Clang 23 also provides a few other improvements (such as being able to
deal with arrays of locks [2]) that make it worthwhile bumping the
compiler version instead of trying to make both Clang 22 and later work
while supporting these new features.

Link: https://github.com/llvm/llvm-project/pull/186838 [1]
Link: https://github.com/llvm/llvm-project/pull/148551 [2]
Requested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Marco Elver <elver@google.com>
---
v2:
* Bump version instead of __guarded_by_any workaround.
---
 Documentation/dev-tools/context-analysis.rst |  2 +-
 include/linux/compiler-context-analysis.h    | 30 ++++++++++++++------
 lib/Kconfig.debug                            |  4 +--
 lib/test_context-analysis.c                  | 24 ++++++++++++++++
 4 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/Documentation/dev-tools/context-analysis.rst b/Documentation/dev-tools/context-analysis.rst
index 54d9ee28de98..8e71e1e75b5b 100644
--- a/Documentation/dev-tools/context-analysis.rst
+++ b/Documentation/dev-tools/context-analysis.rst
@@ -17,7 +17,7 @@ features. To enable for Clang, configure the kernel with::
 
     CONFIG_WARN_CONTEXT_ANALYSIS=y
 
-The feature requires Clang 22 or later.
+The feature requires Clang 23 or later.
 
 The analysis is *opt-in by default*, and requires declaring which modules and
 subsystems should be analyzed in the respective `Makefile`::
diff --git a/include/linux/compiler-context-analysis.h b/include/linux/compiler-context-analysis.h
index 00c074a2ccb0..1ab2622621c3 100644
--- a/include/linux/compiler-context-analysis.h
+++ b/include/linux/compiler-context-analysis.h
@@ -39,12 +39,14 @@
 # define __assumes_shared_ctx_lock(...)	__attribute__((assert_shared_capability(__VA_ARGS__)))
 
 /**
- * __guarded_by - struct member and globals attribute, declares variable
- *                only accessible within active context
+ * __guarded_by() - struct member and globals attribute, declares variable
+ *                  only accessible within active context
+ * @...: context lock instance pointer(s)
  *
  * Declares that the struct member or global variable is only accessible within
- * the context entered by the given context lock. Read operations on the data
- * require shared access, while write operations require exclusive access.
+ * the context entered by the given context lock(s). Read operations on the data
+ * require shared access to at least one of the context locks, while write
+ * operations require exclusive access to all listed context locks.
  *
  * .. code-block:: c
  *
@@ -52,17 +54,24 @@
  *		spinlock_t lock;
  *		long counter __guarded_by(&lock);
  *	};
+ *
+ *	struct some_state {
+ *		spinlock_t lock1, lock2;
+ *		long counter __guarded_by(&lock1, &lock2);
+ *	};
  */
 # define __guarded_by(...)		__attribute__((guarded_by(__VA_ARGS__)))
 
 /**
- * __pt_guarded_by - struct member and globals attribute, declares pointed-to
- *                   data only accessible within active context
+ * __pt_guarded_by() - struct member and globals attribute, declares pointed-to
+ *                     data only accessible within active context
+ * @...: context lock instance pointer(s)
  *
  * Declares that the data pointed to by the struct member pointer or global
  * pointer is only accessible within the context entered by the given context
- * lock. Read operations on the data require shared access, while write
- * operations require exclusive access.
+ * lock(s). Read operations on the data require shared access to at least one
+ * of the context locks, while write operations require exclusive access to all
+ * listed context locks.
  *
  * .. code-block:: c
  *
@@ -70,6 +79,11 @@
  *		spinlock_t lock;
  *		long *counter __pt_guarded_by(&lock);
  *	};
+ *
+ *	struct some_state {
+ *		spinlock_t lock1, lock2;
+ *		long *counter __pt_guarded_by(&lock1, &lock2);
+ *	};
  */
 # define __pt_guarded_by(...)		__attribute__((pt_guarded_by(__VA_ARGS__)))
 
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 93f356d2b3d9..09e9bd003c70 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -630,7 +630,7 @@ config DEBUG_FORCE_WEAK_PER_CPU
 
 config WARN_CONTEXT_ANALYSIS
 	bool "Compiler context-analysis warnings"
-	depends on CC_IS_CLANG && CLANG_VERSION >= 220100
+	depends on CC_IS_CLANG && CLANG_VERSION >= 230000
 	# Branch profiling re-defines "if", which messes with the compiler's
 	# ability to analyze __cond_acquires(..), resulting in false positives.
 	depends on !TRACE_BRANCH_PROFILING
@@ -641,7 +641,7 @@ config WARN_CONTEXT_ANALYSIS
 	  and releasing user-definable "context locks".
 
 	  Clang's name of the feature is "Thread Safety Analysis". Requires
-	  Clang 22.1.0 or later.
+	  Clang 23 or later.
 
 	  Produces warnings by default. Select CONFIG_WERROR if you wish to
 	  turn these warnings into errors.
diff --git a/lib/test_context-analysis.c b/lib/test_context-analysis.c
index 06b4a6a028e0..316f4dfcda65 100644
--- a/lib/test_context-analysis.c
+++ b/lib/test_context-analysis.c
@@ -159,6 +159,10 @@ TEST_SPINLOCK_COMMON(read_lock,
 struct test_mutex_data {
 	struct mutex mtx;
 	int counter __guarded_by(&mtx);
+
+	struct mutex mtx2;
+	int anyread __guarded_by(&mtx, &mtx2);
+	int *anyptr __pt_guarded_by(&mtx, &mtx2);
 };
 
 static void __used test_mutex_init(struct test_mutex_data *d)
@@ -219,6 +223,26 @@ static void __used test_mutex_cond_guard(struct test_mutex_data *d)
 	}
 }
 
+static void __used test_mutex_multiguard(struct test_mutex_data *d)
+{
+	mutex_lock(&d->mtx);
+	(void)d->anyread;
+	(void)*d->anyptr;
+	mutex_unlock(&d->mtx);
+
+	mutex_lock(&d->mtx2);
+	(void)d->anyread;
+	(void)*d->anyptr;
+	mutex_unlock(&d->mtx2);
+
+	mutex_lock(&d->mtx);
+	mutex_lock(&d->mtx2);
+	d->anyread++;
+	(*d->anyptr)++;
+	mutex_unlock(&d->mtx2);
+	mutex_unlock(&d->mtx);
+}
+
 struct test_seqlock_data {
 	seqlock_t sl;
 	int counter __guarded_by(&sl);
-- 
2.53.0.1018.g2bb0e51243-goog

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH tip/locking/core] compiler-context-analysis: Bump required Clang version to 23
  2026-03-30 14:09     ` [PATCH tip/locking/core] compiler-context-analysis: Bump required Clang version to 23 Marco Elver
@ 2026-03-30 14:18       ` Nathan Chancellor
  2026-03-30 14:22         ` Marco Elver
  0 siblings, 1 reply; 7+ messages in thread
From: Nathan Chancellor @ 2026-03-30 14:18 UTC (permalink / raw)
  To: Marco Elver
  Cc: Peter Zijlstra, Ingo Molnar, Nick Desaulniers, Bill Wendling,
	Justin Stitt, llvm, Bart Van Assche, linux-kernel

On Mon, Mar 30, 2026 at 04:09:50PM +0200, Marco Elver wrote:
> Clang 23 introduces support for multiple arguments in the `guarded_by`
> and `pt_guarded_by` attributes [1]. This allows defining variables
> protected by multiple context locks, where read access requires holding
> at least one lock (shared or exclusive), and write access requires
> holding all of them exclusively.
> 
> Clang 23 also provides a few other improvements (such as being able to
> deal with arrays of locks [2]) that make it worthwhile bumping the
> compiler version instead of trying to make both Clang 22 and later work
> while supporting these new features.
> 
> Link: https://github.com/llvm/llvm-project/pull/186838 [1]
> Link: https://github.com/llvm/llvm-project/pull/148551 [2]
> Requested-by: Peter Zijlstra <peterz@infradead.org>
> Signed-off-by: Marco Elver <elver@google.com>

Fair enough. I will upload a new main snapshot to kernel.org to make it
more accessible to folks for testing.

Reviewed-by: Nathan Chancellor <nathan@kernel.org>

> ---
> v2:
> * Bump version instead of __guarded_by_any workaround.
> ---
>  Documentation/dev-tools/context-analysis.rst |  2 +-
>  include/linux/compiler-context-analysis.h    | 30 ++++++++++++++------
>  lib/Kconfig.debug                            |  4 +--
>  lib/test_context-analysis.c                  | 24 ++++++++++++++++
>  4 files changed, 49 insertions(+), 11 deletions(-)
> 
> diff --git a/Documentation/dev-tools/context-analysis.rst b/Documentation/dev-tools/context-analysis.rst
> index 54d9ee28de98..8e71e1e75b5b 100644
> --- a/Documentation/dev-tools/context-analysis.rst
> +++ b/Documentation/dev-tools/context-analysis.rst
> @@ -17,7 +17,7 @@ features. To enable for Clang, configure the kernel with::
>  
>      CONFIG_WARN_CONTEXT_ANALYSIS=y
>  
> -The feature requires Clang 22 or later.
> +The feature requires Clang 23 or later.
>  
>  The analysis is *opt-in by default*, and requires declaring which modules and
>  subsystems should be analyzed in the respective `Makefile`::
> diff --git a/include/linux/compiler-context-analysis.h b/include/linux/compiler-context-analysis.h
> index 00c074a2ccb0..1ab2622621c3 100644
> --- a/include/linux/compiler-context-analysis.h
> +++ b/include/linux/compiler-context-analysis.h
> @@ -39,12 +39,14 @@
>  # define __assumes_shared_ctx_lock(...)	__attribute__((assert_shared_capability(__VA_ARGS__)))
>  
>  /**
> - * __guarded_by - struct member and globals attribute, declares variable
> - *                only accessible within active context
> + * __guarded_by() - struct member and globals attribute, declares variable
> + *                  only accessible within active context
> + * @...: context lock instance pointer(s)
>   *
>   * Declares that the struct member or global variable is only accessible within
> - * the context entered by the given context lock. Read operations on the data
> - * require shared access, while write operations require exclusive access.
> + * the context entered by the given context lock(s). Read operations on the data
> + * require shared access to at least one of the context locks, while write
> + * operations require exclusive access to all listed context locks.
>   *
>   * .. code-block:: c
>   *
> @@ -52,17 +54,24 @@
>   *		spinlock_t lock;
>   *		long counter __guarded_by(&lock);
>   *	};
> + *
> + *	struct some_state {
> + *		spinlock_t lock1, lock2;
> + *		long counter __guarded_by(&lock1, &lock2);
> + *	};
>   */
>  # define __guarded_by(...)		__attribute__((guarded_by(__VA_ARGS__)))
>  
>  /**
> - * __pt_guarded_by - struct member and globals attribute, declares pointed-to
> - *                   data only accessible within active context
> + * __pt_guarded_by() - struct member and globals attribute, declares pointed-to
> + *                     data only accessible within active context
> + * @...: context lock instance pointer(s)
>   *
>   * Declares that the data pointed to by the struct member pointer or global
>   * pointer is only accessible within the context entered by the given context
> - * lock. Read operations on the data require shared access, while write
> - * operations require exclusive access.
> + * lock(s). Read operations on the data require shared access to at least one
> + * of the context locks, while write operations require exclusive access to all
> + * listed context locks.
>   *
>   * .. code-block:: c
>   *
> @@ -70,6 +79,11 @@
>   *		spinlock_t lock;
>   *		long *counter __pt_guarded_by(&lock);
>   *	};
> + *
> + *	struct some_state {
> + *		spinlock_t lock1, lock2;
> + *		long *counter __pt_guarded_by(&lock1, &lock2);
> + *	};
>   */
>  # define __pt_guarded_by(...)		__attribute__((pt_guarded_by(__VA_ARGS__)))
>  
> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> index 93f356d2b3d9..09e9bd003c70 100644
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -630,7 +630,7 @@ config DEBUG_FORCE_WEAK_PER_CPU
>  
>  config WARN_CONTEXT_ANALYSIS
>  	bool "Compiler context-analysis warnings"
> -	depends on CC_IS_CLANG && CLANG_VERSION >= 220100
> +	depends on CC_IS_CLANG && CLANG_VERSION >= 230000
>  	# Branch profiling re-defines "if", which messes with the compiler's
>  	# ability to analyze __cond_acquires(..), resulting in false positives.
>  	depends on !TRACE_BRANCH_PROFILING
> @@ -641,7 +641,7 @@ config WARN_CONTEXT_ANALYSIS
>  	  and releasing user-definable "context locks".
>  
>  	  Clang's name of the feature is "Thread Safety Analysis". Requires
> -	  Clang 22.1.0 or later.
> +	  Clang 23 or later.
>  
>  	  Produces warnings by default. Select CONFIG_WERROR if you wish to
>  	  turn these warnings into errors.
> diff --git a/lib/test_context-analysis.c b/lib/test_context-analysis.c
> index 06b4a6a028e0..316f4dfcda65 100644
> --- a/lib/test_context-analysis.c
> +++ b/lib/test_context-analysis.c
> @@ -159,6 +159,10 @@ TEST_SPINLOCK_COMMON(read_lock,
>  struct test_mutex_data {
>  	struct mutex mtx;
>  	int counter __guarded_by(&mtx);
> +
> +	struct mutex mtx2;
> +	int anyread __guarded_by(&mtx, &mtx2);
> +	int *anyptr __pt_guarded_by(&mtx, &mtx2);
>  };
>  
>  static void __used test_mutex_init(struct test_mutex_data *d)
> @@ -219,6 +223,26 @@ static void __used test_mutex_cond_guard(struct test_mutex_data *d)
>  	}
>  }
>  
> +static void __used test_mutex_multiguard(struct test_mutex_data *d)
> +{
> +	mutex_lock(&d->mtx);
> +	(void)d->anyread;
> +	(void)*d->anyptr;
> +	mutex_unlock(&d->mtx);
> +
> +	mutex_lock(&d->mtx2);
> +	(void)d->anyread;
> +	(void)*d->anyptr;
> +	mutex_unlock(&d->mtx2);
> +
> +	mutex_lock(&d->mtx);
> +	mutex_lock(&d->mtx2);
> +	d->anyread++;
> +	(*d->anyptr)++;
> +	mutex_unlock(&d->mtx2);
> +	mutex_unlock(&d->mtx);
> +}
> +
>  struct test_seqlock_data {
>  	seqlock_t sl;
>  	int counter __guarded_by(&sl);
> -- 
> 2.53.0.1018.g2bb0e51243-goog

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH tip/locking/core] compiler-context-analysis: Bump required Clang version to 23
  2026-03-30 14:18       ` Nathan Chancellor
@ 2026-03-30 14:22         ` Marco Elver
  0 siblings, 0 replies; 7+ messages in thread
From: Marco Elver @ 2026-03-30 14:22 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: Peter Zijlstra, Ingo Molnar, Nick Desaulniers, Bill Wendling,
	Justin Stitt, llvm, Bart Van Assche, linux-kernel

On Mon, 30 Mar 2026 at 16:18, Nathan Chancellor <nathan@kernel.org> wrote:
>
> On Mon, Mar 30, 2026 at 04:09:50PM +0200, Marco Elver wrote:
> > Clang 23 introduces support for multiple arguments in the `guarded_by`
> > and `pt_guarded_by` attributes [1]. This allows defining variables
> > protected by multiple context locks, where read access requires holding
> > at least one lock (shared or exclusive), and write access requires
> > holding all of them exclusively.
> >
> > Clang 23 also provides a few other improvements (such as being able to
> > deal with arrays of locks [2]) that make it worthwhile bumping the
> > compiler version instead of trying to make both Clang 22 and later work
> > while supporting these new features.
> >
> > Link: https://github.com/llvm/llvm-project/pull/186838 [1]
> > Link: https://github.com/llvm/llvm-project/pull/148551 [2]
> > Requested-by: Peter Zijlstra <peterz@infradead.org>
> > Signed-off-by: Marco Elver <elver@google.com>
>
> Fair enough. I will upload a new main snapshot to kernel.org to make it
> more accessible to folks for testing.
>
> Reviewed-by: Nathan Chancellor <nathan@kernel.org>

Thanks.  I always suspected we'll need to bump the Clang version here,
which is a bit inconvenient for now. But I think it's better to do now
than find odd workarounds in the kernel tree later that we need to
revert.

> > ---
> > v2:
> > * Bump version instead of __guarded_by_any workaround.
> > ---
> >  Documentation/dev-tools/context-analysis.rst |  2 +-
> >  include/linux/compiler-context-analysis.h    | 30 ++++++++++++++------
> >  lib/Kconfig.debug                            |  4 +--
> >  lib/test_context-analysis.c                  | 24 ++++++++++++++++
> >  4 files changed, 49 insertions(+), 11 deletions(-)
> >
> > diff --git a/Documentation/dev-tools/context-analysis.rst b/Documentation/dev-tools/context-analysis.rst
> > index 54d9ee28de98..8e71e1e75b5b 100644
> > --- a/Documentation/dev-tools/context-analysis.rst
> > +++ b/Documentation/dev-tools/context-analysis.rst
> > @@ -17,7 +17,7 @@ features. To enable for Clang, configure the kernel with::
> >
> >      CONFIG_WARN_CONTEXT_ANALYSIS=y
> >
> > -The feature requires Clang 22 or later.
> > +The feature requires Clang 23 or later.
> >
> >  The analysis is *opt-in by default*, and requires declaring which modules and
> >  subsystems should be analyzed in the respective `Makefile`::
> > diff --git a/include/linux/compiler-context-analysis.h b/include/linux/compiler-context-analysis.h
> > index 00c074a2ccb0..1ab2622621c3 100644
> > --- a/include/linux/compiler-context-analysis.h
> > +++ b/include/linux/compiler-context-analysis.h
> > @@ -39,12 +39,14 @@
> >  # define __assumes_shared_ctx_lock(...)      __attribute__((assert_shared_capability(__VA_ARGS__)))
> >
> >  /**
> > - * __guarded_by - struct member and globals attribute, declares variable
> > - *                only accessible within active context
> > + * __guarded_by() - struct member and globals attribute, declares variable
> > + *                  only accessible within active context
> > + * @...: context lock instance pointer(s)
> >   *
> >   * Declares that the struct member or global variable is only accessible within
> > - * the context entered by the given context lock. Read operations on the data
> > - * require shared access, while write operations require exclusive access.
> > + * the context entered by the given context lock(s). Read operations on the data
> > + * require shared access to at least one of the context locks, while write
> > + * operations require exclusive access to all listed context locks.
> >   *
> >   * .. code-block:: c
> >   *
> > @@ -52,17 +54,24 @@
> >   *           spinlock_t lock;
> >   *           long counter __guarded_by(&lock);
> >   *   };
> > + *
> > + *   struct some_state {
> > + *           spinlock_t lock1, lock2;
> > + *           long counter __guarded_by(&lock1, &lock2);
> > + *   };
> >   */
> >  # define __guarded_by(...)           __attribute__((guarded_by(__VA_ARGS__)))
> >
> >  /**
> > - * __pt_guarded_by - struct member and globals attribute, declares pointed-to
> > - *                   data only accessible within active context
> > + * __pt_guarded_by() - struct member and globals attribute, declares pointed-to
> > + *                     data only accessible within active context
> > + * @...: context lock instance pointer(s)
> >   *
> >   * Declares that the data pointed to by the struct member pointer or global
> >   * pointer is only accessible within the context entered by the given context
> > - * lock. Read operations on the data require shared access, while write
> > - * operations require exclusive access.
> > + * lock(s). Read operations on the data require shared access to at least one
> > + * of the context locks, while write operations require exclusive access to all
> > + * listed context locks.
> >   *
> >   * .. code-block:: c
> >   *
> > @@ -70,6 +79,11 @@
> >   *           spinlock_t lock;
> >   *           long *counter __pt_guarded_by(&lock);
> >   *   };
> > + *
> > + *   struct some_state {
> > + *           spinlock_t lock1, lock2;
> > + *           long *counter __pt_guarded_by(&lock1, &lock2);
> > + *   };
> >   */
> >  # define __pt_guarded_by(...)                __attribute__((pt_guarded_by(__VA_ARGS__)))
> >
> > diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> > index 93f356d2b3d9..09e9bd003c70 100644
> > --- a/lib/Kconfig.debug
> > +++ b/lib/Kconfig.debug
> > @@ -630,7 +630,7 @@ config DEBUG_FORCE_WEAK_PER_CPU
> >
> >  config WARN_CONTEXT_ANALYSIS
> >       bool "Compiler context-analysis warnings"
> > -     depends on CC_IS_CLANG && CLANG_VERSION >= 220100
> > +     depends on CC_IS_CLANG && CLANG_VERSION >= 230000
> >       # Branch profiling re-defines "if", which messes with the compiler's
> >       # ability to analyze __cond_acquires(..), resulting in false positives.
> >       depends on !TRACE_BRANCH_PROFILING
> > @@ -641,7 +641,7 @@ config WARN_CONTEXT_ANALYSIS
> >         and releasing user-definable "context locks".
> >
> >         Clang's name of the feature is "Thread Safety Analysis". Requires
> > -       Clang 22.1.0 or later.
> > +       Clang 23 or later.
> >
> >         Produces warnings by default. Select CONFIG_WERROR if you wish to
> >         turn these warnings into errors.
> > diff --git a/lib/test_context-analysis.c b/lib/test_context-analysis.c
> > index 06b4a6a028e0..316f4dfcda65 100644
> > --- a/lib/test_context-analysis.c
> > +++ b/lib/test_context-analysis.c
> > @@ -159,6 +159,10 @@ TEST_SPINLOCK_COMMON(read_lock,
> >  struct test_mutex_data {
> >       struct mutex mtx;
> >       int counter __guarded_by(&mtx);
> > +
> > +     struct mutex mtx2;
> > +     int anyread __guarded_by(&mtx, &mtx2);
> > +     int *anyptr __pt_guarded_by(&mtx, &mtx2);
> >  };
> >
> >  static void __used test_mutex_init(struct test_mutex_data *d)
> > @@ -219,6 +223,26 @@ static void __used test_mutex_cond_guard(struct test_mutex_data *d)
> >       }
> >  }
> >
> > +static void __used test_mutex_multiguard(struct test_mutex_data *d)
> > +{
> > +     mutex_lock(&d->mtx);
> > +     (void)d->anyread;
> > +     (void)*d->anyptr;
> > +     mutex_unlock(&d->mtx);
> > +
> > +     mutex_lock(&d->mtx2);
> > +     (void)d->anyread;
> > +     (void)*d->anyptr;
> > +     mutex_unlock(&d->mtx2);
> > +
> > +     mutex_lock(&d->mtx);
> > +     mutex_lock(&d->mtx2);
> > +     d->anyread++;
> > +     (*d->anyptr)++;
> > +     mutex_unlock(&d->mtx2);
> > +     mutex_unlock(&d->mtx);
> > +}
> > +
> >  struct test_seqlock_data {
> >       seqlock_t sl;
> >       int counter __guarded_by(&sl);
> > --
> > 2.53.0.1018.g2bb0e51243-goog

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-03-30 14:23 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-23 15:33 [PATCH tip/locking/core] compiler-context-analysis: Add support for multi-argument guarded_by Marco Elver
2026-03-23 15:39 ` Marco Elver
2026-03-25 15:20   ` Peter Zijlstra
2026-03-30 14:09     ` [PATCH tip/locking/core] compiler-context-analysis: Bump required Clang version to 23 Marco Elver
2026-03-30 14:18       ` Nathan Chancellor
2026-03-30 14:22         ` Marco Elver
2026-03-23 23:28 ` [PATCH tip/locking/core] compiler-context-analysis: Add support for multi-argument guarded_by Nathan Chancellor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox