From nobody Fri Feb 14 15:56:45 2025 X-Original-To: dev-commits-src-main@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 4Yvc9p5jCvz5nHpZ; Fri, 14 Feb 2025 15:56:46 +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 "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Yvc9n6Krjz3SX4; Fri, 14 Feb 2025 15:56:45 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1739548605; 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=q/I/2mTQcZ/DBT9Yb9UEJibVuljWrURfwUGYlUb8JH4=; b=tNgTMy3ISAbH2sa07WX11DUn47CyxY7mDI1roR0NF+QBL87B42pXq7fQUp6op1vADNMuNv jBbJrnswArRLHVzLF6fompcvrBfYoSQy7h8UreaASSIaDjYiPOQVsvHmqeMyChHNEf6uRF /PFn7vSuP41HiWkApOgb96XV6jasGwK/IiivUTO7dpNOpEyKVGPXtinATPzFJdTdjxTkbc 0lVRINfgTyUmJh8/LoBIxTnRoB/qRWr+gjbdygYANsRMvKzAsiCRnKCQGnHd1eAoazUFsp 2imzMxifCreIIH9aHYDnI9UDrf/nqOGauon4y/QIHtvzBGfOAo2Ne5xpfYJODw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1739548605; 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=q/I/2mTQcZ/DBT9Yb9UEJibVuljWrURfwUGYlUb8JH4=; b=U+2XKl++HnwYtF1/3qJ4KFyY8f5UPCfaYC6gGckegGp5tu3l3awdt0fUNOUHvfofCt4pKo t2JpisbAhif9UqnV241sJwfk9Nwwv546lGo5aloAp8WmxF8Cw01D3w1OzG2uTyJ+dfi52G e6/YDcqk6IJUeBfGr5Mi38ZqGiSPorG2T4T6rO5VJvhOZHGGiS3znO0nXxq63x9yp7jvtm WT5r3S/T5qRFT6lw4zTJQRTv+Icj8g5aChWZh6XX/O7i1imfNg39uUxHueEO3P5EtIECFe jZKurUSbajXYPHdk1Osv0+nd8bz+bu2RjK796a5Tu8xT0dF22BSPHCEIjgzHNw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1739548605; a=rsa-sha256; cv=none; b=Ps+/z4vmP6tb+iDA94IGT+3Xs7Qy7L21OBY0A+taDn8aUSVCZzRsHiv2/77eYGE484ItYz dbOqlLlm/mwcPDPqHhhcCKjv2BOpAVFk+c1zxzEQSzrvqkYbopBSlbwuzF7l6U2BKPLnnk L2kJHGmWATfwsFQWnjoS2GAzPRUAqVrqo/RssxwHWh/Tk/t8wmqbVXOcfefmM2Z9hPps5S oWxM80UtGYUezIfV8hhYz2ht0mNfnxv650syDbJsil2G1Y4hY8eJUE135vQTp6UWNthOuV reFwYIyEysSt+sEF6/cqZFh3jKC+FsIjtB6JACCA953bEjuFTMdSVwhV4Lspwg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Yvc9n5rcxzdYg; Fri, 14 Feb 2025 15:56:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 51EFujCs046155; Fri, 14 Feb 2025 15:56:45 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 51EFujI8046152; Fri, 14 Feb 2025 15:56:45 GMT (envelope-from git) Date: Fri, 14 Feb 2025 15:56:45 GMT Message-Id: <202502141556.51EFujI8046152@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: d2870b8666f2 - main - queue: Add atomic variants for *_EMPTY List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: d2870b8666f2438af400269c0f6a1a48031bb71e Auto-Submitted: auto-generated The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=d2870b8666f2438af400269c0f6a1a48031bb71e commit d2870b8666f2438af400269c0f6a1a48031bb71e Author: Mark Johnston AuthorDate: 2025-02-14 15:45:11 +0000 Commit: Mark Johnston CommitDate: 2025-02-14 15:45:11 +0000 queue: Add atomic variants for *_EMPTY In some places, these macros are used without a lock, under the assumption that they are naturally atomic. After commit 34740937f7a4 ("queue: New debug macros for STAILQ"), this assumption is false. Provide *_EMPTY_ATOMIC for such cases. This lets us include extra debug checks for the non-atomic case, and gives us a way to explicitly annotate unlocked checks, which generally deserve extra scrutiny and might otherwise raise reports from KCSAN. Reviewed by: kib, olce (previous version) MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D48899 --- share/man/man3/queue.3 | 26 +++++++++++++++++++++++++- sys/sys/queue.h | 12 ++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/share/man/man3/queue.3 b/share/man/man3/queue.3 index be890fd2cc88..e55c7cfb7513 100644 --- a/share/man/man3/queue.3 +++ b/share/man/man3/queue.3 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 8, 2024 +.Dd February 10, 2025 .Dt QUEUE 3 .Os .Sh NAME @@ -33,6 +33,7 @@ .Nm SLIST_CLASS_HEAD , .Nm SLIST_CONCAT , .Nm SLIST_EMPTY , +.Nm SLIST_EMPTY_ATOMIC , .Nm SLIST_ENTRY , .Nm SLIST_FIRST , .Nm SLIST_FOREACH , @@ -53,6 +54,7 @@ .Nm STAILQ_CLASS_HEAD , .Nm STAILQ_CONCAT , .Nm STAILQ_EMPTY , +.Nm STAILQ_EMPTY_ATOMIC , .Nm STAILQ_ENTRY , .Nm STAILQ_FIRST , .Nm STAILQ_FOREACH , @@ -75,6 +77,7 @@ .Nm LIST_CLASS_HEAD , .Nm LIST_CONCAT , .Nm LIST_EMPTY , +.Nm LIST_EMPTY_ATOMIC , .Nm LIST_ENTRY , .Nm LIST_FIRST , .Nm LIST_FOREACH , @@ -96,6 +99,7 @@ .Nm TAILQ_CLASS_HEAD , .Nm TAILQ_CONCAT , .Nm TAILQ_EMPTY , +.Nm TAILQ_EMPTY_ATOMIC , .Nm TAILQ_ENTRY , .Nm TAILQ_FIRST , .Nm TAILQ_FOREACH , @@ -128,6 +132,7 @@ lists and tail queues .Fn SLIST_CLASS_HEAD "HEADNAME" "CLASSTYPE" .Fn SLIST_CONCAT "SLIST_HEAD *head1" "SLIST_HEAD *head2" "TYPE" "SLIST_ENTRY NAME" .Fn SLIST_EMPTY "SLIST_HEAD *head" +.Fn SLIST_EMPTY_ATOMIC "SLIST_HEAD *head" .Fn SLIST_ENTRY "TYPE" .Fn SLIST_FIRST "SLIST_HEAD *head" .Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" @@ -149,6 +154,7 @@ lists and tail queues .Fn STAILQ_CLASS_HEAD "HEADNAME" "CLASSTYPE" .Fn STAILQ_CONCAT "STAILQ_HEAD *head1" "STAILQ_HEAD *head2" .Fn STAILQ_EMPTY "STAILQ_HEAD *head" +.Fn STAILQ_EMPTY_ATOMIC "STAILQ_HEAD *head" .Fn STAILQ_ENTRY "TYPE" .Fn STAILQ_FIRST "STAILQ_HEAD *head" .Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" @@ -172,6 +178,7 @@ lists and tail queues .Fn LIST_CLASS_HEAD "HEADNAME" "CLASSTYPE" .Fn LIST_CONCAT "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME" .Fn LIST_EMPTY "LIST_HEAD *head" +.Fn LIST_EMPTY_ATOMIC "LIST_HEAD *head" .Fn LIST_ENTRY "TYPE" .Fn LIST_FIRST "LIST_HEAD *head" .Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" @@ -194,6 +201,7 @@ lists and tail queues .Fn TAILQ_CLASS_HEAD "HEADNAME" "CLASSTYPE" .Fn TAILQ_CONCAT "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TAILQ_ENTRY NAME" .Fn TAILQ_EMPTY "TAILQ_HEAD *head" +.Fn TAILQ_EMPTY_ATOMIC "TAILQ_HEAD *head" .Fn TAILQ_ENTRY "TYPE" .Fn TAILQ_FIRST "TAILQ_HEAD *head" .Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" @@ -425,6 +433,10 @@ high-usage code paths or to operate on long lists. The macro .Nm SLIST_EMPTY evaluates to true if there are no elements in the list. +The +.Nm SLIST_EMPTY_ATOMIC +variant has the same behavior, but can be safely used in contexts where it is +possible that a different thread is concurrently updating the list. .Pp The macro .Nm SLIST_ENTRY @@ -633,6 +645,10 @@ removing all entries from the former. The macro .Nm STAILQ_EMPTY evaluates to true if there are no items on the tail queue. +The +.Nm STAILQ_EMPTY_ATOMIC +variant has the same behavior, but can be safely used in contexts where it is +possible that a different thread is concurrently updating the queue. .Pp The macro .Nm STAILQ_ENTRY @@ -866,6 +882,10 @@ high-usage code paths or to operate on long lists. The macro .Nm LIST_EMPTY evaluates to true if there are no elements in the list. +The +.Nm LIST_EMPTY_ATOMIC +variant has the same behavior, but can be safely used in contexts where it is +possible that a different thread is concurrently updating the list. .Pp The macro .Nm LIST_ENTRY @@ -1084,6 +1104,10 @@ removing all entries from the former. The macro .Nm TAILQ_EMPTY evaluates to true if there are no items on the tail queue. +The +.Nm TAILQ_EMPTY_ATOMIC +variant has the same behavior, but can be safely used in contexts where it is +possible that a different thread is concurrently updating the queue. .Pp The macro .Nm TAILQ_ENTRY diff --git a/sys/sys/queue.h b/sys/sys/queue.h index c1fa8cd812cf..6e4da0fa0bec 100644 --- a/sys/sys/queue.h +++ b/sys/sys/queue.h @@ -226,6 +226,9 @@ struct { \ #define SLIST_EMPTY(head) ((head)->slh_first == NULL) +#define SLIST_EMPTY_ATOMIC(head) \ + (atomic_load_ptr(&(head)->slh_first) == NULL) + #define SLIST_FIRST(head) ((head)->slh_first) #define SLIST_FOREACH(var, head, field) \ @@ -387,6 +390,9 @@ struct { \ STAILQ_FIRST(head) == NULL; \ }) +#define STAILQ_EMPTY_ATOMIC(head) \ + (atomic_load_ptr(&(head)->stqh_first) == NULL) + #define STAILQ_FIRST(head) ((head)->stqh_first) #define STAILQ_FOREACH(var, head, field) \ @@ -575,6 +581,9 @@ struct { \ #define LIST_EMPTY(head) ((head)->lh_first == NULL) +#define LIST_EMPTY_ATOMIC(head) \ + (atomic_load_ptr(&(head)->lh_first) == NULL) + #define LIST_FIRST(head) ((head)->lh_first) #define LIST_FOREACH(var, head, field) \ @@ -779,6 +788,9 @@ struct { \ #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) +#define TAILQ_EMPTY_ATOMIC(head) \ + (atomic_load_ptr(&(head)->tqh_first) == NULL) + #define TAILQ_FIRST(head) ((head)->tqh_first) #define TAILQ_FOREACH(var, head, field) \