From 7208ac32cce8980d7849afc1d3b2c449560fb581 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner <tglx@linutronix.de> Date: Tue, 28 Sep 2021 14:24:28 +0200 Subject: [PATCH 070/158] sched: Move kprobes cleanup out of finish_task_switch() Doing cleanups in the tail of schedule() is a latency punishment for the incoming task. The point of invoking kprobes_task_flush() for a dead task is that the instances are returned and cannot leak when __schedule() is kprobed. Move it into the delayed cleanup. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Link: https://lore.kernel.org/r/20210928122411.537994026@linutronix.de --- kernel/exit.c | 2 ++ kernel/kprobes.c | 8 ++++---- kernel/sched/core.c | 6 ------ 3 files changed, 6 insertions(+), 10 deletions(-) Index: linux-5.15.19-rt29/kernel/exit.c =================================================================== @ linux-5.15.19-rt29/kernel/exit.c:67 @ #include <linux/rcuwait.h> #include <linux/compat.h> #include <linux/io_uring.h> +#include <linux/kprobes.h> #include <linux/uaccess.h> #include <asm/unistd.h> @ linux-5.15.19-rt29/kernel/exit.c:172 @ static void delayed_put_task_struct(stru { struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); + kprobe_flush_task(tsk); perf_event_delayed_put(tsk); trace_sched_process_free(tsk); put_task_struct(tsk); Index: linux-5.15.19-rt29/kernel/kprobes.c =================================================================== --- linux-5.15.19-rt29.orig/kernel/kprobes.c +++ linux-5.15.19-rt29/kernel/kprobes.c @ linux-5.15.19-rt29/kernel/exit.c:1253 @ void kprobe_busy_end(void) } /* - * This function is called from finish_task_switch when task tk becomes dead, - * so that we can recycle any function-return probe instances associated - * with this task. These left over instances represent probed functions - * that have been called but will never return. + * This function is called from delayed_put_task_struct() when a task is + * dead and cleaned up to recycle any function-return probe instances + * associated with this task. These left over instances represent probed + * functions that have been called but will never return. */ void kprobe_flush_task(struct task_struct *tk) { Index: linux-5.15.19-rt29/kernel/sched/core.c =================================================================== --- linux-5.15.19-rt29.orig/kernel/sched/core.c +++ linux-5.15.19-rt29/kernel/sched/core.c @ linux-5.15.19-rt29/kernel/exit.c:4852 @ static struct rq *finish_task_switch(str if (prev->sched_class->task_dead) prev->sched_class->task_dead(prev); - /* - * Remove function-return probe instances associated with this - * task and put them back on the free list. - */ - kprobe_flush_task(prev); - /* Task is done with its stack. */ put_task_stack(prev);