From: Greg Kroah-Hartman Date: Thu, 30 Jan 2020 14:44:51 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v5.5.1~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d8fc50ec5439939b068095aeb87aedc9571307c6;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches 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 --- 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 index 00000000000..1d8c8450099 --- /dev/null +++ b/queue-4.19/crypto-af_alg-use-bh_lock_sock-in-sk_destruct.patch @@ -0,0 +1,43 @@ +From 37f96694cf73ba116993a9d2d99ad6a75fa7fdb0 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Thu, 5 Dec 2019 13:45:05 +0800 +Subject: crypto: af_alg - Use bh_lock_sock in sk_destruct + +From: Herbert Xu + +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 +Fixes: c840ac6af3f8 ("crypto: af_alg - Disallow bind/setkey/...") +Cc: +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b98baa4567a --- /dev/null +++ b/queue-4.19/random-try-to-actively-add-entropy-rather-than-passively-wait-for-it.patch @@ -0,0 +1,146 @@ +From 50ee7529ec4500c88f8664560770a7a1b65db72b Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +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 + +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 +Cc: Thomas Gleixner +Cc: Theodore Ts'o +Cc: Nicholas Mc Guire +Cc: Andy Lutomirski +Cc: Kees Cook +Cc: Willy Tarreau +Cc: Alexander E. Patrakov +Cc: Lennart Poettering +Cc: Noah Meyerhans +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..af7392c030c --- /dev/null +++ b/queue-4.19/rsi-fix-memory-leak-on-failed-urb-submission.patch @@ -0,0 +1,37 @@ +From 47768297481184932844ab01a86752ba31a38861 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 28 Nov 2019 18:22:02 +0100 +Subject: rsi: fix memory leak on failed URB submission + +From: Johan Hovold + +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 # 4.17 +Cc: Prameela Rani Garnepudi +Signed-off-by: Johan Hovold +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..357a1a90f7c --- /dev/null +++ b/queue-4.19/rsi-fix-non-atomic-allocation-in-completion-handler.patch @@ -0,0 +1,84 @@ +From b9b9f9fea21830f85cf0148cd8dce001ae55ead1 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 28 Nov 2019 18:22:03 +0100 +Subject: rsi: fix non-atomic allocation in completion handler + +From: Johan Hovold + +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 # 4.17 +Cc: Prameela Rani Garnepudi +Signed-off-by: Johan Hovold +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + 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 ++#include + #include + #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 index 00000000000..0f99c62c3f2 --- /dev/null +++ b/queue-4.19/rsi-fix-use-after-free-on-probe-errors.patch @@ -0,0 +1,73 @@ +From 92aafe77123ab478e5f5095878856ab0424910da Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 28 Nov 2019 18:22:01 +0100 +Subject: rsi: fix use-after-free on probe errors + +From: Johan Hovold + +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 # 4.12 +Cc: Prameela Rani Garnepudi +Cc: Amitkumar Karwar +Signed-off-by: Johan Hovold +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + 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, ®out_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, + ®out_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 index 00000000000..1ca528a6931 --- /dev/null +++ b/queue-4.19/sched-fair-add-tmp_alone_branch-assertion.patch @@ -0,0 +1,194 @@ +From 5d299eabea5a251fbf66e8277704b874bbba92dc Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Wed, 30 Jan 2019 14:41:04 +0100 +Subject: sched/fair: Add tmp_alone_branch assertion + +From: Peter Zijlstra + +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) +Cc: Linus Torvalds +Cc: Mike Galbraith +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Signed-off-by: Ingo Molnar +Cc: Janne Huttunen +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..038581c5d18 --- /dev/null +++ b/queue-4.19/sched-fair-fix-insertion-in-rq-leaf_cfs_rq_list.patch @@ -0,0 +1,143 @@ +From f6783319737f28e4436a69611853a5a098cbe974 Mon Sep 17 00:00:00 2001 +From: Vincent Guittot +Date: Wed, 30 Jan 2019 06:22:47 +0100 +Subject: sched/fair: Fix insertion in rq->leaf_cfs_rq_list + +From: Vincent Guittot + +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 +Signed-off-by: Vincent Guittot +Signed-off-by: Peter Zijlstra (Intel) +Cc: Linus Torvalds +Cc: Mike Galbraith +Cc: Peter Zijlstra +Cc: Thomas Gleixner +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 +Cc: Janne Huttunen +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-4.19/series b/queue-4.19/series index cb9c0821c50..15e564591f9 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -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