Commit 53da1d9456fe7 ("fix ptrace slowness") added a preempt-disable section
between read_unlock() and the following schedule() invocation without
explaining why it is needed.
Replace the comment with an explanation why this is needed. Clarify that
it is needed for correctness but for performance reasons.
Acked-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
kernel/signal.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2318,10 +2318,21 @@ static int ptrace_stop(int exit_code, in
do_notify_parent_cldstop(current, false, why);
/*
- * Don't want to allow preemption here, because
- * sys_ptrace() needs this task to be inactive.
+ * The previous do_notify_parent_cldstop() invocation woke ptracer.
+ * One a PREEMPTION kernel this can result in preemption requirement
+ * which will be fulfilled after read_unlock() and the ptracer will be
+ * put on the CPU.
+ * The ptracer is in wait_task_inactive(, __TASK_TRACED) waiting for
+ * this task wait in schedule(). If this task gets preempted then it
+ * remains enqueued on the runqueue. The ptracer will observe this and
+ * then sleep for a delay of one HZ tick. In the meantime this task
+ * gets scheduled, enters schedule() and will wait for the ptracer.
*
- * XXX: implement read_unlock_no_resched().
+ * This preemption point is not bad from correctness point of view but
+ * extends the runtime by one HZ tick time due to the ptracer's sleep.
+ * The preempt-disable section ensures that there will be no preemption
+ * between unlock and schedule() and so improving the performance since
+ * the ptracer has no reason to sleep.
*/
preempt_disable();
read_unlock(&tasklist_lock);
The following commit has been merged into the core/core branch of tip:
Commit-ID: a20d6f63dbfc176697886d7709312ad0a795648e
Gitweb: https://git.kernel.org/tip/a20d6f63dbfc176697886d7709312ad0a795648e
Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
AuthorDate: Thu, 03 Aug 2023 12:09:31 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Tue, 19 Sep 2023 22:08:29 +02:00
signal: Add a proper comment about preempt_disable() in ptrace_stop()
Commit 53da1d9456fe7 ("fix ptrace slowness") added a preempt-disable section
between read_unlock() and the following schedule() invocation without
explaining why it is needed.
Replace the existing contentless comment with a proper explanation to
clarify that it is not needed for correctness but for performance reasons.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Link: https://lore.kernel.org/r/20230803100932.325870-2-bigeasy@linutronix.de
---
kernel/signal.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/kernel/signal.c b/kernel/signal.c
index 0901901..3035beb 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2329,10 +2329,22 @@ static int ptrace_stop(int exit_code, int why, unsigned long message,
do_notify_parent_cldstop(current, false, why);
/*
- * Don't want to allow preemption here, because
- * sys_ptrace() needs this task to be inactive.
+ * The previous do_notify_parent_cldstop() invocation woke ptracer.
+ * One a PREEMPTION kernel this can result in preemption requirement
+ * which will be fulfilled after read_unlock() and the ptracer will be
+ * put on the CPU.
+ * The ptracer is in wait_task_inactive(, __TASK_TRACED) waiting for
+ * this task wait in schedule(). If this task gets preempted then it
+ * remains enqueued on the runqueue. The ptracer will observe this and
+ * then sleep for a delay of one HZ tick. In the meantime this task
+ * gets scheduled, enters schedule() and will wait for the ptracer.
*
- * XXX: implement read_unlock_no_resched().
+ * This preemption point is not bad from a correctness point of
+ * view but extends the runtime by one HZ tick time due to the
+ * ptracer's sleep. The preempt-disable section ensures that there
+ * will be no preemption between unlock and schedule() and so
+ * improving the performance since the ptracer will observe that
+ * the tracee is scheduled out once it gets on the CPU.
*/
preempt_disable();
read_unlock(&tasklist_lock);
* tip-bot2 for Sebastian Andrzej Siewior <tip-bot2@linutronix.de> wrote:
> The following commit has been merged into the core/core branch of tip:
>
> Commit-ID: a20d6f63dbfc176697886d7709312ad0a795648e
> Gitweb: https://git.kernel.org/tip/a20d6f63dbfc176697886d7709312ad0a795648e
> Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> AuthorDate: Thu, 03 Aug 2023 12:09:31 +02:00
> Committer: Thomas Gleixner <tglx@linutronix.de>
> CommitterDate: Tue, 19 Sep 2023 22:08:29 +02:00
>
> signal: Add a proper comment about preempt_disable() in ptrace_stop()
>
> Commit 53da1d9456fe7 ("fix ptrace slowness") added a preempt-disable section
> between read_unlock() and the following schedule() invocation without
> explaining why it is needed.
>
> Replace the existing contentless comment with a proper explanation to
> clarify that it is not needed for correctness but for performance reasons.
>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Acked-by: Oleg Nesterov <oleg@redhat.com>
> Link: https://lore.kernel.org/r/20230803100932.325870-2-bigeasy@linutronix.de
>
> ---
> kernel/signal.c | 18 +++++++++++++++---
> 1 file changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/kernel/signal.c b/kernel/signal.c
> index 0901901..3035beb 100644
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
> @@ -2329,10 +2329,22 @@ static int ptrace_stop(int exit_code, int why, unsigned long message,
> do_notify_parent_cldstop(current, false, why);
>
Minor speling nits:
> /*
> - * Don't want to allow preemption here, because
> - * sys_ptrace() needs this task to be inactive.
> + * The previous do_notify_parent_cldstop() invocation woke ptracer.
> + * One a PREEMPTION kernel this can result in preemption requirement
s/One
/On
> + * which will be fulfilled after read_unlock() and the ptracer will be
> + * put on the CPU.
> + * The ptracer is in wait_task_inactive(, __TASK_TRACED) waiting for
> + * this task wait in schedule(). If this task gets preempted then it
> + * remains enqueued on the runqueue. The ptracer will observe this and
> + * then sleep for a delay of one HZ tick. In the meantime this task
> + * gets scheduled, enters schedule() and will wait for the ptracer.
> *
> - * XXX: implement read_unlock_no_resched().
> + * This preemption point is not bad from a correctness point of
> + * view but extends the runtime by one HZ tick time due to the
> + * ptracer's sleep. The preempt-disable section ensures that there
> + * will be no preemption between unlock and schedule() and so
> + * improving the performance since the ptracer will observe that
s/improving the performance
/improving performance
> + * the tracee is scheduled out once it gets on the CPU.
> */
> preempt_disable();
> read_unlock(&tasklist_lock);
Thanks,
Ingo
Ingo spotted typos in the recently added comment and suggested
corrections.
Use 'On' instead of 'One' and remove one superfluous 'the' in a
sentence.
Suggested-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
kernel/signal.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/signal.c b/kernel/signal.c
index f2a5578326ade..384b77ad1bc15 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2330,7 +2330,7 @@ static int ptrace_stop(int exit_code, int why, unsigned long message,
/*
* The previous do_notify_parent_cldstop() invocation woke ptracer.
- * One a PREEMPTION kernel this can result in preemption requirement
+ * On a PREEMPTION kernel this can result in preemption requirement
* which will be fulfilled after read_unlock() and the ptracer will be
* put on the CPU.
* The ptracer is in wait_task_inactive(, __TASK_TRACED) waiting for
@@ -2343,7 +2343,7 @@ static int ptrace_stop(int exit_code, int why, unsigned long message,
* view but extends the runtime by one HZ tick time due to the
* ptracer's sleep. The preempt-disable section ensures that there
* will be no preemption between unlock and schedule() and so
- * improving the performance since the ptracer will observe that
+ * improving performance since the ptracer will observe that
* the tracee is scheduled out once it gets on the CPU.
*
* On PREEMPT_RT locking tasklist_lock does not disable preemption.
--
2.40.1
© 2016 - 2026 Red Hat, Inc.