Surround reference count decrement-branch by release/acquire membars.#127
Surround reference count decrement-branch by release/acquire membars.#127riastradh wants to merge 1 commit intormind:masterfrom
Conversation
|
@riastradh: Thanks. However, I think Can we just use C11 here? I would even use a plain atomic_fetch_add() / atomic_fetch_sub() as performance is really not a concern in this code path (i.e. just keep it straightorward to read!). If needed, we can define NetBSD-specific wrappers in the npf_os.c (under the |
src/kern/npf_tableset.c
Outdated
| continue; | ||
| #ifndef __HAVE_ATOMIC_AS_MEMBAR | ||
| membar_acquire(); | ||
| #endif |
There was a problem hiding this comment.
So, what happen to npf_table_destroy() here?
There was a problem hiding this comment.
Oops -- missed a spot while transcribing the patch from NetBSD npf. Fixed with a forced update.
9c6a255 to
4e543a0
Compare
No real disagreement here. This was part of a much larger change I made in NetBSD to audit reference counts so I could fix bugs promptly -- without taking extra effort to tidy everything up or rework the abstractions, and without incurring a performance penalty on machines that don't need it. I'm just posting all of my commits to npf in NetBSD for posterity so they don't languish as local changes. |
In order to ensure that that all users of an object have finished all access to it before the last one actually frees it, we need the decrement to have release/acquire semantics to establish a happens-before relation. ... x->f = 42 ... x->f ... /* A */ if (--x->refcnt != 0) /* atomic */ return; x->a = x->b = ... = x->f = 0; /* B */ free(x); To guarantee that A in one thread happens-before B in another thread, we need the reference count decrement (and branch) to have release/acquire semantics, so put membar_release before and membar_acquire after. (We could use memory_order_acq_rel with atomic_fetch_add_explicit in C11.) Note: membar_producer and membar_consumer are not enough, because they only order stores on one side and loads on the other, whereas it is necessary to order loads and stores on both sides. v2: Nix __HAVE_MEMBAR_AS_ATOMIC.
4e543a0 to
9e9a1c2
Compare
|
@riastradh: I would encourage you to amend |
Discussed on tech-kern: https://mail-index.netbsd.org/tech-kern/2023/02/23/msg028729.html Requested by rmind@: rmind/npf#127 (comment)
Discussed on tech-kern: https://mail-index.netbsd.org/tech-kern/2023/02/23/msg028729.html Requested by rmind@: rmind/npf#127 (comment)
In order to ensure that that all users of an object have finished all access to it before the last one actually frees it, we need the decrement to have release/acquire semantics to establish a happens-before relation.
To guarantee that A in one thread happens-before B in another thread, we need the reference count decrement (and branch) to have release/acquire semantics, so put membar_release before and membar_acquire after. (We could use memory_order_acq_rel with atomic_fetch_add_explicit in C11.)
Note: membar_producer and membar_consumer are not enough, because they only order stores on one side and loads on the other, whereas it is necessary to order loads and stores on both sides.