]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Nov 2017 12:22:58 +0000 (13:22 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Nov 2017 12:22:58 +0000 (13:22 +0100)
added patches:
cpufreq-schedutil-reset-cached_raw_freq-when-not-in-sync-with-next_freq.patch
lib-mpi-call-cond_resched-from-mpi_powm-loop.patch
sched-make-resched_cpu-unconditional.patch
serdev-fix-registration-of-second-slave.patch

queue-4.14/cpufreq-schedutil-reset-cached_raw_freq-when-not-in-sync-with-next_freq.patch [new file with mode: 0644]
queue-4.14/lib-mpi-call-cond_resched-from-mpi_powm-loop.patch [new file with mode: 0644]
queue-4.14/sched-make-resched_cpu-unconditional.patch [new file with mode: 0644]
queue-4.14/serdev-fix-registration-of-second-slave.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/cpufreq-schedutil-reset-cached_raw_freq-when-not-in-sync-with-next_freq.patch b/queue-4.14/cpufreq-schedutil-reset-cached_raw_freq-when-not-in-sync-with-next_freq.patch
new file mode 100644 (file)
index 0000000..8a7cf34
--- /dev/null
@@ -0,0 +1,52 @@
+From 07458f6a5171d97511dfbdf6ce549ed2ca0280c7 Mon Sep 17 00:00:00 2001
+From: Viresh Kumar <viresh.kumar@linaro.org>
+Date: Wed, 8 Nov 2017 20:23:55 +0530
+Subject: cpufreq: schedutil: Reset cached_raw_freq when not in sync with next_freq
+
+From: Viresh Kumar <viresh.kumar@linaro.org>
+
+commit 07458f6a5171d97511dfbdf6ce549ed2ca0280c7 upstream.
+
+'cached_raw_freq' is used to get the next frequency quickly but should
+always be in sync with sg_policy->next_freq. There is a case where it is
+not and in such cases it should be reset to avoid switching to incorrect
+frequencies.
+
+Consider this case for example:
+
+ - policy->cur is 1.2 GHz (Max)
+ - New request comes for 780 MHz and we store that in cached_raw_freq.
+ - Based on 780 MHz, we calculate the effective frequency as 800 MHz.
+ - We then see the CPU wasn't idle recently and choose to keep the next
+   freq as 1.2 GHz.
+ - Now we have cached_raw_freq is 780 MHz and sg_policy->next_freq is
+   1.2 GHz.
+ - Now if the utilization doesn't change in then next request, then the
+   next target frequency will still be 780 MHz and it will match with
+   cached_raw_freq. But we will choose 1.2 GHz instead of 800 MHz here.
+
+Fixes: b7eaf1aab9f8 (cpufreq: schedutil: Avoid reducing frequency of busy CPUs prematurely)
+Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/sched/cpufreq_schedutil.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/kernel/sched/cpufreq_schedutil.c
++++ b/kernel/sched/cpufreq_schedutil.c
+@@ -282,8 +282,12 @@ static void sugov_update_single(struct u
+                * Do not reduce the frequency if the CPU has not been idle
+                * recently, as the reduction is likely to be premature then.
+                */
+-              if (busy && next_f < sg_policy->next_freq)
++              if (busy && next_f < sg_policy->next_freq) {
+                       next_f = sg_policy->next_freq;
++
++                      /* Reset cached freq as next_freq has changed */
++                      sg_policy->cached_raw_freq = 0;
++              }
+       }
+       sugov_update_commit(sg_policy, time, next_f);
+ }
diff --git a/queue-4.14/lib-mpi-call-cond_resched-from-mpi_powm-loop.patch b/queue-4.14/lib-mpi-call-cond_resched-from-mpi_powm-loop.patch
new file mode 100644 (file)
index 0000000..063e4bc
--- /dev/null
@@ -0,0 +1,49 @@
+From 1d9ddde12e3c9bab7f3d3484eb9446315e3571ca Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Tue, 7 Nov 2017 14:15:27 -0800
+Subject: lib/mpi: call cond_resched() from mpi_powm() loop
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit 1d9ddde12e3c9bab7f3d3484eb9446315e3571ca upstream.
+
+On a non-preemptible kernel, if KEYCTL_DH_COMPUTE is called with the
+largest permitted inputs (16384 bits), the kernel spends 10+ seconds
+doing modular exponentiation in mpi_powm() without rescheduling.  If all
+threads do it, it locks up the system.  Moreover, it can cause
+rcu_sched-stall warnings.
+
+Notwithstanding the insanity of doing this calculation in kernel mode
+rather than in userspace, fix it by calling cond_resched() as each bit
+from the exponent is processed.  It's still noninterruptible, but at
+least it's preemptible now.
+
+Do the cond_resched() once per bit rather than once per MPI limb because
+each limb might still easily take 100+ milliseconds on slow CPUs.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ lib/mpi/mpi-pow.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/lib/mpi/mpi-pow.c
++++ b/lib/mpi/mpi-pow.c
+@@ -26,6 +26,7 @@
+  *     however I decided to publish this code under the plain GPL.
+  */
++#include <linux/sched.h>
+ #include <linux/string.h>
+ #include "mpi-internal.h"
+ #include "longlong.h"
+@@ -256,6 +257,7 @@ int mpi_powm(MPI res, MPI base, MPI exp,
+                               }
+                               e <<= 1;
+                               c--;
++                              cond_resched();
+                       }
+                       i--;
diff --git a/queue-4.14/sched-make-resched_cpu-unconditional.patch b/queue-4.14/sched-make-resched_cpu-unconditional.patch
new file mode 100644 (file)
index 0000000..96b75b2
--- /dev/null
@@ -0,0 +1,66 @@
+From 7c2102e56a3f7d85b5d8f33efbd7aecc1f36fdd8 Mon Sep 17 00:00:00 2001
+From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
+Date: Mon, 18 Sep 2017 08:54:40 -0700
+Subject: sched: Make resched_cpu() unconditional
+
+From: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+
+commit 7c2102e56a3f7d85b5d8f33efbd7aecc1f36fdd8 upstream.
+
+The current implementation of synchronize_sched_expedited() incorrectly
+assumes that resched_cpu() is unconditional, which it is not.  This means
+that synchronize_sched_expedited() can hang when resched_cpu()'s trylock
+fails as follows (analysis by Neeraj Upadhyay):
+
+o      CPU1 is waiting for expedited wait to complete:
+
+       sync_rcu_exp_select_cpus
+            rdp->exp_dynticks_snap & 0x1   // returns 1 for CPU5
+            IPI sent to CPU5
+
+       synchronize_sched_expedited_wait
+                ret = swait_event_timeout(rsp->expedited_wq,
+                                          sync_rcu_preempt_exp_done(rnp_root),
+                                          jiffies_stall);
+
+       expmask = 0x20, CPU 5 in idle path (in cpuidle_enter())
+
+o      CPU5 handles IPI and fails to acquire rq lock.
+
+       Handles IPI
+            sync_sched_exp_handler
+                resched_cpu
+                    returns while failing to try lock acquire rq->lock
+                need_resched is not set
+
+o      CPU5 calls  rcu_idle_enter() and as need_resched is not set, goes to
+       idle (schedule() is not called).
+
+o      CPU 1 reports RCU stall.
+
+Given that resched_cpu() is now used only by RCU, this commit fixes the
+assumption by making resched_cpu() unconditional.
+
+Reported-by: Neeraj Upadhyay <neeraju@codeaurora.org>
+Suggested-by: Neeraj Upadhyay <neeraju@codeaurora.org>
+Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/sched/core.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -505,8 +505,7 @@ void resched_cpu(int cpu)
+       struct rq *rq = cpu_rq(cpu);
+       unsigned long flags;
+-      if (!raw_spin_trylock_irqsave(&rq->lock, flags))
+-              return;
++      raw_spin_lock_irqsave(&rq->lock, flags);
+       resched_curr(rq);
+       raw_spin_unlock_irqrestore(&rq->lock, flags);
+ }
diff --git a/queue-4.14/serdev-fix-registration-of-second-slave.patch b/queue-4.14/serdev-fix-registration-of-second-slave.patch
new file mode 100644 (file)
index 0000000..b64df05
--- /dev/null
@@ -0,0 +1,90 @@
+From 08fcee289f341786eb3b44e5f2d1dc850943238e Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 10 Oct 2017 18:09:49 +0200
+Subject: serdev: fix registration of second slave
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 08fcee289f341786eb3b44e5f2d1dc850943238e upstream.
+
+Serdev currently only supports a single slave device, but the required
+sanity checks to prevent further registration attempts were missing.
+
+If a serial-port node has two child nodes with compatible properties,
+the OF code would try to register two slave devices using the same id
+and name. Driver core will not allow this (and there will be loud
+complaints), but the controller's slave pointer would already have been
+set to address of the soon to be deallocated second struct
+serdev_device. As the first slave device remains registered, this can
+lead to later use-after-free issues when the slave callbacks are
+accessed.
+
+Note that while the serdev registration helpers are exported, they are
+typically only called by serdev core. Any other (out-of-tree) callers
+must serialise registration and deregistration themselves.
+
+Fixes: cd6484e1830b ("serdev: Introduce new bus for serial attached devices")
+Cc: Rob Herring <robh@kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serdev/core.c |   19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+--- a/drivers/tty/serdev/core.c
++++ b/drivers/tty/serdev/core.c
+@@ -65,21 +65,32 @@ static int serdev_uevent(struct device *
+  */
+ int serdev_device_add(struct serdev_device *serdev)
+ {
++      struct serdev_controller *ctrl = serdev->ctrl;
+       struct device *parent = serdev->dev.parent;
+       int err;
+       dev_set_name(&serdev->dev, "%s-%d", dev_name(parent), serdev->nr);
++      /* Only a single slave device is currently supported. */
++      if (ctrl->serdev) {
++              dev_err(&serdev->dev, "controller busy\n");
++              return -EBUSY;
++      }
++      ctrl->serdev = serdev;
++
+       err = device_add(&serdev->dev);
+       if (err < 0) {
+               dev_err(&serdev->dev, "Can't add %s, status %d\n",
+                       dev_name(&serdev->dev), err);
+-              goto err_device_add;
++              goto err_clear_serdev;
+       }
+       dev_dbg(&serdev->dev, "device %s registered\n", dev_name(&serdev->dev));
+-err_device_add:
++      return 0;
++
++err_clear_serdev:
++      ctrl->serdev = NULL;
+       return err;
+ }
+ EXPORT_SYMBOL_GPL(serdev_device_add);
+@@ -90,7 +101,10 @@ EXPORT_SYMBOL_GPL(serdev_device_add);
+  */
+ void serdev_device_remove(struct serdev_device *serdev)
+ {
++      struct serdev_controller *ctrl = serdev->ctrl;
++
+       device_unregister(&serdev->dev);
++      ctrl->serdev = NULL;
+ }
+ EXPORT_SYMBOL_GPL(serdev_device_remove);
+@@ -295,7 +309,6 @@ struct serdev_device *serdev_device_allo
+               return NULL;
+       serdev->ctrl = ctrl;
+-      ctrl->serdev = serdev;
+       device_initialize(&serdev->dev);
+       serdev->dev.parent = &ctrl->dev;
+       serdev->dev.bus = &serdev_bus_type;
index 9a3b10c5bb1ff29483aa02243751e482dedae783..2516bc4ba4bdc3311a90d1a2213fb7f7d6b01722 100644 (file)
@@ -6,3 +6,7 @@ s390-disassembler-add-missing-end-marker-for-e7-table.patch
 s390-disassembler-increase-show_code-buffer-size.patch
 acpi-pm-fix-acpi_pm_notifier_lock-vs-flush_workqueue-deadlock.patch
 acpi-ec-fix-regression-related-to-triggering-source-of-ec-event-handling.patch
+cpufreq-schedutil-reset-cached_raw_freq-when-not-in-sync-with-next_freq.patch
+serdev-fix-registration-of-second-slave.patch
+sched-make-resched_cpu-unconditional.patch
+lib-mpi-call-cond_resched-from-mpi_powm-loop.patch