Re: mbuf cluster m_extref_mtx contention

Christian Ludwig <[email protected]>
Newsgroups gmane.os.openbsd.tech
Message-ID <[email protected]>
Hi,

On Thu, 2026-06-11 at 13:44 +0200, Alexander Bluhm wrote:
> On Fri, Apr 24, 2026 at 04:43:03PM +0200, Alexander Bluhm wrote:
> > On Wed, Apr 22, 2026 at 04:21:42PM +1000, David Gwynne wrote:
> > > from another perspective, if the use after free is the result
> > > mishandling mbufs, then the other diff is more forgiving of a
> > > buggy
> > > behaviour.
> > 
> > I still see stability problems with the extfree proxy diff.  It
> > only happens when doing creating kstack flamegraphs with btrace.
> 
> cludwig@ gave me a hint where r_traceidx in refcnt_rele() is
> problematic.
> 
> thread A calls atomic_dec_int_nv(&r->r_refs), count from 2 to 1
> thread B calls atomic_dec_int_nv(&r->r_refs), set refs to 0
> thread B reads r->r_traceidx
> thread B frees and poisons struct refcnt
> thread A reads r->r_traceidx from invalid memory
> 
> This scenario is unlikely as thread B has to do a lot of work between
> consecutive instructions on thread A.  But it is wrong anyway.
> 
> With the diff below, I tested dlg@'s mbuf-ext-proxy diff multiple
> times without crash.
> 
> ok for the refcnt_rele() trace index fix?

ok cludwig@

> bluhm
> 
> Index: kern/kern_synch.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/kern/kern_synch.c,v
> diff -u -p -r1.233 kern_synch.c
> --- kern/kern_synch.c	24 Nov 2025 12:54:53 -0000	1.233
> +++ kern/kern_synch.c	11 Jun 2026 11:35:50 -0000
> @@ -926,11 +926,13 @@ int
>  refcnt_rele(struct refcnt *r)
>  {
>  	u_int refs;
> +	int trace;
>  
> +	trace = r->r_traceidx;
>  	membar_exit_before_atomic();
>  	refs = atomic_dec_int_nv(&r->r_refs);
>  	KASSERT(refs != ~0);
> -	TRACEINDEX(refcnt, r->r_traceidx, r, refs + 1, -1);
> +	TRACEINDEX(refcnt, trace, r, refs + 1, -1);
>  	if (refs == 0) {
>  		membar_enter_after_atomic();
>  		return (1);
> @@ -949,17 +951,19 @@ void
>  refcnt_finalize(struct refcnt *r, const char *wmesg)
>  {
>  	u_int refs;
> +	int trace;
>  
> +	trace = r->r_traceidx;
>  	membar_exit_before_atomic();
>  	refs = atomic_dec_int_nv(&r->r_refs);
>  	KASSERT(refs != ~0);
> -	TRACEINDEX(refcnt, r->r_traceidx, r, refs + 1, -1);
> +	TRACEINDEX(refcnt, trace, r, refs + 1, -1);
>  	while (refs) {
>  		sleep_setup(r, PWAIT, wmesg);
>  		refs = atomic_load_int(&r->r_refs);
>  		sleep_finish(INFSLP, refs);
>  	}
> -	TRACEINDEX(refcnt, r->r_traceidx, r, refs, 0);
> +	TRACEINDEX(refcnt, trace, r, refs, 0);
>  	/* Order subsequent loads and stores after refs == 0 load.
> */
>  	membar_sync();
>  }
> 
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.