NetBSD Problem Report #60980
From hoshinomori@xps13-7390-2in1.owarisekai.moe Sat Nov 7 09:35:10 2026
Return-Path: <hoshinomori@xps13-7390-2in1.owarisekai.moe>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature RSA-PSS (2048 bits) client-digest SHA256)
(Client CN "mail.netbsd.org", Issuer "YR1" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 82FF91A923C
for <gnats-bugs@gnats.NetBSD.org>; Sat, 7 Nov 2026 09:35:10 +0000 (UTC)
Message-Id: <20261107092826.DAD648B8BA7@xps13-7390-2in1.owarisekai.moe>
Date: Sat, 07 Nov 2026 17:28:26 +0800 (CST)
From: hoshinomori@owarisekai.moe
Reply-To: hoshinomori@owarisekai.moe
To: gnats-bugs@NetBSD.org
Subject: rcu_replace_pointer() fails to update the original pointer
X-Send-Pr-Version: 3.95
X-From4GNATS: "hoshinomori@owarisekai.moe via gnats" <gnats-admin@NetBSD.org>
>Number: 60980
>Category: kern
>Synopsis: rcu_replace_pointer() fails to update the original pointer
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: needs-pullups
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Nov 07 09:40:01 +0000 2026
>Closed-Date:
>Last-Modified: Sat Nov 07 10:12:21 +0000 2026
>Originator: hoshinomori
>Release: NetBSD 11.0_STABLE
>Organization:
>Environment:
System: NetBSD xps13-7390-2in1.owarisekai.moe 11.0_STABLE NetBSD 11.0_STABLE (GENERIC) #8: Wed Nov 4 20:13:26 CST 2026 root@xps13-7390-2in1.owarisekai.moe:/usr/obj/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
The rcu_replace_pointer() macro in src/sys/external/bsd/common/include/linux/rcupdate.h doesn't update the original pointer.
The macro copy PTRP into a local var __rrp_ptrp and then call rcu_assign_pointer on it instead of the original one.
>How-To-Repeat:
cc rcu_replace_pointer_test.c -o test && ./test
expect output:
returned_old=1 updated_caller=0 still_old=1
=== rcu_replace_pointer_test.c ===
#include <stdio.h>
#define WARN_ON(c) ((void)(c))
#define atomic_store_release(p, v) __atomic_store_n((p), (v), __ATOMIC_RELEASE)
#define rcu_assign_pointer(P,V) atomic_store_release(&(P), (V))
#define rcu_dereference_protected(P, C) ({ \
WARN_ON(!(C)); \
(P); \
})
#define rcu_replace_pointer(PTRP, NEWPTR, C) ({ \
__typeof__(PTRP) __rrp_ptrp = (PTRP); \
__typeof__(PTRP) __rrp_oldptr = \
rcu_dereference_protected(__rrp_ptrp, C); \
rcu_assign_pointer(__rrp_ptrp, NEWPTR); \
__rrp_oldptr; \
})
int
main(void)
{
int old_object = 1, new_object = 2;
struct { int *engines; } ctx = { &old_object };
int *ret = rcu_replace_pointer(ctx.engines, &new_object, 1);
printf("returned_old=%d updated_caller=%d still_old=%d\n",
ret == &old_object, ctx.engines == &new_object,
ctx.engines == &old_object);
return !(ret == &old_object && ctx.engines == &new_object);
}
=== EOF ===
>Fix:
Index: rcupdate.h
===================================================================
RCS file: /cvsroot/src/sys/external/bsd/common/include/linux/rcupdate.h,v
retrieving revision 1.8
diff -u -r1.8 rcupdate.h
--- rcupdate.h 19 Dec 2021 11:49:11 -0000 1.8
+++ rcupdate.h 7 Nov 2026 09:16:14 -0000
@@ -54,10 +54,10 @@
})
#define rcu_replace_pointer(PTRP, NEWPTR, C) ({ \
- __typeof__(PTRP) __rrp_ptrp = (PTRP); \
+ __typeof__(&(PTRP)) __rrp_ptrp = &(PTRP); \
__typeof__(PTRP) __rrp_oldptr = \
- rcu_dereference_protected(__rrp_ptrp, C); \
- rcu_assign_pointer(__rrp_ptrp, NEWPTR); \
+ rcu_dereference_protected(*__rrp_ptrp, C); \
+ rcu_assign_pointer(*__rrp_ptrp, NEWPTR); \
__rrp_oldptr; \
})
>Release-Note:
>Audit-Trail:
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/60980 CVS commit: src/sys/external/bsd/common/include/linux
Date: Sat, 7 Nov 2026 10:08:16 +0000
Module Name: src
Committed By: riastradh
Date: Sat Nov 7 10:08:16 UTC 2026
Modified Files:
src/sys/external/bsd/common/include/linux: rcupdate.h
Log Message:
drm: Fix rcu_replace_pointer.
This Linux API macro takes an _lvalue_ expression for an object, not
a pointer to the object -- unlike, e.g., the atomic_load/store
functions. So we can't copy its value into a local variable (to
avoid duplicate macro argument expansion) and then assign the local
variable with rcu_assign_pointer because that will only modify the
local copy, not the caller's lvalue!
Rename the macro parameters to make this clearer so it doesn't trip
me up again next time I read this.
Probably fixes dozens of graphics problems on a generation of Intel
hardware. Derp!
PR kern/60980: rcu_replace_pointer() fails to update the original pointer
To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/sys/external/bsd/common/include/linux/rcupdate.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->needs-pullups
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Sat, 07 Nov 2026 10:12:21 +0000
State-Changed-Why:
Thanks! Fixed in HEAD, if I got the patch right this time (I made some
intentional changes on top in an attempt to make the macro clearer for
the next reader), needs pullup-11 and pullup-10.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.