Revert "Bluetooth: Store advertising handle so it can be re-enabled"
[platform/kernel/linux-rpi.git] / kernel / signal.c
index 0901901..b710263 100644 (file)
@@ -2329,15 +2329,35 @@ 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 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.
+        *
+        * On PREEMPT_RT locking tasklist_lock does not disable preemption.
+        * Therefore the task can be preempted (after
+        * do_notify_parent_cldstop()) before unlocking tasklist_lock so there
+        * is no benefit in doing this. The optimisation is harmful on
+        * PEEMPT_RT because the spinlock_t (in cgroup_enter_frozen()) must not
+        * be acquired with disabled preemption.
         */
-       preempt_disable();
+       if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_disable();
        read_unlock(&tasklist_lock);
        cgroup_enter_frozen();
-       preempt_enable_no_resched();
+       if (!IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_enable_no_resched();
        schedule();
        cgroup_leave_frozen(true);