Re: [RFC 06/10] Reclaim memory from blocked kernel stacks
From: Peter Zijlstra
Date: Fri Aug 28 2026 - 09:00:28 EST
On Thu, Aug 27, 2026 at 04:29:44PM -0700, David Stevens wrote:
> +DEFINE_CLASS(allow_stack_reclaim, bool,
> + ({
> + if (!_T)
> + current->flags &= ~PF_RECLAIMABLE_STACK;
> + }),
> + ({
> + bool was_set = current->flags & PF_RECLAIMABLE_STACK;
> +
> + current->flags |= PF_RECLAIMABLE_STACK;
> + was_set;
> + }),
> + void)
> + allow_stack_reclaim(prev);
> +void __allow_stack_reclaim(struct task_struct *tsk)
> +{
> + union stack_reclaim_state prev_state, target_state;
> +
> + if (WARN_ON_ONCE(tsk->__state == TASK_DEAD))
> + return;
> +
> + prev_state.val = READ_ONCE(tsk->stack_reclaim_state.val);
> + do {
> + target_state.val = prev_state.val;
> +
> + if (prev_state.stack_state != STACK_PREPARE_RECLAIM) {
> + WARN(prev_state.stack_state != STACK_IN_USE,
> + "Reclaimable state %x for previously running task", prev_state.val);
> + return;
> + }
> + target_state.stack_state = STACK_RECLAIMABLE;
> + } while (!try_cmpxchg(&tsk->stack_reclaim_state.val, &prev_state.val, target_state.val));
> +
> + if (irq_work_queue(&tsk->stack_reclaim_work->irq_work)) {
> + /*
> + * Take a ref that gets released by do_reclaim_stack() so we don't
> + * have to worry about races with remove_from_stack_shrinker().
> + */
> + get_task_struct(tsk);
> + }
> +}
> +static inline void allow_stack_reclaim(struct task_struct *tsk)
> +{
> + if (unlikely(tsk->flags & PF_RECLAIMABLE_STACK))
> + __allow_stack_reclaim(tsk);
> +}
So you have a guard with the same name as a function, but the function
only functions when inside the guard of the same name. WTF ?!
Anyway, it looks like you're sprinkling this guard around a few specific
block sites. Which seems to suggest your PF_ flag *should* have been a
TASK_ flag, no?