Cribbing a good idea from linux, use specific accessors for smr so that we can get some kinds of assertions. The basic notion is that when you load or store through a smr protected pointer you need to explain how you have access. This is done with an invariants only expression. For a load this is as simple as asserting that you're in the section. For a write you want to assert something like mtx_owned().
i.e.
x = smr_entered_load(foo, foo_smr);
x = smr_serialized_load(foo, mtx_owned(&foo_lock));
smr_serialized_store(foo, y, mtx_owned(&foo_lock));
smr_unserialized_store(foo, NULL, in_destructor);
Linux has a static analysis tool that takes annotated sections to discover invalid dereferences. That is nice but I think using a type that hides pointer contents is sufficient and makes it very explicit what consumers are doing. If someone casts their way out of it, it's no different from failing to use the type. Just as lock asserts have become a culturally mandatory practice, smr accessors should, and generic datatypes that implement concurrent access should follow a pattern to start to ingrain this practice.
This also provides the acq/rel barriers necessary. It assumes that the caller has made some modifications to the thing that it is storing and the thing that is loading it needs the corresponding barrier. For routines that don't need barriers they may use the unsynchronized variants to still be explicit. For example, in the destructor in vm_radix the structure is no longer visible so access is unsynchronized so as to not add overhead.
I will add a man page when all of this stabilizes but I am looking for design feedback now. I have used this in radix but I do not have the lock visible so it's not possible for me to use the assert portions for complicated layering reasons.
I'm concerned about the lack of annotation in epoch use in the network stack and how that may proliferate into anti-patterns. I would like to establish a safer, more obvious framework so that we maintain some debuggability.