Messages in this thread | | | From | Wander Lairson Costa <> | Subject | [PATCH v10 0/2] kernel/fork: beware of __put_task_struct calling context | Date | Wed, 14 Jun 2023 09:23:20 -0300 |
| |
Under PREEMPT_RT, __put_task_struct() indirectly acquires sleeping locks. Therefore, it can't be called from an non-preemptible context.
Instead of calling __put_task_struct() directly, we defer it using call_rcu(). A more natural approach would use a workqueue, but since in PREEMPT_RT, we can't allocate dynamic memory from atomic context, the code would become more complex because we would need to put the work_struct instance in the task_struct and initialize it when we allocate a new task_struct.
Changelog =========
v1: * Initial implementation fixing the splat.
v2: * Isolate the logic in its own function. * Fix two more cases caught in review.
v3: * Change __put_task_struct() to handle the issue internally.
v4: * Explain why call_rcu() is safe to call from interrupt context.
v5: * Explain why __put_task_struct() doesn't conflict with put_task_sruct_rcu_user.
v6: * As per Sebastian's review, revert back the implementation of v2 with a distinct function. * Add a check in put_task_struct() to warning when called from a non-sleepable context. * Address more call sites.
v7: * Fix typos. * Add an explanation why the new function doesn't conflict with delayed_free_task().
v8: * Bring back v5. * Fix coding style.
v9: * Reorganize to not need ___put_task_struct() by Oleg's suggestion.
v10: * Add a patch preventing a splat when compile with CONFIG_PROVE_RAW_LOCK_NESTING.
Reported-by: Hu Chunyu <chuhu@redhat.com> Suggested-by: Oleg Nesterov <oleg@redhat.com> Suggested-by: Valentin Schneider <vschneid@redhat.com> Suggested-by: Peter Zijlstra <peterz@infradead.org> Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: Paul McKenney <paulmck@kernel.org> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Luis Goncalves <lgoncalv@redhat.com>
Wander Lairson Costa (2): kernel/fork: beware of __put_task_struct calling context sched: avoid false lockdep splat in put_task_struct()
include/linux/sched/task.h | 38 +++++++++++++++++++++++++++++++++++++- kernel/fork.c | 8 ++++++++ 2 files changed, 45 insertions(+), 1 deletion(-)
-- 2.40.1
| |