Re: [PATCH v7 2/3] sched/task: Add the put_task_struct_atomic_safe() function

From: Peter Zijlstra
Date: Thu May 04 2023 - 04:43:32 EST


On Tue, Apr 25, 2023 at 08:43:02AM -0300, Wander Lairson Costa wrote:
> diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h
> index b597b97b1f8f..cf774b83b2ec 100644
> --- a/include/linux/sched/task.h
> +++ b/include/linux/sched/task.h
> @@ -141,6 +141,41 @@ static inline void put_task_struct_many(struct task_struct *t, int nr)
>
> void put_task_struct_rcu_user(struct task_struct *task);
>
> +extern void __delayed_put_task_struct(struct rcu_head *rhp);
> +
> +static inline void put_task_struct_atomic_safe(struct task_struct *task)
> +{
> + if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
> + /*
> + * Decrement the refcount explicitly to avoid unnecessarily
> + * calling call_rcu.
> + */
> + if (refcount_dec_and_test(&task->usage))
> + /*
> + * under PREEMPT_RT, we can't call put_task_struct
> + * in atomic context because it will indirectly
> + * acquire sleeping locks.
> + * call_rcu() will schedule __delayed_put_task_struct()
> + * to be called in process context.
> + *
> + * __put_task_struct() is called when
> + * refcount_dec_and_test(&t->usage) succeeds.
> + *
> + * This means that it can't conflict with
> + * put_task_struct_rcu_user() which abuses ->rcu the same
> + * way; rcu_users has a reference so task->usage can't be
> + * zero after rcu_users 1 -> 0 transition.
> + *
> + * delayed_free_task() also uses ->rcu, but it is only called
> + * when it fails to fork a process. Therefore, there is no
> + * way it can conflict with put_task_struct().
> + */
> + call_rcu(&task->rcu, __delayed_put_task_struct);
> + } else {
> + put_task_struct(task);
> + }
> +}

Urgh.. that's plenty horrible. And I'm sure everybody plus kitchen sink
has already asked why can't we just rcu free the thing unconditionally.

Google only found me an earlier version of this same patch set, but I'm
sure we've had that discussion many times over the past several years.
The above and your follow up patch is just horrible.

It requires users to know the RT specific context and gives them no help
what so ever for !RT builds.