]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 Jan 2020 14:44:51 +0000 (15:44 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 30 Jan 2020 14:44:51 +0000 (15:44 +0100)
added patches:
crypto-af_alg-use-bh_lock_sock-in-sk_destruct.patch
random-try-to-actively-add-entropy-rather-than-passively-wait-for-it.patch
rsi-fix-memory-leak-on-failed-urb-submission.patch
rsi-fix-non-atomic-allocation-in-completion-handler.patch
rsi-fix-use-after-free-on-probe-errors.patch
sched-fair-add-tmp_alone_branch-assertion.patch
sched-fair-fix-insertion-in-rq-leaf_cfs_rq_list.patch

queue-4.19/crypto-af_alg-use-bh_lock_sock-in-sk_destruct.patch [new file with mode: 0644]
queue-4.19/random-try-to-actively-add-entropy-rather-than-passively-wait-for-it.patch [new file with mode: 0644]
queue-4.19/rsi-fix-memory-leak-on-failed-urb-submission.patch [new file with mode: 0644]
queue-4.19/rsi-fix-non-atomic-allocation-in-completion-handler.patch [new file with mode: 0644]
queue-4.19/rsi-fix-use-after-free-on-probe-errors.patch [new file with mode: 0644]
queue-4.19/sched-fair-add-tmp_alone_branch-assertion.patch [new file with mode: 0644]
queue-4.19/sched-fair-fix-insertion-in-rq-leaf_cfs_rq_list.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/crypto-af_alg-use-bh_lock_sock-in-sk_destruct.patch b/queue-4.19/crypto-af_alg-use-bh_lock_sock-in-sk_destruct.patch
new file mode 100644 (file)
index 0000000..1d8c845
--- /dev/null
@@ -0,0 +1,43 @@
+From 37f96694cf73ba116993a9d2d99ad6a75fa7fdb0 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Thu, 5 Dec 2019 13:45:05 +0800
+Subject: crypto: af_alg - Use bh_lock_sock in sk_destruct
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+commit 37f96694cf73ba116993a9d2d99ad6a75fa7fdb0 upstream.
+
+As af_alg_release_parent may be called from BH context (most notably
+due to an async request that only completes after socket closure,
+or as reported here because of an RCU-delayed sk_destruct call), we
+must use bh_lock_sock instead of lock_sock.
+
+Reported-by: syzbot+c2f1558d49e25cc36e5e@syzkaller.appspotmail.com
+Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
+Fixes: c840ac6af3f8 ("crypto: af_alg - Disallow bind/setkey/...")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/af_alg.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/crypto/af_alg.c
++++ b/crypto/af_alg.c
+@@ -139,11 +139,13 @@ void af_alg_release_parent(struct sock *
+       sk = ask->parent;
+       ask = alg_sk(sk);
+-      lock_sock(sk);
++      local_bh_disable();
++      bh_lock_sock(sk);
+       ask->nokey_refcnt -= nokey;
+       if (!last)
+               last = !--ask->refcnt;
+-      release_sock(sk);
++      bh_unlock_sock(sk);
++      local_bh_enable();
+       if (last)
+               sock_put(sk);
diff --git a/queue-4.19/random-try-to-actively-add-entropy-rather-than-passively-wait-for-it.patch b/queue-4.19/random-try-to-actively-add-entropy-rather-than-passively-wait-for-it.patch
new file mode 100644 (file)
index 0000000..b98baa4
--- /dev/null
@@ -0,0 +1,146 @@
+From 50ee7529ec4500c88f8664560770a7a1b65db72b Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Sat, 28 Sep 2019 16:53:52 -0700
+Subject: random: try to actively add entropy rather than passively wait for it
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 50ee7529ec4500c88f8664560770a7a1b65db72b upstream.
+
+For 5.3 we had to revert a nice ext4 IO pattern improvement, because it
+caused a bootup regression due to lack of entropy at bootup together
+with arguably broken user space that was asking for secure random
+numbers when it really didn't need to.
+
+See commit 72dbcf721566 (Revert "ext4: make __ext4_get_inode_loc plug").
+
+This aims to solve the issue by actively generating entropy noise using
+the CPU cycle counter when waiting for the random number generator to
+initialize.  This only works when you have a high-frequency time stamp
+counter available, but that's the case on all modern x86 CPU's, and on
+most other modern CPU's too.
+
+What we do is to generate jitter entropy from the CPU cycle counter
+under a somewhat complex load: calling the scheduler while also
+guaranteeing a certain amount of timing noise by also triggering a
+timer.
+
+I'm sure we can tweak this, and that people will want to look at other
+alternatives, but there's been a number of papers written on jitter
+entropy, and this should really be fairly conservative by crediting one
+bit of entropy for every timer-induced jump in the cycle counter.  Not
+because the timer itself would be all that unpredictable, but because
+the interaction between the timer and the loop is going to be.
+
+Even if (and perhaps particularly if) the timer actually happens on
+another CPU, the cacheline interaction between the loop that reads the
+cycle counter and the timer itself firing is going to add perturbations
+to the cycle counter values that get mixed into the entropy pool.
+
+As Thomas pointed out, with a modern out-of-order CPU, even quite simple
+loops show a fair amount of hard-to-predict timing variability even in
+the absense of external interrupts.  But this tries to take that further
+by actually having a fairly complex interaction.
+
+This is not going to solve the entropy issue for architectures that have
+no CPU cycle counter, but it's not clear how (and if) that is solvable,
+and the hardware in question is largely starting to be irrelevant.  And
+by doing this we can at least avoid some of the even more contentious
+approaches (like making the entropy waiting time out in order to avoid
+the possibly unbounded waiting).
+
+Cc: Ahmed Darwish <darwish.07@gmail.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Theodore Ts'o <tytso@mit.edu>
+Cc: Nicholas Mc Guire <hofrat@opentech.at>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Willy Tarreau <w@1wt.eu>
+Cc: Alexander E. Patrakov <patrakov@gmail.com>
+Cc: Lennart Poettering <mzxreary@0pointer.de>
+Cc: Noah Meyerhans <noahm@debian.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/random.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 61 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -1653,6 +1653,56 @@ void get_random_bytes(void *buf, int nby
+ }
+ EXPORT_SYMBOL(get_random_bytes);
++
++/*
++ * Each time the timer fires, we expect that we got an unpredictable
++ * jump in the cycle counter. Even if the timer is running on another
++ * CPU, the timer activity will be touching the stack of the CPU that is
++ * generating entropy..
++ *
++ * Note that we don't re-arm the timer in the timer itself - we are
++ * happy to be scheduled away, since that just makes the load more
++ * complex, but we do not want the timer to keep ticking unless the
++ * entropy loop is running.
++ *
++ * So the re-arming always happens in the entropy loop itself.
++ */
++static void entropy_timer(struct timer_list *t)
++{
++      credit_entropy_bits(&input_pool, 1);
++}
++
++/*
++ * If we have an actual cycle counter, see if we can
++ * generate enough entropy with timing noise
++ */
++static void try_to_generate_entropy(void)
++{
++      struct {
++              unsigned long now;
++              struct timer_list timer;
++      } stack;
++
++      stack.now = random_get_entropy();
++
++      /* Slow counter - or none. Don't even bother */
++      if (stack.now == random_get_entropy())
++              return;
++
++      timer_setup_on_stack(&stack.timer, entropy_timer, 0);
++      while (!crng_ready()) {
++              if (!timer_pending(&stack.timer))
++                      mod_timer(&stack.timer, jiffies+1);
++              mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
++              schedule();
++              stack.now = random_get_entropy();
++      }
++
++      del_timer_sync(&stack.timer);
++      destroy_timer_on_stack(&stack.timer);
++      mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
++}
++
+ /*
+  * Wait for the urandom pool to be seeded and thus guaranteed to supply
+  * cryptographically secure random numbers. This applies to: the /dev/urandom
+@@ -1667,7 +1717,17 @@ int wait_for_random_bytes(void)
+ {
+       if (likely(crng_ready()))
+               return 0;
+-      return wait_event_interruptible(crng_init_wait, crng_ready());
++
++      do {
++              int ret;
++              ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
++              if (ret)
++                      return ret > 0 ? 0 : ret;
++
++              try_to_generate_entropy();
++      } while (!crng_ready());
++
++      return 0;
+ }
+ EXPORT_SYMBOL(wait_for_random_bytes);
diff --git a/queue-4.19/rsi-fix-memory-leak-on-failed-urb-submission.patch b/queue-4.19/rsi-fix-memory-leak-on-failed-urb-submission.patch
new file mode 100644 (file)
index 0000000..af7392c
--- /dev/null
@@ -0,0 +1,37 @@
+From 47768297481184932844ab01a86752ba31a38861 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 28 Nov 2019 18:22:02 +0100
+Subject: rsi: fix memory leak on failed URB submission
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 47768297481184932844ab01a86752ba31a38861 upstream.
+
+Make sure to free the skb on failed receive-URB submission (e.g. on
+disconnect or currently also due to a missing endpoint).
+
+Fixes: a1854fae1414 ("rsi: improve RX packet handling in USB interface")
+Cc: stable <stable@vger.kernel.org>     # 4.17
+Cc: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rsi/rsi_91x_usb.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
++++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
+@@ -327,8 +327,10 @@ static int rsi_rx_urb_submit(struct rsi_
+                         rx_cb);
+       status = usb_submit_urb(urb, GFP_KERNEL);
+-      if (status)
++      if (status) {
+               rsi_dbg(ERR_ZONE, "%s: Failed in urb submission\n", __func__);
++              dev_kfree_skb(skb);
++      }
+       return status;
+ }
diff --git a/queue-4.19/rsi-fix-non-atomic-allocation-in-completion-handler.patch b/queue-4.19/rsi-fix-non-atomic-allocation-in-completion-handler.patch
new file mode 100644 (file)
index 0000000..357a1a9
--- /dev/null
@@ -0,0 +1,84 @@
+From b9b9f9fea21830f85cf0148cd8dce001ae55ead1 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 28 Nov 2019 18:22:03 +0100
+Subject: rsi: fix non-atomic allocation in completion handler
+
+From: Johan Hovold <johan@kernel.org>
+
+commit b9b9f9fea21830f85cf0148cd8dce001ae55ead1 upstream.
+
+USB completion handlers are called in atomic context and must
+specifically not allocate memory using GFP_KERNEL.
+
+Fixes: a1854fae1414 ("rsi: improve RX packet handling in USB interface")
+Cc: stable <stable@vger.kernel.org> # 4.17
+Cc: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rsi/rsi_91x_usb.c |   13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
++++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
+@@ -16,6 +16,7 @@
+  */
+ #include <linux/module.h>
++#include <linux/types.h>
+ #include <net/rsi_91x.h>
+ #include "rsi_usb.h"
+ #include "rsi_hal.h"
+@@ -29,7 +30,7 @@ MODULE_PARM_DESC(dev_oper_mode,
+                "9[Wi-Fi STA + BT LE], 13[Wi-Fi STA + BT classic + BT LE]\n"
+                "6[AP + BT classic], 14[AP + BT classic + BT LE]");
+-static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num);
++static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num, gfp_t flags);
+ /**
+  * rsi_usb_card_write() - This function writes to the USB Card.
+@@ -283,7 +284,7 @@ static void rsi_rx_done_handler(struct u
+       status = 0;
+ out:
+-      if (rsi_rx_urb_submit(dev->priv, rx_cb->ep_num))
++      if (rsi_rx_urb_submit(dev->priv, rx_cb->ep_num, GFP_ATOMIC))
+               rsi_dbg(ERR_ZONE, "%s: Failed in urb submission", __func__);
+       if (status)
+@@ -296,7 +297,7 @@ out:
+  *
+  * Return: 0 on success, a negative error code on failure.
+  */
+-static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num)
++static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num, gfp_t mem_flags)
+ {
+       struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
+       struct rx_usb_ctrl_block *rx_cb = &dev->rx_cb[ep_num - 1];
+@@ -326,7 +327,7 @@ static int rsi_rx_urb_submit(struct rsi_
+                         rsi_rx_done_handler,
+                         rx_cb);
+-      status = usb_submit_urb(urb, GFP_KERNEL);
++      status = usb_submit_urb(urb, mem_flags);
+       if (status) {
+               rsi_dbg(ERR_ZONE, "%s: Failed in urb submission\n", __func__);
+               dev_kfree_skb(skb);
+@@ -783,12 +784,12 @@ static int rsi_probe(struct usb_interfac
+               rsi_dbg(INIT_ZONE, "%s: Device Init Done\n", __func__);
+       }
+-      status = rsi_rx_urb_submit(adapter, WLAN_EP);
++      status = rsi_rx_urb_submit(adapter, WLAN_EP, GFP_KERNEL);
+       if (status)
+               goto err1;
+       if (adapter->priv->coex_mode > 1) {
+-              status = rsi_rx_urb_submit(adapter, BT_EP);
++              status = rsi_rx_urb_submit(adapter, BT_EP, GFP_KERNEL);
+               if (status)
+                       goto err1;
+       }
diff --git a/queue-4.19/rsi-fix-use-after-free-on-probe-errors.patch b/queue-4.19/rsi-fix-use-after-free-on-probe-errors.patch
new file mode 100644 (file)
index 0000000..0f99c62
--- /dev/null
@@ -0,0 +1,73 @@
+From 92aafe77123ab478e5f5095878856ab0424910da Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 28 Nov 2019 18:22:01 +0100
+Subject: rsi: fix use-after-free on probe errors
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 92aafe77123ab478e5f5095878856ab0424910da upstream.
+
+The driver would fail to stop the command timer in most error paths,
+something which specifically could lead to the timer being freed while
+still active on I/O errors during probe.
+
+Fix this by making sure that each function starting the timer also stops
+it in all relevant error paths.
+
+Reported-by: syzbot+1d1597a5aa3679c65b9f@syzkaller.appspotmail.com
+Fixes: b78e91bcfb33 ("rsi: Add new firmware loading method")
+Cc: stable <stable@vger.kernel.org>     # 4.12
+Cc: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
+Cc: Amitkumar Karwar <amit.karwar@redpinesignals.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/rsi/rsi_91x_hal.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
++++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
+@@ -616,6 +616,7 @@ static int bl_cmd(struct rsi_hw *adapter
+       bl_start_cmd_timer(adapter, timeout);
+       status = bl_write_cmd(adapter, cmd, exp_resp, &regout_val);
+       if (status < 0) {
++              bl_stop_cmd_timer(adapter);
+               rsi_dbg(ERR_ZONE,
+                       "%s: Command %s (%0x) writing failed..\n",
+                       __func__, str, cmd);
+@@ -731,10 +732,9 @@ static int ping_pong_write(struct rsi_hw
+       }
+       status = bl_cmd(adapter, cmd_req, cmd_resp, str);
+-      if (status) {
+-              bl_stop_cmd_timer(adapter);
++      if (status)
+               return status;
+-      }
++
+       return 0;
+ }
+@@ -822,10 +822,9 @@ static int auto_fw_upgrade(struct rsi_hw
+       status = bl_cmd(adapter, EOF_REACHED, FW_LOADING_SUCCESSFUL,
+                       "EOF_REACHED");
+-      if (status) {
+-              bl_stop_cmd_timer(adapter);
++      if (status)
+               return status;
+-      }
++
+       rsi_dbg(INFO_ZONE, "FW loading is done and FW is running..\n");
+       return 0;
+ }
+@@ -846,6 +845,7 @@ static int rsi_load_firmware(struct rsi_
+               status = hif_ops->master_reg_read(adapter, SWBL_REGOUT,
+                                             &regout_val, 2);
+               if (status < 0) {
++                      bl_stop_cmd_timer(adapter);
+                       rsi_dbg(ERR_ZONE,
+                               "%s: REGOUT read failed\n", __func__);
+                       return status;
diff --git a/queue-4.19/sched-fair-add-tmp_alone_branch-assertion.patch b/queue-4.19/sched-fair-add-tmp_alone_branch-assertion.patch
new file mode 100644 (file)
index 0000000..1ca528a
--- /dev/null
@@ -0,0 +1,194 @@
+From 5d299eabea5a251fbf66e8277704b874bbba92dc Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Wed, 30 Jan 2019 14:41:04 +0100
+Subject: sched/fair: Add tmp_alone_branch assertion
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+commit 5d299eabea5a251fbf66e8277704b874bbba92dc upstream.
+
+The magic in list_add_leaf_cfs_rq() requires that at the end of
+enqueue_task_fair():
+
+  rq->tmp_alone_branch == &rq->lead_cfs_rq_list
+
+If this is violated, list integrity is compromised for list entries
+and the tmp_alone_branch pointer might dangle.
+
+Also, reflow list_add_leaf_cfs_rq() while there. This looses one
+indentation level and generates a form that's convenient for the next
+patch.
+
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Janne Huttunen <janne.huttunen@nokia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/sched/fair.c |  126 +++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 71 insertions(+), 55 deletions(-)
+
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -284,64 +284,69 @@ static inline struct cfs_rq *group_cfs_r
+ static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
+ {
+-      if (!cfs_rq->on_list) {
+-              struct rq *rq = rq_of(cfs_rq);
+-              int cpu = cpu_of(rq);
++      struct rq *rq = rq_of(cfs_rq);
++      int cpu = cpu_of(rq);
++
++      if (cfs_rq->on_list)
++              return;
++
++      cfs_rq->on_list = 1;
++
++      /*
++       * Ensure we either appear before our parent (if already
++       * enqueued) or force our parent to appear after us when it is
++       * enqueued. The fact that we always enqueue bottom-up
++       * reduces this to two cases and a special case for the root
++       * cfs_rq. Furthermore, it also means that we will always reset
++       * tmp_alone_branch either when the branch is connected
++       * to a tree or when we reach the top of the tree
++       */
++      if (cfs_rq->tg->parent &&
++          cfs_rq->tg->parent->cfs_rq[cpu]->on_list) {
+               /*
+-               * Ensure we either appear before our parent (if already
+-               * enqueued) or force our parent to appear after us when it is
+-               * enqueued. The fact that we always enqueue bottom-up
+-               * reduces this to two cases and a special case for the root
+-               * cfs_rq. Furthermore, it also means that we will always reset
+-               * tmp_alone_branch either when the branch is connected
+-               * to a tree or when we reach the beg of the tree
++               * If parent is already on the list, we add the child
++               * just before. Thanks to circular linked property of
++               * the list, this means to put the child at the tail
++               * of the list that starts by parent.
+                */
+-              if (cfs_rq->tg->parent &&
+-                  cfs_rq->tg->parent->cfs_rq[cpu]->on_list) {
+-                      /*
+-                       * If parent is already on the list, we add the child
+-                       * just before. Thanks to circular linked property of
+-                       * the list, this means to put the child at the tail
+-                       * of the list that starts by parent.
+-                       */
+-                      list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list,
+-                              &(cfs_rq->tg->parent->cfs_rq[cpu]->leaf_cfs_rq_list));
+-                      /*
+-                       * The branch is now connected to its tree so we can
+-                       * reset tmp_alone_branch to the beginning of the
+-                       * list.
+-                       */
+-                      rq->tmp_alone_branch = &rq->leaf_cfs_rq_list;
+-              } else if (!cfs_rq->tg->parent) {
+-                      /*
+-                       * cfs rq without parent should be put
+-                       * at the tail of the list.
+-                       */
+-                      list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list,
+-                              &rq->leaf_cfs_rq_list);
+-                      /*
+-                       * We have reach the beg of a tree so we can reset
+-                       * tmp_alone_branch to the beginning of the list.
+-                       */
+-                      rq->tmp_alone_branch = &rq->leaf_cfs_rq_list;
+-              } else {
+-                      /*
+-                       * The parent has not already been added so we want to
+-                       * make sure that it will be put after us.
+-                       * tmp_alone_branch points to the beg of the branch
+-                       * where we will add parent.
+-                       */
+-                      list_add_rcu(&cfs_rq->leaf_cfs_rq_list,
+-                              rq->tmp_alone_branch);
+-                      /*
+-                       * update tmp_alone_branch to points to the new beg
+-                       * of the branch
+-                       */
+-                      rq->tmp_alone_branch = &cfs_rq->leaf_cfs_rq_list;
+-              }
++              list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list,
++                      &(cfs_rq->tg->parent->cfs_rq[cpu]->leaf_cfs_rq_list));
++              /*
++               * The branch is now connected to its tree so we can
++               * reset tmp_alone_branch to the beginning of the
++               * list.
++               */
++              rq->tmp_alone_branch = &rq->leaf_cfs_rq_list;
++              return;
++      }
+-              cfs_rq->on_list = 1;
++      if (!cfs_rq->tg->parent) {
++              /*
++               * cfs rq without parent should be put
++               * at the tail of the list.
++               */
++              list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list,
++                      &rq->leaf_cfs_rq_list);
++              /*
++               * We have reach the top of a tree so we can reset
++               * tmp_alone_branch to the beginning of the list.
++               */
++              rq->tmp_alone_branch = &rq->leaf_cfs_rq_list;
++              return;
+       }
++
++      /*
++       * The parent has not already been added so we want to
++       * make sure that it will be put after us.
++       * tmp_alone_branch points to the begin of the branch
++       * where we will add parent.
++       */
++      list_add_rcu(&cfs_rq->leaf_cfs_rq_list, rq->tmp_alone_branch);
++      /*
++       * update tmp_alone_branch to points to the new begin
++       * of the branch
++       */
++      rq->tmp_alone_branch = &cfs_rq->leaf_cfs_rq_list;
+ }
+ static inline void list_del_leaf_cfs_rq(struct cfs_rq *cfs_rq)
+@@ -352,7 +357,12 @@ static inline void list_del_leaf_cfs_rq(
+       }
+ }
+-/* Iterate through all leaf cfs_rq's on a runqueue: */
++static inline void assert_list_leaf_cfs_rq(struct rq *rq)
++{
++      SCHED_WARN_ON(rq->tmp_alone_branch != &rq->leaf_cfs_rq_list);
++}
++
++/* Iterate through all cfs_rq's on a runqueue in bottom-up order */
+ #define for_each_leaf_cfs_rq(rq, cfs_rq) \
+       list_for_each_entry_rcu(cfs_rq, &rq->leaf_cfs_rq_list, leaf_cfs_rq_list)
+@@ -446,6 +456,10 @@ static inline void list_del_leaf_cfs_rq(
+ {
+ }
++static inline void assert_list_leaf_cfs_rq(struct rq *rq)
++{
++}
++
+ #define for_each_leaf_cfs_rq(rq, cfs_rq)      \
+               for (cfs_rq = &rq->cfs; cfs_rq; cfs_rq = NULL)
+@@ -5160,6 +5174,8 @@ enqueue_task_fair(struct rq *rq, struct
+       if (!se)
+               add_nr_running(rq, 1);
++      assert_list_leaf_cfs_rq(rq);
++
+       hrtick_update(rq);
+ }
diff --git a/queue-4.19/sched-fair-fix-insertion-in-rq-leaf_cfs_rq_list.patch b/queue-4.19/sched-fair-fix-insertion-in-rq-leaf_cfs_rq_list.patch
new file mode 100644 (file)
index 0000000..038581c
--- /dev/null
@@ -0,0 +1,143 @@
+From f6783319737f28e4436a69611853a5a098cbe974 Mon Sep 17 00:00:00 2001
+From: Vincent Guittot <vincent.guittot@linaro.org>
+Date: Wed, 30 Jan 2019 06:22:47 +0100
+Subject: sched/fair: Fix insertion in rq->leaf_cfs_rq_list
+
+From: Vincent Guittot <vincent.guittot@linaro.org>
+
+commit f6783319737f28e4436a69611853a5a098cbe974 upstream.
+
+Sargun reported a crash:
+
+  "I picked up c40f7d74c741a907cfaeb73a7697081881c497d0 sched/fair: Fix
+   infinite loop in update_blocked_averages() by reverting a9e7f6544b9c
+   and put it on top of 4.19.13. In addition to this, I uninlined
+   list_add_leaf_cfs_rq for debugging.
+
+   This revealed a new bug that we didn't get to because we kept getting
+   crashes from the previous issue. When we are running with cgroups that
+   are rapidly changing, with CFS bandwidth control, and in addition
+   using the cpusets cgroup, we see this crash. Specifically, it seems to
+   occur with cgroups that are throttled and we change the allowed
+   cpuset."
+
+The algorithm used to order cfs_rq in rq->leaf_cfs_rq_list assumes that
+it will walk down to root the 1st time a cfs_rq is used and we will finish
+to add either a cfs_rq without parent or a cfs_rq with a parent that is
+already on the list. But this is not always true in presence of throttling.
+Because a cfs_rq can be throttled even if it has never been used but other CPUs
+of the cgroup have already used all the bandwdith, we are not sure to go down to
+the root and add all cfs_rq in the list.
+
+Ensure that all cfs_rq will be added in the list even if they are throttled.
+
+[ mingo: Fix !CGROUPS build. ]
+
+Reported-by: Sargun Dhillon <sargun@sargun.me>
+Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: tj@kernel.org
+Fixes: 9c2791f936ef ("Fix hierarchical order in rq->leaf_cfs_rq_list")
+Link: https://lkml.kernel.org/r/1548825767-10799-1-git-send-email-vincent.guittot@linaro.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Janne Huttunen <janne.huttunen@nokia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/sched/fair.c |   33 ++++++++++++++++++++++++++++-----
+ 1 file changed, 28 insertions(+), 5 deletions(-)
+
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -282,13 +282,13 @@ static inline struct cfs_rq *group_cfs_r
+       return grp->my_q;
+ }
+-static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
++static inline bool list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
+ {
+       struct rq *rq = rq_of(cfs_rq);
+       int cpu = cpu_of(rq);
+       if (cfs_rq->on_list)
+-              return;
++              return rq->tmp_alone_branch == &rq->leaf_cfs_rq_list;
+       cfs_rq->on_list = 1;
+@@ -317,7 +317,7 @@ static inline void list_add_leaf_cfs_rq(
+                * list.
+                */
+               rq->tmp_alone_branch = &rq->leaf_cfs_rq_list;
+-              return;
++              return true;
+       }
+       if (!cfs_rq->tg->parent) {
+@@ -332,7 +332,7 @@ static inline void list_add_leaf_cfs_rq(
+                * tmp_alone_branch to the beginning of the list.
+                */
+               rq->tmp_alone_branch = &rq->leaf_cfs_rq_list;
+-              return;
++              return true;
+       }
+       /*
+@@ -347,6 +347,7 @@ static inline void list_add_leaf_cfs_rq(
+        * of the branch
+        */
+       rq->tmp_alone_branch = &cfs_rq->leaf_cfs_rq_list;
++      return false;
+ }
+ static inline void list_del_leaf_cfs_rq(struct cfs_rq *cfs_rq)
+@@ -448,8 +449,9 @@ static inline struct cfs_rq *group_cfs_r
+       return NULL;
+ }
+-static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
++static inline bool list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
+ {
++      return true;
+ }
+ static inline void list_del_leaf_cfs_rq(struct cfs_rq *cfs_rq)
+@@ -5019,6 +5021,12 @@ static void __maybe_unused unthrottle_of
+ }
+ #else /* CONFIG_CFS_BANDWIDTH */
++
++static inline bool cfs_bandwidth_used(void)
++{
++      return false;
++}
++
+ static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq)
+ {
+       return rq_clock_task(rq_of(cfs_rq));
+@@ -5174,6 +5182,21 @@ enqueue_task_fair(struct rq *rq, struct
+       if (!se)
+               add_nr_running(rq, 1);
++      if (cfs_bandwidth_used()) {
++              /*
++               * When bandwidth control is enabled; the cfs_rq_throttled()
++               * breaks in the above iteration can result in incomplete
++               * leaf list maintenance, resulting in triggering the assertion
++               * below.
++               */
++              for_each_sched_entity(se) {
++                      cfs_rq = cfs_rq_of(se);
++
++                      if (list_add_leaf_cfs_rq(cfs_rq))
++                              break;
++              }
++      }
++
+       assert_list_leaf_cfs_rq(rq);
+       hrtick_update(rq);
index cb9c0821c506511824407915d59ba1fcc96734f1..15e564591f90ac6e5999c75e2c028930b3a102b0 100644 (file)
@@ -43,3 +43,10 @@ pci-add-dma-alias-quirk-for-intel-vca-ntb.patch
 iommu-amd-support-multiple-pci-dma-aliases-in-irq-re.patch
 arm-omap2-smartreflex-add-omap_sr_pdata-definition.patch
 usb-storage-disable-uas-on-jmicron-sata-enclosure.patch
+sched-fair-add-tmp_alone_branch-assertion.patch
+sched-fair-fix-insertion-in-rq-leaf_cfs_rq_list.patch
+rsi-fix-use-after-free-on-probe-errors.patch
+rsi-fix-memory-leak-on-failed-urb-submission.patch
+rsi-fix-non-atomic-allocation-in-completion-handler.patch
+crypto-af_alg-use-bh_lock_sock-in-sk_destruct.patch
+random-try-to-actively-add-entropy-rather-than-passively-wait-for-it.patch