[RFC 06/10] Reclaim memory from blocked kernel stacks

David Stevens stevensd at google.com
Fri Aug 28 16:33:00 PDT 2026


On Fri, Aug 28, 2026 at 5:57 AM Peter Zijlstra <peterz at infradead.org> wrote:
>
> 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?

A TASK_ flag is definitely better. I was thinking in terms of defining
safe scopes, but that just complicates things for no real benefit.

-David



More information about the linux-arm-kernel mailing list