--- /dev/null
+From 147f04b14adde831eb4a0a1e378667429732f9e8 Mon Sep 17 00:00:00 2001
+From: "Paul E. McKenney" <paulmck@kernel.org>
+Date: Wed, 29 Sep 2021 09:21:34 -0700
+Subject: rcu: Prevent expedited GP from enabling tick on offline CPU
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+commit 147f04b14adde831eb4a0a1e378667429732f9e8 upstream.
+
+If an RCU expedited grace period starts just when a CPU is in the process
+of going offline, so that the outgoing CPU has completed its pass through
+stop-machine but has not yet completed its final dive into the idle loop,
+RCU will attempt to enable that CPU's scheduling-clock tick via a call
+to tick_dep_set_cpu(). For this to happen, that CPU has to have been
+online when the expedited grace period completed its CPU-selection phase.
+
+This is pointless: The outgoing CPU has interrupts disabled, so it cannot
+take a scheduling-clock tick anyway. In addition, the tick_dep_set_cpu()
+function's eventual call to irq_work_queue_on() will splat as follows:
+
+smpboot: CPU 1 is now offline
+WARNING: CPU: 6 PID: 124 at kernel/irq_work.c:95
++irq_work_queue_on+0x57/0x60
+Modules linked in:
+CPU: 6 PID: 124 Comm: kworker/6:2 Not tainted 5.15.0-rc1+ #3
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
++rel-1.14.0-0-g155821a-rebuilt.opensuse.org 04/01/2014
+Workqueue: rcu_gp wait_rcu_exp_gp
+RIP: 0010:irq_work_queue_on+0x57/0x60
+Code: 8b 05 1d c7 ea 62 a9 00 00 f0 00 75 21 4c 89 ce 44 89 c7 e8
++9b 37 fa ff ba 01 00 00 00 89 d0 c3 4c 89 cf e8 3b ff ff ff eb ee <0f> 0b eb b7
++0f 0b eb db 90 48 c7 c0 98 2a 02 00 65 48 03 05 91
+ 6f
+RSP: 0000:ffffb12cc038fe48 EFLAGS: 00010282
+RAX: 0000000000000001 RBX: 0000000000005208 RCX: 0000000000000020
+RDX: 0000000000000001 RSI: 0000000000000001 RDI: ffff9ad01f45a680
+RBP: 000000000004c990 R08: 0000000000000001 R09: ffff9ad01f45a680
+R10: ffffb12cc0317db0 R11: 0000000000000001 R12: 00000000fffecee8
+R13: 0000000000000001 R14: 0000000000026980 R15: ffffffff9e53ae00
+FS: 0000000000000000(0000) GS:ffff9ad01f580000(0000)
++knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000000000000000 CR3: 000000000de0c000 CR4: 00000000000006e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ tick_nohz_dep_set_cpu+0x59/0x70
+ rcu_exp_wait_wake+0x54e/0x870
+ ? sync_rcu_exp_select_cpus+0x1fc/0x390
+ process_one_work+0x1ef/0x3c0
+ ? process_one_work+0x3c0/0x3c0
+ worker_thread+0x28/0x3c0
+ ? process_one_work+0x3c0/0x3c0
+ kthread+0x115/0x140
+ ? set_kthread_struct+0x40/0x40
+ ret_from_fork+0x22/0x30
+---[ end trace c5bf75eb6aa80bc6 ]---
+
+This commit therefore avoids invoking tick_dep_set_cpu() on offlined
+CPUs to limit both futility and false-positive splats.
+
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/rcu/tree_exp.h | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/kernel/rcu/tree_exp.h
++++ b/kernel/rcu/tree_exp.h
+@@ -507,7 +507,10 @@ static void synchronize_rcu_expedited_wa
+ if (rdp->rcu_forced_tick_exp)
+ continue;
+ rdp->rcu_forced_tick_exp = true;
+- tick_dep_set_cpu(cpu, TICK_DEP_BIT_RCU_EXP);
++ preempt_disable();
++ if (cpu_online(cpu))
++ tick_dep_set_cpu(cpu, TICK_DEP_BIT_RCU_EXP);
++ preempt_enable();
+ }
+ }
+ j = READ_ONCE(jiffies_till_first_fqs);
--- /dev/null
+From 18f08e758f34e6dfe0668bee51bd2af7adacf381 Mon Sep 17 00:00:00 2001
+From: "Paul E. McKenney" <paulmck@kernel.org>
+Date: Wed, 28 Jul 2021 11:32:28 -0700
+Subject: rcu-tasks: Add trc_inspect_reader() checks for exiting critical section
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+commit 18f08e758f34e6dfe0668bee51bd2af7adacf381 upstream.
+
+Currently, trc_inspect_reader() treats a task exiting its RCU Tasks
+Trace read-side critical section the same as being within that critical
+section. However, this can fail because that task might have already
+checked its .need_qs field, which means that it might never decrement
+the all-important trc_n_readers_need_end counter. Of course, for that
+to happen, the task would need to never again execute an RCU Tasks Trace
+read-side critical section, but this really could happen if the system's
+last trampoline was removed. Note that exit from such a critical section
+cannot be treated as a quiescent state due to the possibility of nested
+critical sections. This means that if trc_inspect_reader() sees a
+negative nesting value, it must set up to try again later.
+
+This commit therefore ignores tasks that are exiting their RCU Tasks
+Trace read-side critical sections so that they will be rechecked later.
+
+[ paulmck: Apply feedback from Neeraj Upadhyay and Boqun Feng. ]
+
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Cc: Joel Fernandes <joel@joelfernandes.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/rcu/tasks.h | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/kernel/rcu/tasks.h
++++ b/kernel/rcu/tasks.h
+@@ -874,7 +874,7 @@ reset_ipi:
+ static bool trc_inspect_reader(struct task_struct *t, void *arg)
+ {
+ int cpu = task_cpu(t);
+- bool in_qs = false;
++ int nesting;
+ bool ofl = cpu_is_offline(cpu);
+
+ if (task_curr(t)) {
+@@ -894,18 +894,18 @@ static bool trc_inspect_reader(struct ta
+ n_heavy_reader_updates++;
+ if (ofl)
+ n_heavy_reader_ofl_updates++;
+- in_qs = true;
++ nesting = 0;
+ } else {
+ // The task is not running, so C-language access is safe.
+- in_qs = likely(!t->trc_reader_nesting);
++ nesting = t->trc_reader_nesting;
+ }
+
+- // Mark as checked so that the grace-period kthread will
+- // remove it from the holdout list.
+- t->trc_reader_checked = true;
+-
+- if (in_qs)
+- return true; // Already in quiescent state, done!!!
++ // If not exiting a read-side critical section, mark as checked
++ // so that the grace-period kthread will remove it from the
++ // holdout list.
++ t->trc_reader_checked = nesting >= 0;
++ if (nesting <= 0)
++ return !nesting; // If in QS, done, otherwise try again later.
+
+ // The task is in a read-side critical section, so set up its
+ // state so that it will awaken the grace-period kthread upon exit
--- /dev/null
+From 46aa886c483f57ef13cd5ea0a85e70b93eb1d381 Mon Sep 17 00:00:00 2001
+From: Neeraj Upadhyay <neeraju@codeaurora.org>
+Date: Fri, 27 Aug 2021 13:43:35 +0530
+Subject: rcu-tasks: Fix IPI failure handling in trc_wait_for_one_reader
+
+From: Neeraj Upadhyay <neeraju@codeaurora.org>
+
+commit 46aa886c483f57ef13cd5ea0a85e70b93eb1d381 upstream.
+
+The trc_wait_for_one_reader() function is called at multiple stages
+of trace rcu-tasks GP function, rcu_tasks_wait_gp():
+
+- First, it is called as part of per task function -
+ rcu_tasks_trace_pertask(), for all non-idle tasks. As part of per task
+ processing, this function add the task in the holdout list and if the
+ task is currently running on a CPU, it sends IPI to the task's CPU.
+ The IPI handler takes action depending on whether task is in trace
+ rcu-tasks read side critical section or not:
+
+ - a. If the task is in trace rcu-tasks read side critical section
+ (t->trc_reader_nesting != 0), the IPI handler sets the task's
+ ->trc_reader_special.b.need_qs, so that this task notifies exit
+ from its outermost read side critical section (by decrementing
+ trc_n_readers_need_end) to the GP handling function.
+ trc_wait_for_one_reader() also increments trc_n_readers_need_end,
+ so that the trace rcu-tasks GP handler function waits for this
+ task's read side exit notification. The IPI handler also sets
+ t->trc_reader_checked to true, and no further IPIs are sent for
+ this task, for this trace rcu-tasks grace period and this
+ task can be removed from holdout list.
+
+ - b. If the task is in the process of exiting its trace rcu-tasks
+ read side critical section, (t->trc_reader_nesting < 0), defer
+ this task's processing to future calls to trc_wait_for_one_reader().
+
+ - c. If task is not in rcu-task read side critical section,
+ t->trc_reader_nesting == 0, ->trc_reader_checked is set for this
+ task, so that this task is removed from holdout list.
+
+- Second, trc_wait_for_one_reader() is called as part of post scan, in
+ function rcu_tasks_trace_postscan(), for all idle tasks.
+
+- Third, in function check_all_holdout_tasks_trace(), this function is
+ called for each task in the holdout list, but only if there isn't
+ a pending IPI for the task (->trc_ipi_to_cpu == -1). This function
+ removed the task from holdout list, if IPI handler has completed the
+ required work, to ensure that the current trace rcu-tasks grace period
+ either waits for this task, or this task is not in a trace rcu-tasks
+ read side critical section.
+
+Now, considering the scenario where smp_call_function_single() fails in
+first case, inside rcu_tasks_trace_pertask(). In this case,
+->trc_ipi_to_cpu is set to the current CPU for that task. This will
+result in trc_wait_for_one_reader() getting skipped in third case,
+inside check_all_holdout_tasks_trace(), for this task. This further
+results in ->trc_reader_checked never getting set for this task,
+and the task not getting removed from holdout list. This can cause
+the current trace rcu-tasks grace period to stall.
+
+Fix the above problem, by resetting ->trc_ipi_to_cpu to -1, on
+smp_call_function_single() failure, so that future IPI calls can
+be send for this task.
+
+Note that all three of the trc_wait_for_one_reader() function's
+callers (rcu_tasks_trace_pertask(), rcu_tasks_trace_postscan(),
+check_all_holdout_tasks_trace()) hold cpu_read_lock(). This means
+that smp_call_function_single() cannot race with CPU hotplug, and thus
+should never fail. Therefore, also add a warning in order to report
+any such failure in case smp_call_function_single() grows some other
+reason for failure.
+
+Signed-off-by: Neeraj Upadhyay <neeraju@codeaurora.org>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Cc: Joel Fernandes <joel@joelfernandes.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/rcu/tasks.h | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/kernel/rcu/tasks.h
++++ b/kernel/rcu/tasks.h
+@@ -958,9 +958,11 @@ static void trc_wait_for_one_reader(stru
+ if (smp_call_function_single(cpu, trc_read_check_handler, t, 0)) {
+ // Just in case there is some other reason for
+ // failure than the target CPU being offline.
++ WARN_ONCE(1, "%s(): smp_call_function_single() failed for CPU: %d\n",
++ __func__, cpu);
+ rcu_tasks_trace.n_ipis_fails++;
+ per_cpu(trc_ipi_to_cpu, cpu) = false;
+- t->trc_ipi_to_cpu = cpu;
++ t->trc_ipi_to_cpu = -1;
+ }
+ }
+ }
--- /dev/null
+From cbe0d8d91415c9692fe88191940d98952b6855d9 Mon Sep 17 00:00:00 2001
+From: "Paul E. McKenney" <paulmck@kernel.org>
+Date: Fri, 30 Jul 2021 12:17:59 -0700
+Subject: rcu-tasks: Wait for trc_read_check_handler() IPIs
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+commit cbe0d8d91415c9692fe88191940d98952b6855d9 upstream.
+
+Currently, RCU Tasks Trace initializes the trc_n_readers_need_end counter
+to the value one, increments it before each trc_read_check_handler()
+IPI, then decrements it within trc_read_check_handler() if the target
+task was in a quiescent state (or if the target task moved to some other
+CPU while the IPI was in flight), complaining if the new value was zero.
+The rationale for complaining is that the initial value of one must be
+decremented away before zero can be reached, and this decrement has not
+yet happened.
+
+Except that trc_read_check_handler() is initiated with an asynchronous
+smp_call_function_single(), which might be significantly delayed. This
+can result in false-positive complaints about the counter reaching zero.
+
+This commit therefore waits for in-flight IPI handlers to complete before
+decrementing away the initial value of one from the trc_n_readers_need_end
+counter.
+
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Cc: Joel Fernandes <joel@joelfernandes.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/rcu/tasks.h | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/kernel/rcu/tasks.h
++++ b/kernel/rcu/tasks.h
+@@ -1083,14 +1083,28 @@ static void check_all_holdout_tasks_trac
+ }
+ }
+
++static void rcu_tasks_trace_empty_fn(void *unused)
++{
++}
++
+ /* Wait for grace period to complete and provide ordering. */
+ static void rcu_tasks_trace_postgp(struct rcu_tasks *rtp)
+ {
++ int cpu;
+ bool firstreport;
+ struct task_struct *g, *t;
+ LIST_HEAD(holdouts);
+ long ret;
+
++ // Wait for any lingering IPI handlers to complete. Note that
++ // if a CPU has gone offline or transitioned to userspace in the
++ // meantime, all IPI handlers should have been drained beforehand.
++ // Yes, this assumes that CPUs process IPIs in order. If that ever
++ // changes, there will need to be a recheck and/or timed wait.
++ for_each_online_cpu(cpu)
++ if (smp_load_acquire(per_cpu_ptr(&trc_ipi_to_cpu, cpu)))
++ smp_call_function_single(cpu, rcu_tasks_trace_empty_fn, NULL, 1);
++
+ // Remove the safety count.
+ smp_mb__before_atomic(); // Order vs. earlier atomics
+ atomic_dec(&trc_n_readers_need_end);
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/mips/alchemy/common/dbdma.c | 27 ++++++++++++---------------
1 file changed, 12 insertions(+), 15 deletions(-)
mhi-pci_generic-fix-implicit-conversion-warning.patch
revert-drm-amdgpu-install-stub-fence-into-potential-unused-fence-pointers.patch
revert-mips-alchemy-fix-dbdma2.patch
+rcu-prevent-expedited-gp-from-enabling-tick-on-offline-cpu.patch
+rcu-tasks-fix-ipi-failure-handling-in-trc_wait_for_one_reader.patch
+rcu-tasks-wait-for-trc_read_check_handler-ipis.patch
+rcu-tasks-add-trc_inspect_reader-checks-for-exiting-critical-section.patch