]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 12 Jun 2024 15:28:57 +0000 (17:28 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 12 Jun 2024 15:28:57 +0000 (17:28 +0200)
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

queue-5.10/acpi-resource-do-irq-override-on-tongfang-gxxhrxx-and-gmxhgxx.patch [new file with mode: 0644]
queue-5.10/arm64-dts-qcom-qcs404-fix-bluetooth-device-address.patch [new file with mode: 0644]
queue-5.10/arm64-tegra-correct-tegra132-i2c-alias.patch [new file with mode: 0644]
queue-5.10/ata-pata_legacy-make-legacy_exit-work-again.patch [new file with mode: 0644]
queue-5.10/bcache-fix-variable-length-array-abuse-in-btree_iter.patch [new file with mode: 0644]
queue-5.10/md-raid5-fix-deadlock-that-raid5d-wait-for-itself-to-clear-md_sb_change_pending.patch [new file with mode: 0644]
queue-5.10/series

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 (file)
index 0000000..8d18ab8
--- /dev/null
@@ -0,0 +1,41 @@
+From c81bf14f9db68311c2e75428eea070d97d603975 Mon Sep 17 00:00:00 2001
+From: Christoffer Sandberg <cs@tuxedo.de>
+Date: Mon, 22 Apr 2024 10:04:36 +0200
+Subject: ACPI: resource: Do IRQ override on TongFang GXxHRXx and GMxHGxx
+
+From: Christoffer Sandberg <cs@tuxedo.de>
+
+commit c81bf14f9db68311c2e75428eea070d97d603975 upstream.
+
+Listed devices need the override for the keyboard to work.
+
+Signed-off-by: Christoffer Sandberg <cs@tuxedo.de>
+Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
+Cc: All applicable <stable@vger.kernel.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..70a6233
--- /dev/null
@@ -0,0 +1,37 @@
+From f5f390a77f18eaeb2c93211a1b7c5e66b5acd423 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan+linaro@kernel.org>
+Date: Wed, 1 May 2024 09:52:01 +0200
+Subject: arm64: dts: qcom: qcs404: fix bluetooth device address
+
+From: Johan Hovold <johan+linaro@kernel.org>
+
+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 <johan+linaro@kernel.org>
+Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+Link: https://lore.kernel.org/r/20240501075201.4732-1-johan+linaro@kernel.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..fb92985
--- /dev/null
@@ -0,0 +1,50 @@
+From 2633c58e1354d7de2c8e7be8bdb6f68a0a01bad7 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzk@kernel.org>
+Date: Mon, 1 Apr 2024 16:08:54 +0200
+Subject: arm64: tegra: Correct Tegra132 I2C alias
+
+From: Krzysztof Kozlowski <krzk@kernel.org>
+
+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 <krzk@kernel.org>
+Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
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 (file)
index 0000000..8ed2d88
--- /dev/null
@@ -0,0 +1,52 @@
+From d4a89339f17c87c4990070e9116462d16e75894f Mon Sep 17 00:00:00 2001
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+Date: Sat, 4 May 2024 23:27:25 +0300
+Subject: ata: pata_legacy: make legacy_exit() work again
+
+From: Sergey Shtylyov <s.shtylyov@omp.ru>
+
+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 <s.shtylyov@omp.ru>
+Reviewed-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..5a94b05
--- /dev/null
@@ -0,0 +1,409 @@
+From 3a861560ccb35f2a4f0a4b8207fa7c2a35fc7f31 Mon Sep 17 00:00:00 2001
+From: Matthew Mirvish <matthew@mm12.xyz>
+Date: Thu, 9 May 2024 09:11:17 +0800
+Subject: bcache: fix variable length array abuse in btree_iter
+
+From: Matthew Mirvish <matthew@mm12.xyz>
+
+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 <matthew@mm12.xyz>
+Signed-off-by: Coly Li <colyli@suse.de>
+Link: https://lore.kernel.org/r/20240509011117.2697-3-colyli@suse.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..2510279
--- /dev/null
@@ -0,0 +1,86 @@
+From 151f66bb618d1fd0eeb84acb61b4a9fa5d8bb0fa Mon Sep 17 00:00:00 2001
+From: Yu Kuai <yukuai3@huawei.com>
+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 <yukuai3@huawei.com>
+
+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 <dan@danm.net>
+Closes: https://lore.kernel.org/all/20240123005700.9302-1-dan@danm.net/
+Investigated-by: Junxiao Bi <junxiao.bi@oracle.com>
+Signed-off-by: Yu Kuai <yukuai3@huawei.com>
+Link: https://lore.kernel.org/r/20240322081005.1112401-1-yukuai1@huaweicloud.com
+Signed-off-by: Song Liu <song@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 <linux/blkdev.h>
+-#include <linux/delay.h>
+ #include <linux/kthread.h>
+ #include <linux/raid/pq.h>
+ #include <linux/async_tx.h>
+@@ -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);
index 41f956c9ee7f7c3ea905eba7eafcedf89585d755..d7ecaf54f62165f3d576b9e13f37721cb2e8d1df 100644 (file)
@@ -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