From: Greg Kroah-Hartman Date: Wed, 12 Jun 2024 15:28:57 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v4.19.316~96 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4d1c7faa818717ac68a2a826474f98337329e6ab;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: acpi-resource-do-irq-override-on-tongfang-gxxhrxx-and-gmxhgxx.patch arm64-dts-qcom-qcs404-fix-bluetooth-device-address.patch arm64-tegra-correct-tegra132-i2c-alias.patch ata-pata_legacy-make-legacy_exit-work-again.patch bcache-fix-variable-length-array-abuse-in-btree_iter.patch md-raid5-fix-deadlock-that-raid5d-wait-for-itself-to-clear-md_sb_change_pending.patch --- diff --git a/queue-5.10/acpi-resource-do-irq-override-on-tongfang-gxxhrxx-and-gmxhgxx.patch b/queue-5.10/acpi-resource-do-irq-override-on-tongfang-gxxhrxx-and-gmxhgxx.patch new file mode 100644 index 00000000000..8d18ab8dd48 --- /dev/null +++ b/queue-5.10/acpi-resource-do-irq-override-on-tongfang-gxxhrxx-and-gmxhgxx.patch @@ -0,0 +1,41 @@ +From c81bf14f9db68311c2e75428eea070d97d603975 Mon Sep 17 00:00:00 2001 +From: Christoffer Sandberg +Date: Mon, 22 Apr 2024 10:04:36 +0200 +Subject: ACPI: resource: Do IRQ override on TongFang GXxHRXx and GMxHGxx + +From: Christoffer Sandberg + +commit c81bf14f9db68311c2e75428eea070d97d603975 upstream. + +Listed devices need the override for the keyboard to work. + +Signed-off-by: Christoffer Sandberg +Signed-off-by: Werner Sembach +Cc: All applicable +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/acpi/resource.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/acpi/resource.c ++++ b/drivers/acpi/resource.c +@@ -475,6 +475,18 @@ static const struct dmi_system_id asus_l + DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"), + }, + }, ++ { ++ /* TongFang GXxHRXx/TUXEDO InfinityBook Pro Gen9 AMD */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "GXxHRXx"), ++ }, ++ }, ++ { ++ /* TongFang GMxHGxx/TUXEDO Stellaris Slim Gen1 AMD */ ++ .matches = { ++ DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"), ++ }, ++ }, + { } + }; + diff --git a/queue-5.10/arm64-dts-qcom-qcs404-fix-bluetooth-device-address.patch b/queue-5.10/arm64-dts-qcom-qcs404-fix-bluetooth-device-address.patch new file mode 100644 index 00000000000..70a6233922c --- /dev/null +++ b/queue-5.10/arm64-dts-qcom-qcs404-fix-bluetooth-device-address.patch @@ -0,0 +1,37 @@ +From f5f390a77f18eaeb2c93211a1b7c5e66b5acd423 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 1 May 2024 09:52:01 +0200 +Subject: arm64: dts: qcom: qcs404: fix bluetooth device address + +From: Johan Hovold + +commit f5f390a77f18eaeb2c93211a1b7c5e66b5acd423 upstream. + +The 'local-bd-address' property is used to pass a unique Bluetooth +device address from the boot firmware to the kernel and should otherwise +be left unset so that the OS can prevent the controller from being used +until a valid address has been provided through some other means (e.g. +using btmgmt). + +Fixes: 60f77ae7d1c1 ("arm64: dts: qcom: qcs404-evb: Enable uart3 and add Bluetooth") +Cc: stable@vger.kernel.org # 5.10 +Signed-off-by: Johan Hovold +Reviewed-by: Bryan O'Donoghue +Link: https://lore.kernel.org/r/20240501075201.4732-1-johan+linaro@kernel.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/qcom/qcs404-evb.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi ++++ b/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi +@@ -60,7 +60,7 @@ + vddrf-supply = <&vreg_l1_1p3>; + vddch0-supply = <&vdd_ch0_3p3>; + +- local-bd-address = [ 02 00 00 00 5a ad ]; ++ local-bd-address = [ 00 00 00 00 00 00 ]; + + max-speed = <3200000>; + }; diff --git a/queue-5.10/arm64-tegra-correct-tegra132-i2c-alias.patch b/queue-5.10/arm64-tegra-correct-tegra132-i2c-alias.patch new file mode 100644 index 00000000000..fb92985009f --- /dev/null +++ b/queue-5.10/arm64-tegra-correct-tegra132-i2c-alias.patch @@ -0,0 +1,50 @@ +From 2633c58e1354d7de2c8e7be8bdb6f68a0a01bad7 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Mon, 1 Apr 2024 16:08:54 +0200 +Subject: arm64: tegra: Correct Tegra132 I2C alias + +From: Krzysztof Kozlowski + +commit 2633c58e1354d7de2c8e7be8bdb6f68a0a01bad7 upstream. + +There is no such device as "as3722@40", because its name is "pmic". Use +phandles for aliases to fix relying on full node path. This corrects +aliases for RTC devices and also fixes dtc W=1 warning: + + tegra132-norrin.dts:12.3-36: Warning (alias_paths): /aliases:rtc0: aliases property is not a valid node (/i2c@7000d000/as3722@40) + +Fixes: 0f279ebdf3ce ("arm64: tegra: Add NVIDIA Tegra132 Norrin support") +Cc: stable@vger.kernel.org +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Jon Hunter +Signed-off-by: Thierry Reding +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/nvidia/tegra132-norrin.dts | 4 ++-- + arch/arm64/boot/dts/nvidia/tegra132.dtsi | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts ++++ b/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts +@@ -9,8 +9,8 @@ + compatible = "nvidia,norrin", "nvidia,tegra132", "nvidia,tegra124"; + + aliases { +- rtc0 = "/i2c@7000d000/as3722@40"; +- rtc1 = "/rtc@7000e000"; ++ rtc0 = &as3722; ++ rtc1 = &tegra_rtc; + serial0 = &uarta; + }; + +--- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi +@@ -573,7 +573,7 @@ + status = "disabled"; + }; + +- rtc@7000e000 { ++ tegra_rtc: rtc@7000e000 { + compatible = "nvidia,tegra124-rtc", "nvidia,tegra20-rtc"; + reg = <0x0 0x7000e000 0x0 0x100>; + interrupts = ; diff --git a/queue-5.10/ata-pata_legacy-make-legacy_exit-work-again.patch b/queue-5.10/ata-pata_legacy-make-legacy_exit-work-again.patch new file mode 100644 index 00000000000..8ed2d88640c --- /dev/null +++ b/queue-5.10/ata-pata_legacy-make-legacy_exit-work-again.patch @@ -0,0 +1,52 @@ +From d4a89339f17c87c4990070e9116462d16e75894f Mon Sep 17 00:00:00 2001 +From: Sergey Shtylyov +Date: Sat, 4 May 2024 23:27:25 +0300 +Subject: ata: pata_legacy: make legacy_exit() work again + +From: Sergey Shtylyov + +commit d4a89339f17c87c4990070e9116462d16e75894f upstream. + +Commit defc9cd826e4 ("pata_legacy: resychronize with upstream changes and +resubmit") missed to update legacy_exit(), so that it now fails to do any +cleanup -- the loop body there can never be entered. Fix that and finally +remove now useless nr_legacy_host variable... + +Found by Linux Verification Center (linuxtesting.org) with the Svace static +analysis tool. + +Fixes: defc9cd826e4 ("pata_legacy: resychronize with upstream changes and resubmit") +Cc: stable@vger.kernel.org +Signed-off-by: Sergey Shtylyov +Reviewed-by: Niklas Cassel +Signed-off-by: Damien Le Moal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/pata_legacy.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/ata/pata_legacy.c ++++ b/drivers/ata/pata_legacy.c +@@ -114,8 +114,6 @@ static int legacy_port[NR_HOST] = { 0x1f + static struct legacy_probe probe_list[NR_HOST]; + static struct legacy_data legacy_data[NR_HOST]; + static struct ata_host *legacy_host[NR_HOST]; +-static int nr_legacy_host; +- + + static int probe_all; /* Set to check all ISA port ranges */ + static int ht6560a; /* HT 6560A on primary 1, second 2, both 3 */ +@@ -1239,9 +1237,11 @@ static __exit void legacy_exit(void) + { + int i; + +- for (i = 0; i < nr_legacy_host; i++) { ++ for (i = 0; i < NR_HOST; i++) { + struct legacy_data *ld = &legacy_data[i]; +- ata_host_detach(legacy_host[i]); ++ ++ if (legacy_host[i]) ++ ata_host_detach(legacy_host[i]); + platform_device_unregister(ld->platform_dev); + } + } diff --git a/queue-5.10/bcache-fix-variable-length-array-abuse-in-btree_iter.patch b/queue-5.10/bcache-fix-variable-length-array-abuse-in-btree_iter.patch new file mode 100644 index 00000000000..5a94b05f459 --- /dev/null +++ b/queue-5.10/bcache-fix-variable-length-array-abuse-in-btree_iter.patch @@ -0,0 +1,409 @@ +From 3a861560ccb35f2a4f0a4b8207fa7c2a35fc7f31 Mon Sep 17 00:00:00 2001 +From: Matthew Mirvish +Date: Thu, 9 May 2024 09:11:17 +0800 +Subject: bcache: fix variable length array abuse in btree_iter + +From: Matthew Mirvish + +commit 3a861560ccb35f2a4f0a4b8207fa7c2a35fc7f31 upstream. + +btree_iter is used in two ways: either allocated on the stack with a +fixed size MAX_BSETS, or from a mempool with a dynamic size based on the +specific cache set. Previously, the struct had a fixed-length array of +size MAX_BSETS which was indexed out-of-bounds for the dynamically-sized +iterators, which causes UBSAN to complain. + +This patch uses the same approach as in bcachefs's sort_iter and splits +the iterator into a btree_iter with a flexible array member and a +btree_iter_stack which embeds a btree_iter as well as a fixed-length +data array. + +Cc: stable@vger.kernel.org +Closes: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2039368 +Signed-off-by: Matthew Mirvish +Signed-off-by: Coly Li +Link: https://lore.kernel.org/r/20240509011117.2697-3-colyli@suse.de +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/bcache/bset.c | 44 +++++++++++++++++++++--------------------- + drivers/md/bcache/bset.h | 30 ++++++++++++++++++---------- + drivers/md/bcache/btree.c | 40 ++++++++++++++++++++------------------ + drivers/md/bcache/super.c | 5 ++-- + drivers/md/bcache/sysfs.c | 2 - + drivers/md/bcache/writeback.c | 10 ++++----- + 6 files changed, 71 insertions(+), 60 deletions(-) + +--- a/drivers/md/bcache/bset.c ++++ b/drivers/md/bcache/bset.c +@@ -54,7 +54,7 @@ void bch_dump_bucket(struct btree_keys * + int __bch_count_data(struct btree_keys *b) + { + unsigned int ret = 0; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct bkey *k; + + if (b->ops->is_extents) +@@ -67,7 +67,7 @@ void __bch_check_keys(struct btree_keys + { + va_list args; + struct bkey *k, *p = NULL; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + const char *err; + + for_each_key(b, k, &iter) { +@@ -877,7 +877,7 @@ unsigned int bch_btree_insert_key(struct + unsigned int status = BTREE_INSERT_STATUS_NO_INSERT; + struct bset *i = bset_tree_last(b)->data; + struct bkey *m, *prev = NULL; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct bkey preceding_key_on_stack = ZERO_KEY; + struct bkey *preceding_key_p = &preceding_key_on_stack; + +@@ -893,9 +893,9 @@ unsigned int bch_btree_insert_key(struct + else + preceding_key(k, &preceding_key_p); + +- m = bch_btree_iter_init(b, &iter, preceding_key_p); ++ m = bch_btree_iter_stack_init(b, &iter, preceding_key_p); + +- if (b->ops->insert_fixup(b, k, &iter, replace_key)) ++ if (b->ops->insert_fixup(b, k, &iter.iter, replace_key)) + return status; + + status = BTREE_INSERT_STATUS_INSERT; +@@ -1096,33 +1096,33 @@ void bch_btree_iter_push(struct btree_it + btree_iter_cmp)); + } + +-static struct bkey *__bch_btree_iter_init(struct btree_keys *b, +- struct btree_iter *iter, +- struct bkey *search, +- struct bset_tree *start) ++static struct bkey *__bch_btree_iter_stack_init(struct btree_keys *b, ++ struct btree_iter_stack *iter, ++ struct bkey *search, ++ struct bset_tree *start) + { + struct bkey *ret = NULL; + +- iter->size = ARRAY_SIZE(iter->data); +- iter->used = 0; ++ iter->iter.size = ARRAY_SIZE(iter->stack_data); ++ iter->iter.used = 0; + + #ifdef CONFIG_BCACHE_DEBUG +- iter->b = b; ++ iter->iter.b = b; + #endif + + for (; start <= bset_tree_last(b); start++) { + ret = bch_bset_search(b, start, search); +- bch_btree_iter_push(iter, ret, bset_bkey_last(start->data)); ++ bch_btree_iter_push(&iter->iter, ret, bset_bkey_last(start->data)); + } + + return ret; + } + +-struct bkey *bch_btree_iter_init(struct btree_keys *b, +- struct btree_iter *iter, ++struct bkey *bch_btree_iter_stack_init(struct btree_keys *b, ++ struct btree_iter_stack *iter, + struct bkey *search) + { +- return __bch_btree_iter_init(b, iter, search, b->set); ++ return __bch_btree_iter_stack_init(b, iter, search, b->set); + } + + static inline struct bkey *__bch_btree_iter_next(struct btree_iter *iter, +@@ -1289,10 +1289,10 @@ void bch_btree_sort_partial(struct btree + struct bset_sort_state *state) + { + size_t order = b->page_order, keys = 0; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + int oldsize = bch_count_data(b); + +- __bch_btree_iter_init(b, &iter, NULL, &b->set[start]); ++ __bch_btree_iter_stack_init(b, &iter, NULL, &b->set[start]); + + if (start) { + unsigned int i; +@@ -1303,7 +1303,7 @@ void bch_btree_sort_partial(struct btree + order = get_order(__set_bytes(b->set->data, keys)); + } + +- __btree_sort(b, &iter, start, order, false, state); ++ __btree_sort(b, &iter.iter, start, order, false, state); + + EBUG_ON(oldsize >= 0 && bch_count_data(b) != oldsize); + } +@@ -1319,11 +1319,11 @@ void bch_btree_sort_into(struct btree_ke + struct bset_sort_state *state) + { + uint64_t start_time = local_clock(); +- struct btree_iter iter; ++ struct btree_iter_stack iter; + +- bch_btree_iter_init(b, &iter, NULL); ++ bch_btree_iter_stack_init(b, &iter, NULL); + +- btree_mergesort(b, new->set->data, &iter, false, true); ++ btree_mergesort(b, new->set->data, &iter.iter, false, true); + + bch_time_stats_update(&state->time, start_time); + +--- a/drivers/md/bcache/bset.h ++++ b/drivers/md/bcache/bset.h +@@ -321,7 +321,14 @@ struct btree_iter { + #endif + struct btree_iter_set { + struct bkey *k, *end; +- } data[MAX_BSETS]; ++ } data[]; ++}; ++ ++/* Fixed-size btree_iter that can be allocated on the stack */ ++ ++struct btree_iter_stack { ++ struct btree_iter iter; ++ struct btree_iter_set stack_data[MAX_BSETS]; + }; + + typedef bool (*ptr_filter_fn)(struct btree_keys *b, const struct bkey *k); +@@ -333,9 +340,9 @@ struct bkey *bch_btree_iter_next_filter( + + void bch_btree_iter_push(struct btree_iter *iter, struct bkey *k, + struct bkey *end); +-struct bkey *bch_btree_iter_init(struct btree_keys *b, +- struct btree_iter *iter, +- struct bkey *search); ++struct bkey *bch_btree_iter_stack_init(struct btree_keys *b, ++ struct btree_iter_stack *iter, ++ struct bkey *search); + + struct bkey *__bch_bset_search(struct btree_keys *b, struct bset_tree *t, + const struct bkey *search); +@@ -350,13 +357,14 @@ static inline struct bkey *bch_bset_sear + return search ? __bch_bset_search(b, t, search) : t->data->start; + } + +-#define for_each_key_filter(b, k, iter, filter) \ +- for (bch_btree_iter_init((b), (iter), NULL); \ +- ((k) = bch_btree_iter_next_filter((iter), (b), filter));) +- +-#define for_each_key(b, k, iter) \ +- for (bch_btree_iter_init((b), (iter), NULL); \ +- ((k) = bch_btree_iter_next(iter));) ++#define for_each_key_filter(b, k, stack_iter, filter) \ ++ for (bch_btree_iter_stack_init((b), (stack_iter), NULL); \ ++ ((k) = bch_btree_iter_next_filter(&((stack_iter)->iter), (b), \ ++ filter));) ++ ++#define for_each_key(b, k, stack_iter) \ ++ for (bch_btree_iter_stack_init((b), (stack_iter), NULL); \ ++ ((k) = bch_btree_iter_next(&((stack_iter)->iter)));) + + /* Sorting */ + +--- a/drivers/md/bcache/btree.c ++++ b/drivers/md/bcache/btree.c +@@ -1283,7 +1283,7 @@ static bool btree_gc_mark_node(struct bt + uint8_t stale = 0; + unsigned int keys = 0, good_keys = 0; + struct bkey *k; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct bset_tree *t; + + gc->nodes++; +@@ -1544,7 +1544,7 @@ static int btree_gc_rewrite_node(struct + static unsigned int btree_gc_count_keys(struct btree *b) + { + struct bkey *k; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + unsigned int ret = 0; + + for_each_key_filter(&b->keys, k, &iter, bch_ptr_bad) +@@ -1585,17 +1585,18 @@ static int btree_gc_recurse(struct btree + int ret = 0; + bool should_rewrite; + struct bkey *k; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct gc_merge_info r[GC_MERGE_NODES]; + struct gc_merge_info *i, *last = r + ARRAY_SIZE(r) - 1; + +- bch_btree_iter_init(&b->keys, &iter, &b->c->gc_done); ++ bch_btree_iter_stack_init(&b->keys, &iter, &b->c->gc_done); + + for (i = r; i < r + ARRAY_SIZE(r); i++) + i->b = ERR_PTR(-EINTR); + + while (1) { +- k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad); ++ k = bch_btree_iter_next_filter(&iter.iter, &b->keys, ++ bch_ptr_bad); + if (k) { + r->b = bch_btree_node_get(b->c, op, k, b->level - 1, + true, b); +@@ -1885,7 +1886,7 @@ static int bch_btree_check_recurse(struc + { + int ret = 0; + struct bkey *k, *p = NULL; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + + for_each_key_filter(&b->keys, k, &iter, bch_ptr_invalid) + bch_initial_mark_key(b->c, b->level, k); +@@ -1893,10 +1894,10 @@ static int bch_btree_check_recurse(struc + bch_initial_mark_key(b->c, b->level + 1, &b->key); + + if (b->level) { +- bch_btree_iter_init(&b->keys, &iter, NULL); ++ bch_btree_iter_stack_init(&b->keys, &iter, NULL); + + do { +- k = bch_btree_iter_next_filter(&iter, &b->keys, ++ k = bch_btree_iter_next_filter(&iter.iter, &b->keys, + bch_ptr_bad); + if (k) { + btree_node_prefetch(b, k); +@@ -1924,7 +1925,7 @@ static int bch_btree_check_thread(void * + struct btree_check_info *info = arg; + struct btree_check_state *check_state = info->state; + struct cache_set *c = check_state->c; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct bkey *k, *p; + int cur_idx, prev_idx, skip_nr; + +@@ -1933,8 +1934,8 @@ static int bch_btree_check_thread(void * + ret = 0; + + /* root node keys are checked before thread created */ +- bch_btree_iter_init(&c->root->keys, &iter, NULL); +- k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad); ++ bch_btree_iter_stack_init(&c->root->keys, &iter, NULL); ++ k = bch_btree_iter_next_filter(&iter.iter, &c->root->keys, bch_ptr_bad); + BUG_ON(!k); + + p = k; +@@ -1952,7 +1953,7 @@ static int bch_btree_check_thread(void * + skip_nr = cur_idx - prev_idx; + + while (skip_nr) { +- k = bch_btree_iter_next_filter(&iter, ++ k = bch_btree_iter_next_filter(&iter.iter, + &c->root->keys, + bch_ptr_bad); + if (k) +@@ -2025,7 +2026,7 @@ int bch_btree_check(struct cache_set *c) + int ret = 0; + int i; + struct bkey *k = NULL; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct btree_check_state check_state; + + /* check and mark root node keys */ +@@ -2521,11 +2522,11 @@ static int bch_btree_map_nodes_recurse(s + + if (b->level) { + struct bkey *k; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + +- bch_btree_iter_init(&b->keys, &iter, from); ++ bch_btree_iter_stack_init(&b->keys, &iter, from); + +- while ((k = bch_btree_iter_next_filter(&iter, &b->keys, ++ while ((k = bch_btree_iter_next_filter(&iter.iter, &b->keys, + bch_ptr_bad))) { + ret = bcache_btree(map_nodes_recurse, k, b, + op, from, fn, flags); +@@ -2554,11 +2555,12 @@ int bch_btree_map_keys_recurse(struct bt + { + int ret = MAP_CONTINUE; + struct bkey *k; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + +- bch_btree_iter_init(&b->keys, &iter, from); ++ bch_btree_iter_stack_init(&b->keys, &iter, from); + +- while ((k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad))) { ++ while ((k = bch_btree_iter_next_filter(&iter.iter, &b->keys, ++ bch_ptr_bad))) { + ret = !b->level + ? fn(op, b, k) + : bcache_btree(map_keys_recurse, k, +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -1939,8 +1939,9 @@ struct cache_set *bch_cache_set_alloc(st + INIT_LIST_HEAD(&c->btree_cache_freed); + INIT_LIST_HEAD(&c->data_buckets); + +- iter_size = ((meta_bucket_pages(sb) * PAGE_SECTORS) / sb->block_size + 1) * +- sizeof(struct btree_iter_set); ++ iter_size = sizeof(struct btree_iter) + ++ ((meta_bucket_pages(sb) * PAGE_SECTORS) / sb->block_size) * ++ sizeof(struct btree_iter_set); + + c->devices = kcalloc(c->nr_uuids, sizeof(void *), GFP_KERNEL); + if (!c->devices) +--- a/drivers/md/bcache/sysfs.c ++++ b/drivers/md/bcache/sysfs.c +@@ -639,7 +639,7 @@ static unsigned int bch_root_usage(struc + unsigned int bytes = 0; + struct bkey *k; + struct btree *b; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + + goto lock_root; + +--- a/drivers/md/bcache/writeback.c ++++ b/drivers/md/bcache/writeback.c +@@ -852,15 +852,15 @@ static int bch_dirty_init_thread(void *a + struct dirty_init_thrd_info *info = arg; + struct bch_dirty_init_state *state = info->state; + struct cache_set *c = state->c; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct bkey *k, *p; + int cur_idx, prev_idx, skip_nr; + + k = p = NULL; + prev_idx = 0; + +- bch_btree_iter_init(&c->root->keys, &iter, NULL); +- k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad); ++ bch_btree_iter_stack_init(&c->root->keys, &iter, NULL); ++ k = bch_btree_iter_next_filter(&iter.iter, &c->root->keys, bch_ptr_bad); + BUG_ON(!k); + + p = k; +@@ -874,7 +874,7 @@ static int bch_dirty_init_thread(void *a + skip_nr = cur_idx - prev_idx; + + while (skip_nr) { +- k = bch_btree_iter_next_filter(&iter, ++ k = bch_btree_iter_next_filter(&iter.iter, + &c->root->keys, + bch_ptr_bad); + if (k) +@@ -923,7 +923,7 @@ void bch_sectors_dirty_init(struct bcach + int i; + struct btree *b = NULL; + struct bkey *k = NULL; +- struct btree_iter iter; ++ struct btree_iter_stack iter; + struct sectors_dirty_init op; + struct cache_set *c = d->c; + struct bch_dirty_init_state state; diff --git a/queue-5.10/md-raid5-fix-deadlock-that-raid5d-wait-for-itself-to-clear-md_sb_change_pending.patch b/queue-5.10/md-raid5-fix-deadlock-that-raid5d-wait-for-itself-to-clear-md_sb_change_pending.patch new file mode 100644 index 00000000000..2510279e030 --- /dev/null +++ b/queue-5.10/md-raid5-fix-deadlock-that-raid5d-wait-for-itself-to-clear-md_sb_change_pending.patch @@ -0,0 +1,86 @@ +From 151f66bb618d1fd0eeb84acb61b4a9fa5d8bb0fa Mon Sep 17 00:00:00 2001 +From: Yu Kuai +Date: Fri, 22 Mar 2024 16:10:05 +0800 +Subject: md/raid5: fix deadlock that raid5d() wait for itself to clear MD_SB_CHANGE_PENDING + +From: Yu Kuai + +commit 151f66bb618d1fd0eeb84acb61b4a9fa5d8bb0fa upstream. + +Xiao reported that lvm2 test lvconvert-raid-takeover.sh can hang with +small possibility, the root cause is exactly the same as commit +bed9e27baf52 ("Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d"") + +However, Dan reported another hang after that, and junxiao investigated +the problem and found out that this is caused by plugged bio can't issue +from raid5d(). + +Current implementation in raid5d() has a weird dependence: + +1) md_check_recovery() from raid5d() must hold 'reconfig_mutex' to clear + MD_SB_CHANGE_PENDING; +2) raid5d() handles IO in a deadloop, until all IO are issued; +3) IO from raid5d() must wait for MD_SB_CHANGE_PENDING to be cleared; + +This behaviour is introduce before v2.6, and for consequence, if other +context hold 'reconfig_mutex', and md_check_recovery() can't update +super_block, then raid5d() will waste one cpu 100% by the deadloop, until +'reconfig_mutex' is released. + +Refer to the implementation from raid1 and raid10, fix this problem by +skipping issue IO if MD_SB_CHANGE_PENDING is still set after +md_check_recovery(), daemon thread will be woken up when 'reconfig_mutex' +is released. Meanwhile, the hang problem will be fixed as well. + +Fixes: 5e2cf333b7bd ("md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d") +Cc: stable@vger.kernel.org # v5.19+ +Reported-and-tested-by: Dan Moulding +Closes: https://lore.kernel.org/all/20240123005700.9302-1-dan@danm.net/ +Investigated-by: Junxiao Bi +Signed-off-by: Yu Kuai +Link: https://lore.kernel.org/r/20240322081005.1112401-1-yukuai1@huaweicloud.com +Signed-off-by: Song Liu +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/raid5.c | 15 +++------------ + 1 file changed, 3 insertions(+), 12 deletions(-) + +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -36,7 +36,6 @@ + */ + + #include +-#include + #include + #include + #include +@@ -6484,6 +6483,9 @@ static void raid5d(struct md_thread *thr + int batch_size, released; + unsigned int offset; + ++ if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) ++ break; ++ + released = release_stripe_list(conf, conf->temp_inactive_list); + if (released) + clear_bit(R5_DID_ALLOC, &conf->cache_state); +@@ -6520,18 +6522,7 @@ static void raid5d(struct md_thread *thr + spin_unlock_irq(&conf->device_lock); + md_check_recovery(mddev); + spin_lock_irq(&conf->device_lock); +- +- /* +- * Waiting on MD_SB_CHANGE_PENDING below may deadlock +- * seeing md_check_recovery() is needed to clear +- * the flag when using mdmon. +- */ +- continue; + } +- +- wait_event_lock_irq(mddev->sb_wait, +- !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags), +- conf->device_lock); + } + pr_debug("%d stripes handled\n", handled); + diff --git a/queue-5.10/series b/queue-5.10/series index 41f956c9ee7..d7ecaf54f62 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -275,3 +275,9 @@ netfilter-nf_tables-fix-potential-data-race-in-__nft_obj_type_get.patch f2fs-fix-to-do-sanity-check-on-i_xattr_nid-in-sanity_check_inode.patch media-lgdt3306a-add-a-check-against-null-pointer-def.patch drm-amdgpu-add-error-handle-to-avoid-out-of-bounds.patch +bcache-fix-variable-length-array-abuse-in-btree_iter.patch +ata-pata_legacy-make-legacy_exit-work-again.patch +acpi-resource-do-irq-override-on-tongfang-gxxhrxx-and-gmxhgxx.patch +arm64-tegra-correct-tegra132-i2c-alias.patch +arm64-dts-qcom-qcs404-fix-bluetooth-device-address.patch +md-raid5-fix-deadlock-that-raid5d-wait-for-itself-to-clear-md_sb_change_pending.patch