css_for_each_descendant_pre(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… css_for_each_descendant_pre(9) πŸ’…

okay so welcome to the Kernel API Manual, bestie πŸŽ€ β€” this one's called css_for_each_descendant_pre, and yeah the name is a whole mouthful, but we're gonna get through it together, i promise 🫢


✨ NAME ✨

css_for_each_descendant_pre β€” pre-order walk of a css's descendants πŸ¦‹


⭐ SYNOPSIS ⭐

css_for_each_descendant_pre (pos , css );

πŸ’– ARGUMENTS πŸ’–

  • pos β€” the css * to use as the loop cursor πŸ” like, this is the lil pointer that scoots along the tree, keep your eyes on her
  • css β€” the manpage literally just says -- undescribed -- 😭 no cap, that's the entire description, we move πŸ’€

🌸 DESCRIPTION 🌸

So here's the vibe: you walk root's descendants. and root is included in the iteration and is the first node to be visited πŸ‘‘ she's the main character, she goes first, periodt. Must be called under rcu_read_lock β€” that part is not optional, ngl, do not skip it πŸ™ˆ

If a subsystem synchronizes ->css_online and the start of iteration, a css which finished ->css_online is guaranteed to be visible in the future iterations and will stay visible until the last reference is put ✨. but heads up β€” a css which hasn't finished ->css_online or already finished ->css_offline may show up during traversal 😭 so synchronizing against on/offlining is each subsystem's own responsibility, fr fr, nobody's gonna do it for you.

For example, the following guarantees that a descendant can't escape state updates of its ancestors 🧚:

my_online(css) { Lock css's parent and css; Inherit state from the parent; Unlock both.  }
my_update_state(css) { css_for_each_descendant_pre(pos, css) { Lock pos; if (pos == css) Update css's state; else Verify pos is alive and inherit state from its parent; Unlock pos; } }

As long as the inheriting step β€” including checking the parent state β€” is enclosed inside pos locking, double-locking the parent isn't necessary while inheriting πŸ’… the state update to the parent is guaranteed to be visible by walking order and, as long as inheriting operations to the same pos are atomic to each other, multiple updates racing each other still result in the correct state ✨ it's guaranateed (their spelling, not mine, don't @ me πŸ“) that at least one inheritance happens for any css after the latest update to its parent.

if checking the parent's state requires locking the parent, then each inheriting iteration should lock and unlock both pos->parent and pos πŸ” two locks, no shortcuts.

Alternatively, a subsystem may choose to use a single global lock to synchronize ->css_online and ->css_offline against tree-walking operations 🌈 lowkey simpler, highkey valid.

And it is allowed to temporarily drop the RCU read lock during iteration πŸ‘€ but then the caller is responsible for ensuring that pos remains accessible until the start of the next iteration, by β€” for example β€” bumping the css refcnt 🫢 like, keep her alive until you come back, that's on you.


🌈 SEE ALSO 🌈

Kernel file ./include/linux/cgroup.h plus the whole friend group πŸ’œ:


and that's the whole page, bestie, you ate that πŸ“βœ¨ this cutie lives in ./include/linux and the date on her little tag says October 2026 β€” screenshot it, cite it, slay it πŸ‘‘πŸ’…

πŸ“¦ where this page comes from