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

Peter Zijlstra peterz at infradead.org
Fri Aug 28 05:57:06 PDT 2026


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?




More information about the linux-arm-kernel mailing list