From nobody Tue Feb 10 00:46:46 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4f92vC0BS7z6R4Ws for ; Tue, 10 Feb 2026 00:46:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4f92vB5z9kz4G3x for ; Tue, 10 Feb 2026 00:46:46 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1770684406; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=PSrvYd9G85CkTuK+bwoO+iTADxb/vngLEmEJoLqAt2U=; b=jVVUSg8UttyYUKzUfJAM+DVrsD6DUqasJ2dbkAfivh1ATEA59N97ERPFtIw6zVqAewpU/D /uMTRpXNYMvaVeNBCDFsoycbGPfabtafEBujKDEj4qelQV6PSYW7DDbfalCIf2ljdUCrk+ 5iEmtNKIIrCUvanCHWTbTvapgiX/q37L5INtmLJ4aqjJKu34fNei1nzlzf3EUp3kmFGuER FN8oNpAmrXbsiryg3GiCflvQWb684qN7qR+m+fil3qo9eBp0WB+WtbzS1i1ueGt3jUQqro 3x+G6GSMEcBi4fpkiMIEjASYmVhNxF/cQdLm0EW2/fT08zOUejBz1TUDgC1eOQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1770684406; a=rsa-sha256; cv=none; b=UYaXqhckexIKSx/3nQY/bhRP5+Vcwc0AHzlxQyJrmKtwxHAkmGZzU4h9COwdWQ+3COpeGR bmcfZZWXOXVpBVy2WmajFEK9X5DzR9/W78DLfyvtUpz7AmNKJ+XZ7CftB9iNW7Vu0nYzIz QuBHPxbuOmd2eZh433Jeve9al/GivHG3uAS2dKKN0PAJhcIQPo9G5BMn+JxMG4BcL72tf9 hCJHkDNyX0U+fL2oQ9gVIVnuYo6bV2Wos5jhCTFiXIsjRhk4pHxaPVFFueYmzmF+Ip6hju 8QzeG67aUbbBYt4Tcc0rwuKE1h7ykM04Kz2zJ4iYfSl3N7e/cqDIVJxJv8aDPw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1770684406; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=PSrvYd9G85CkTuK+bwoO+iTADxb/vngLEmEJoLqAt2U=; b=KqqJ7imDZhZxuwIADLNOjAnbkiAgA8znCE6OfpJsGY6lpYOBjM8+SOIPyyM8oYRnCa+lWN oaBudXLXJRS5XI1M37V4kcPatxPKgVauQ17c53GSwwWWWJGULJMN917U8JT2L/BE+qHT5Y kmcqDUxM6H2TxMebGFkluWaz4QcefP5HO2/qrtOrrLEmRM2lwOmX5HL10lRLH1G4Dh61vw lRtWKpqHg1gcjDcvH0TANsEOsydNYKTXHHMK8hLz38v44ingvRlqnxDZBYp+VS7iJEZOiq AoJ91fjqsveTeQWR6Xo3OjtXZGZdAURt/wh15MlyzXAhlxLy/xu9f0mvNkrfiw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4f92vB5ZxnzwkB for ; Tue, 10 Feb 2026 00:46:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 314a9 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 10 Feb 2026 00:46:46 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Bjoern A. Zeeb Subject: git: 31393810a168 - main - LinuxKPI: add scoped_guard(), spinlock guard support List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bz X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 31393810a168b74cf13ace0e1d35dae6b4a12bf5 Auto-Submitted: auto-generated Date: Tue, 10 Feb 2026 00:46:46 +0000 Message-Id: <698a7ff6.314a9.1c8ee0da@gitrepo.freebsd.org> The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=31393810a168b74cf13ace0e1d35dae6b4a12bf5 commit 31393810a168b74cf13ace0e1d35dae6b4a12bf5 Author: Bjoern A. Zeeb AuthorDate: 2026-01-20 22:54:30 +0000 Commit: Bjoern A. Zeeb CommitDate: 2026-02-09 21:49:45 +0000 LinuxKPI: add scoped_guard(), spinlock guard support The "cleanup.h" implementation got a bit more complicated. For one we now use a macro to concatenate a prefix, the name, and a suffix for variable and function declarations. This was triggered by the fact that the "guard_" prefix we used was confusing. We now use a generic "cleanup_" which is only encoded in the single place rather than all over the file. As already indicated by the comment the DEFINE_LOCK_GUARD_0() macro got split up and a _1 version which also takes a type got implemented and is used for a spinlock variant used by rtw89(4) via the new scoped_guard() bits. Sponsored by: The FreeBSD Foundation MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D54808 --- sys/compat/linuxkpi/common/include/linux/cleanup.h | 127 ++++++++++++++++----- .../linuxkpi/common/include/linux/spinlock.h | 10 ++ 2 files changed, 109 insertions(+), 28 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/cleanup.h b/sys/compat/linuxkpi/common/include/linux/cleanup.h index 5bb146f082ed..fb21a81f121b 100644 --- a/sys/compat/linuxkpi/common/include/linux/cleanup.h +++ b/sys/compat/linuxkpi/common/include/linux/cleanup.h @@ -1,7 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (c) 2024-2025 The FreeBSD Foundation + * Copyright (c) 2024-2026 The FreeBSD Foundation * * This software was developed by Björn Zeeb under sponsorship from * the FreeBSD Foundation. @@ -10,18 +10,26 @@ #ifndef _LINUXKPI_LINUX_CLEANUP_H #define _LINUXKPI_LINUX_CLEANUP_H +#include + +#define CLEANUP_NAME(_n, _s) __CONCAT(__CONCAT(cleanup_, _n), _s) + #define __cleanup(_f) __attribute__((__cleanup__(_f))) +#define DECLARE(_n, _x) \ + CLEANUP_NAME(_n, _t) _x __cleanup(CLEANUP_NAME(_n, _destroy)) = \ + CLEANUP_NAME(_n, _create) + /* * Note: "_T" are special as they are exposed into common code for * statements. Extra care should be taken when changing the code. */ #define DEFINE_GUARD(_n, _dt, _lock, _unlock) \ \ - typedef _dt guard_ ## _n ## _t; \ + typedef _dt CLEANUP_NAME(_n, _t); \ \ static inline _dt \ - guard_ ## _n ## _create( _dt _T) \ + CLEANUP_NAME(_n, _create)( _dt _T) \ { \ _dt c; \ \ @@ -30,7 +38,7 @@ } \ \ static inline void \ - guard_ ## _n ## _destroy(_dt *t) \ + CLEANUP_NAME(_n, _destroy)(_dt *t) \ { \ _dt _T; \ \ @@ -39,9 +47,10 @@ } /* We need to keep these calls unique. */ +#define _guard(_n, _x) \ + DECLARE(_n, _x) #define guard(_n) \ - guard_ ## _n ## _t guard_ ## _n ## _ ## __COUNTER__ \ - __cleanup(guard_ ## _n ## _destroy) = guard_ ## _n ## _create + _guard(_n, guard_ ## _n ## _ ## __COUNTER__) #define DEFINE_FREE(_n, _t, _f) \ static inline void \ @@ -56,38 +65,100 @@ #define __free(_n) __cleanup(__free_##_n) /* - * Given this is a _0 version it should likely be broken up into parts. - * But we have no idead what a _1, _2, ... version would do different - * until we see a call. - * This is used for a not-real-type (rcu). We use a bool to "simulate" - * the lock held. Also _T still special, may not always be used, so tag - * with __unused (or better the LinuxKPI __maybe_unused). + * Our initial version go broken up. Some simplifications like using + * "bool" for the lock had to be changed to a more general type. + * _T is still special and, like other bits, may not always be used, + * so tag with __unused (or better the LinuxKPI __maybe_unused). */ -#define DEFINE_LOCK_GUARD_0(_n, _lock, _unlock, ...) \ +#define _DEFINE_LOCK_GUARD_0(_n, _lock) \ + static inline CLEANUP_NAME(_n, _t) \ + CLEANUP_NAME(_n, _create)(void) \ + { \ + CLEANUP_NAME(_n, _t) _tmp; \ + CLEANUP_NAME(_n, _t) *_T __maybe_unused; \ + \ + _tmp.lock = (void *)1; \ + _T = &_tmp; \ + _lock; \ + return (_tmp); \ + } + +#define _DEFINE_LOCK_GUARD_1(_n, _type, _lock) \ + static inline CLEANUP_NAME(_n, _t) \ + CLEANUP_NAME(_n, _create)(_type *l) \ + { \ + CLEANUP_NAME(_n, _t) _tmp; \ + CLEANUP_NAME(_n, _t) *_T __maybe_unused; \ \ + _tmp.lock = l; \ + _T = &_tmp; \ + _lock; \ + return (_tmp); \ + } + +#define _GUARD_IS_ERR(_v) \ + ({ \ + uintptr_t x = (uintptr_t)(void *)(_v); \ + IS_ERR_VALUE(x); \ + }) + +#define __is_cond_ptr(_n) \ + CLEANUP_NAME(_n, _is_cond) +#define __guard_ptr(_n) \ + CLEANUP_NAME(_n, _ptr) + +#define _DEFINE_CLEANUP_IS_CONDITIONAL(_n, _b) \ + static const bool CLEANUP_NAME(_n, _is_cond) __maybe_unused = _b + +#define _DEFINE_GUARD_LOCK_PTR(_n, _lp) \ + static inline void * \ + CLEANUP_NAME(_n, _lock_ptr)(CLEANUP_NAME(_n, _t) *_T) \ + { \ + void *_p; \ + \ + _p = (void *)(uintptr_t)*(_lp); \ + if (IS_ERR(_p)) \ + _p = NULL; \ + return (_p); \ + } + +#define _DEFINE_UNLOCK_GUARD(_n, _type, _unlock, ...) \ typedef struct { \ - bool lock; \ + _type *lock; \ __VA_ARGS__; \ - } guard_ ## _n ## _t; \ + } CLEANUP_NAME(_n, _t); \ \ static inline void \ - guard_ ## _n ## _destroy(guard_ ## _n ## _t *_T) \ + CLEANUP_NAME(_n, _destroy)(CLEANUP_NAME(_n, _t) *_T) \ { \ - if (_T->lock) { \ + if (!_GUARD_IS_ERR(_T->lock)) { \ _unlock; \ } \ } \ \ - static inline guard_ ## _n ## _t \ - guard_ ## _n ## _create(void) \ - { \ - guard_ ## _n ## _t _tmp; \ - guard_ ## _n ## _t *_T __maybe_unused; \ - \ - _tmp.lock = true; \ - _T = &_tmp; \ - _lock; \ - return (_tmp); \ - } + _DEFINE_GUARD_LOCK_PTR(_n, &_T->lock) + +#define DEFINE_LOCK_GUARD_0(_n, _lock, _unlock, ...) \ + _DEFINE_CLEANUP_IS_CONDITIONAL(_n, false); \ + _DEFINE_UNLOCK_GUARD(_n, void, _unlock, __VA_ARGS__) \ + _DEFINE_LOCK_GUARD_0(_n, _lock) + +/* This allows the type to be set. */ +#define DEFINE_LOCK_GUARD_1(_n, _t, _lock, _unlock, ...) \ + _DEFINE_CLEANUP_IS_CONDITIONAL(_n, false); \ + _DEFINE_UNLOCK_GUARD(_n, _t, _unlock, __VA_ARGS__) \ + _DEFINE_LOCK_GUARD_1(_n, _t, _lock) + +#define _scoped_guard(_n, _l, ...) \ + for (DECLARE(_n, _scoped)(__VA_ARGS__); \ + 1 /*__guard_ptr(_n)(&_scoped) || !__is_cond_ptr(_n) */; \ + ({ goto _l; })) \ + if (0) { \ +_l: \ + break; \ + } else + +#define scoped_guard(_n, ...) \ + _scoped_guard(_n, ___label_ ## __COUNTER__, ##__VA_ARGS__) #endif /* _LINUXKPI_LINUX_CLEANUP_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/spinlock.h b/sys/compat/linuxkpi/common/include/linux/spinlock.h index 341e89b6feed..63dc343d1461 100644 --- a/sys/compat/linuxkpi/common/include/linux/spinlock.h +++ b/sys/compat/linuxkpi/common/include/linux/spinlock.h @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -198,4 +199,13 @@ typedef struct raw_spinlock { #define raw_spin_trylock_irqsave(rl, f) spin_trylock_irqsave(&(rl)->lock, (f)) #define raw_spin_unlock_irqrestore(rl, f) spin_unlock_irqrestore(&(rl)->lock, (f)) +/* + * cleanup.h related pre-defined cases. + */ +DEFINE_LOCK_GUARD_1(spinlock_irqsave, + spinlock_t, + spin_lock_irqsave(_T->lock, _T->flags), + spin_unlock_irqrestore(_T->lock, _T->flags), + unsigned long flags) + #endif /* _LINUXKPI_LINUX_SPINLOCK_H_ */