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:

NetBSD Home
NetBSD PR Database Search

(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.