SLAB_TYPESAFE_BY_RCU(9)
π SLAB_TYPESAFE_BY_RCU(9) π
okay bestie, sit down, we're reading a kernel API manual page (yes, from the Kernel API Manual, we're fancy now) and this one is literally a WARNING page. Like, the name section is literally "WARNING READ THIS!" β so read it, fr fr. π«Ά
β¨ SYNOPSIS β¨
SLAB_TYPESAFE_BY_RCU
that's it. that's the whole synopsis. iconic minimalism. π
πΈ DESCRIPTION πΈ
okay so the vibe here: this flag delays freeing the SLAB page by a grace period. but β and this is the part people get wrong π β it does _NOT_ delay object freeing. none. zero. nada.
so what that means is: if you do kmem_cache_free, that memory location is free to be reused at any time. like, immediately. so it's totally possible to see another object sitting there in the same RCU grace period. yes, in the SAME grace period. not a drill. π
this feature only guarantees one thing: that the memory location backing the object stays valid. that's it. that's the whole promise. the trick to actually using this without setting your kernel on fire is relying on an independent object validation pass. something like this π
there's a lone : hanging out right before the snippet in the original page and we're keeping it because it's part of the lore:
:
begin:
rcu_read_lock;
obj = lockless_lookup(key);
if (obj) {
if (!try_get_ref(obj)) // might fail for free objects
rcu_read_unlock;
goto begin;
if (obj->key != key) { // not the object we expected
put_ref(obj);
rcu_read_unlock;
goto begin;
}
}
rcu_read_unlock;
see how it loops back? that's the whole strategy. try_get_ref might fail for free objects, and even when it works the obj->key might not match β meaning it's not the object we expected β so you put_ref(obj), drop the rcu_read_unlock, and goto begin to try again. slay. π
this is useful when we need to approach a kernel structure obliquely β like, from its address obtained without the usual locking. we can lock the structure to stabilize it and check it's still at the given address, but ONLY if we can be sure the memory hasn't meanwhile been reused for some other kind of object. because if it has? our subsystem's lock might corrupt it. not cute. π«
so the move is: rcu_read_lock before reading the address, then rcu_read_unlock after taking the spinlock within the structure expected at that address. order matters, bestie. β
timing check, no cap: object identity check has to be done _after_ acquiring a reference, so the user has to ensure proper ordering for loads. and similarly? when initializing objects allocated with SLAB_TYPESAFE_BY_RCU, the newly allocated object has to be fully initialized _before_ its refcount gets initialized, and proper ordering for stores is required too. this is the part where you go "wait what" and then re-read it. π
good news: refcount_{add|inc}_not_zero_acquire and refcount_set_release are literally designed with the proper fences required for reference counting objects allocated with SLAB_TYPESAFE_BY_RCU. so use those, they're the main characters here. π
also β big one β it is not possible to acquire a lock within a structure allocated with SLAB_TYPESAFE_BY_RCU without first acquiring a reference as described above. why? because SLAB_TYPESAFE_BY_RCU pages are not zeroed before being given to the slab, which means any locks must be initialized after each and every kmem_struct_alloc. every single one. π₯
alternatively (and this is the elegant route π
): make the ctor passed to kmem_cache_create initialize the locks at page-allocation time, exactly like it's done in __i915_request_ctor, sighand_ctor, and anon_vma_ctor. such a ctor permits readers to safely acquire those ctor-initialized locks under rcu_read_lock protection. chef's kiss. π§
π°οΈ lore drop:SLAB_TYPESAFE_BY_RCUwas originally namedSLAB_DESTROY_BY_RCU. yes, it got a glow-up and a rebrand. we love a rename era.
π¦ SEE ALSO π¦
kernel file ./include/linux/slab.h and also, in no particular order because they're all here:
SLAB_HWCACHE_ALIGN(9)SLAB_ACCOUNT(9)SLAB_RECLAIM_ACCOUNT(9)struct kmem_cache_args(9)kmem_cache_create_usercopy(9)kmem_cache_create(9)krealloc_node_align(9)kmem_cache_alloc(9)kmem_cache_charge(9)kmalloc(9)kmalloc_nolock(9)__alloc_objs(9)__alloc_flex(9)kmalloc_obj(9)kmalloc_objs(9)kmalloc_flex(9)kmalloc_array(9)krealloc_array(9)kcalloc(9)kzalloc(9)kvmalloc_node(9)kvrealloc_node_align(9)kmalloc_size_roundup(9)
that's the whole reading list, go study, iykyk πβ¨
aaaand that's the page!! π this one lives in ./include/linux, dated October 2026, and it's filed under SLAB_TYPESAFE_BY_RCU(9) β so if you forget it, that's where to find it. mwah, go forth and validate your objects properly π«Άππ
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms