--- /dev/null
+From 8c15a18331191b67bdce54d21af068baec044baf Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 5 Jun 2023 16:47:58 +0200
+Subject: ALSA: seq: Avoid confusion of aligned read size
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 8c15a18331191b67bdce54d21af068baec044baf upstream.
+
+Currently the read event packet size in snd_seq_read() is defined by
+client->midi_version value that is guaranteed to be zero if UMP isn't
+enabled. But the static analyzer doesn't know of the fact, and it
+still suspects as if it were leading to a potential overflow.
+
+Add the more explicit check of CONFIG_SND_SEQ_UMP to determine the
+aligned_size value for avoiding the confusion.
+
+Fixes: 46397622a3fa ("ALSA: seq: Add UMP support")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <error27@gmail.com>
+Closes: https://lore.kernel.org/r/202305261415.NY0vapZK-lkp@intel.com/
+Link: https://lore.kernel.org/r/20230605144758.6677-2-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/core/seq/seq_clientmgr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/core/seq/seq_clientmgr.c
++++ b/sound/core/seq/seq_clientmgr.c
+@@ -441,7 +441,7 @@ static ssize_t snd_seq_read(struct file
+ err = 0;
+ snd_seq_fifo_lock(fifo);
+
+- if (client->midi_version > 0)
++ if (IS_ENABLED(CONFIG_SND_SEQ_UMP) && client->midi_version > 0)
+ aligned_size = sizeof(struct snd_seq_ump_event);
+ else
+ aligned_size = sizeof(struct snd_seq_event);
--- /dev/null
+From 761fb8ec8778f0caf2bba5a41e3cff1ea86974f3 Mon Sep 17 00:00:00 2001
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Date: Tue, 17 Mar 2026 11:54:01 -0400
+Subject: Bluetooth: L2CAP: Fix regressions caused by reusing ident
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+commit 761fb8ec8778f0caf2bba5a41e3cff1ea86974f3 upstream.
+
+This attempt to fix regressions caused by reusing ident which apparently
+is not handled well on certain stacks causing the stack to not respond to
+requests, so instead of simple returning the first unallocated id this
+stores the last used tx_ident and then attempt to use the next until all
+available ids are exausted and then cycle starting over to 1.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=221120
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=221177
+Fixes: 6c3ea155e5ee ("Bluetooth: L2CAP: Fix not tracking outstanding TX ident")
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Tested-by: Christian Eggers <ceggers@arri.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/bluetooth/l2cap.h | 1 +
+ net/bluetooth/l2cap_core.c | 29 ++++++++++++++++++++++++++---
+ 2 files changed, 27 insertions(+), 3 deletions(-)
+
+--- a/include/net/bluetooth/l2cap.h
++++ b/include/net/bluetooth/l2cap.h
+@@ -654,6 +654,7 @@ struct l2cap_conn {
+ struct sk_buff *rx_skb;
+ __u32 rx_len;
+ struct ida tx_ida;
++ __u8 tx_ident;
+
+ struct sk_buff_head pending_rx;
+ struct work_struct pending_rx_work;
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -960,16 +960,39 @@ int l2cap_chan_check_security(struct l2c
+
+ static int l2cap_get_ident(struct l2cap_conn *conn)
+ {
++ u8 max;
++ int ident;
++
+ /* LE link does not support tools like l2ping so use the full range */
+ if (conn->hcon->type == LE_LINK)
+- return ida_alloc_range(&conn->tx_ida, 1, 255, GFP_ATOMIC);
+-
++ max = 255;
+ /* Get next available identificator.
+ * 1 - 128 are used by kernel.
+ * 129 - 199 are reserved.
+ * 200 - 254 are used by utilities like l2ping, etc.
+ */
+- return ida_alloc_range(&conn->tx_ida, 1, 128, GFP_ATOMIC);
++ else
++ max = 128;
++
++ /* Allocate ident using min as last used + 1 (cyclic) */
++ ident = ida_alloc_range(&conn->tx_ida, READ_ONCE(conn->tx_ident) + 1,
++ max, GFP_ATOMIC);
++ /* Force min 1 to start over */
++ if (ident <= 0) {
++ ident = ida_alloc_range(&conn->tx_ida, 1, max, GFP_ATOMIC);
++ if (ident <= 0) {
++ /* If all idents are in use, log an error, this is
++ * extremely unlikely to happen and would indicate a bug
++ * in the code that idents are not being freed properly.
++ */
++ BT_ERR("Unable to allocate ident: %d", ident);
++ return 0;
++ }
++ }
++
++ WRITE_ONCE(conn->tx_ident, ident);
++
++ return ident;
+ }
+
+ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
--- /dev/null
+From 6e1930ece855a4c256f1c7e6632d634cfb9888b5 Mon Sep 17 00:00:00 2001
+From: Stig Hornang <stig@hornang.me>
+Date: Fri, 12 Jun 2026 16:38:18 +0200
+Subject: Bluetooth: L2CAP: fix tx ident leak for commands without a response
+
+From: Stig Hornang <stig@hornang.me>
+
+commit 6e1930ece855a4c256f1c7e6632d634cfb9888b5 upstream.
+
+Commit 6c3ea155e5ee ("Bluetooth: L2CAP: Fix not tracking outstanding
+TX ident") changed ident allocation to use an IDA, releasing idents in
+l2cap_put_ident() when the matching response command is received.
+
+But identifiers allocated for commands that have no response defined
+are never released. In particular L2CAP_LE_CREDITS is sent repeatedly for
+the lifetime of an LE CoC channel, so a peer streaming data to the
+host exhausts the 1-255 ident range after 254 credit packets. From
+then on l2cap_get_ident() fails:
+
+ kernel: Bluetooth: Unable to allocate ident: -28
+
+and every subsequent L2CAP_LE_CREDITS packet is sent with ident 0,
+which is invalid (Core Spec, Vol 3, Part A, Section 4: "Signaling
+identifier 0x00 is an invalid identifier and shall never be used in
+any command"). Remote stacks that validate the ident drop these
+commands, never receive new credits, and the channel stalls
+permanently. With default socket buffers this happens after roughly 0.5 MB
+of received data (the exact amount depends on the socket receive buffer):
+
+ < ACL Data TX: Handle 2048 flags 0x00 dlen 12
+ LE L2CAP: LE Flow Control Credit (0x16) ident 0 len 4
+ Source CID: 64
+ Credits: 1
+
+Release the ident immediately after sending L2CAP_LE_CREDITS since no
+response will ever release it. Use a local variable instead of
+chan->ident so that an ident that an EXT_FLOWCTL channel may be waiting on
+(e.g. a pending reconfigure) is not overwritten by a credit packet.
+
+Also add the missing L2CAP_LE_CONN_RSP case to l2cap_put_ident() so
+idents allocated for outgoing L2CAP_LE_CONN_REQ commands are released
+when the response arrives.
+
+Fixes: 6c3ea155e5ee ("Bluetooth: L2CAP: Fix not tracking outstanding TX ident")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=221629
+Assisted-by: Claude:claude-opus-4.8
+Assisted-by: Fable:5
+Signed-off-by: Stig Hornang <stig@hornang.me>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/l2cap_core.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -4895,6 +4895,7 @@ static void l2cap_put_ident(struct l2cap
+ case L2CAP_ECHO_RSP:
+ case L2CAP_INFO_RSP:
+ case L2CAP_CONN_PARAM_UPDATE_RSP:
++ case L2CAP_LE_CONN_RSP:
+ case L2CAP_ECRED_CONN_RSP:
+ case L2CAP_ECRED_RECONF_RSP:
+ /* The remote may send bogus ids that would make ida_free
+@@ -6805,6 +6806,7 @@ static void l2cap_chan_le_send_credits(s
+ struct l2cap_conn *conn = chan->conn;
+ struct l2cap_le_credits pkt;
+ u16 return_credits = l2cap_le_rx_credits(chan);
++ int ident;
+
+ if (chan->mode != L2CAP_MODE_LE_FLOWCTL &&
+ chan->mode != L2CAP_MODE_EXT_FLOWCTL)
+@@ -6822,9 +6824,18 @@ static void l2cap_chan_le_send_credits(s
+ pkt.cid = cpu_to_le16(chan->scid);
+ pkt.credits = cpu_to_le16(return_credits);
+
+- chan->ident = l2cap_get_ident(conn);
++ ident = l2cap_get_ident(conn);
++
++ l2cap_send_cmd(conn, ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
+
+- l2cap_send_cmd(conn, chan->ident, L2CAP_LE_CREDITS, sizeof(pkt), &pkt);
++ /* L2CAP_LE_CREDITS has no response so the ident is never released by
++ * l2cap_put_ident() - release it right away, otherwise the tx_ida
++ * range is exhausted after 254 packets and from then on credits are
++ * sent with the invalid ident 0, which some remote stacks ignore,
++ * stalling the channel.
++ */
++ if (ident > 0)
++ ida_free(&conn->tx_ida, ident);
+ }
+
+ void l2cap_chan_rx_avail(struct l2cap_chan *chan, ssize_t rx_avail)
--- /dev/null
+From f9e6da99fe49277979798a1c3b9790ae10aaa18a Mon Sep 17 00:00:00 2001
+From: Danilo Krummrich <dakr@kernel.org>
+Date: Mon, 25 May 2026 03:23:21 +0200
+Subject: driver core: Fix missing jiffies conversion in deferred_probe_extend_timeout()
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+commit f9e6da99fe49277979798a1c3b9790ae10aaa18a upstream.
+
+mod_delayed_work() takes jiffies, not seconds. Thus, restore the dropped
+conversion.
+
+While at it, fix incorrect indentation.
+
+Fixes: 1137838865bf ("driver core: Use mod_delayed_work to prevent lost deferred probe work")
+Tested-by: Biju Das <biju.das.jz@bp.renesas.com>
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://patch.msgid.link/20260525012340.3860581-1-dakr@kernel.org
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/dd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -327,7 +327,7 @@ void deferred_probe_extend_timeout(void)
+ * start a new one.
+ */
+ if (mod_delayed_work(system_wq, &deferred_probe_timeout_work,
+- driver_deferred_probe_timeout))
++ secs_to_jiffies(driver_deferred_probe_timeout)))
+ pr_debug("Extended deferred probe timeout by %d secs\n",
+ driver_deferred_probe_timeout);
+ }
--- /dev/null
+From 557495bc879013c3d5e21d667e987e7ce3a514de Mon Sep 17 00:00:00 2001
+From: Danilo Krummrich <dakr@kernel.org>
+Date: Mon, 25 May 2026 03:23:22 +0200
+Subject: driver core: Guard deferred probe timeout extension with delayed_work_pending()
+
+From: Danilo Krummrich <dakr@kernel.org>
+
+commit 557495bc879013c3d5e21d667e987e7ce3a514de upstream.
+
+mod_delayed_work() unconditionally queues the work even when it wasn't
+previously pending, which can fire the timeout prematurely or restart it
+after it already fired. Add a delayed_work_pending() guard to restore
+the originally intended semantics.
+
+Premature firing calls fw_devlink_drivers_done() before all built-in
+drivers have registered, causing fw_devlink to prematurely relax device
+links for suppliers whose drivers haven't loaded yet.
+
+Fixes: 1137838865bf ("driver core: Use mod_delayed_work to prevent lost deferred probe work")
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://patch.msgid.link/20260525012340.3860581-2-dakr@kernel.org
+Signed-off-by: Danilo Krummrich <dakr@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/dd.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -326,7 +326,8 @@ void deferred_probe_extend_timeout(void)
+ * If the work hasn't been queued yet or if the work expired, don't
+ * start a new one.
+ */
+- if (mod_delayed_work(system_wq, &deferred_probe_timeout_work,
++ if (delayed_work_pending(&deferred_probe_timeout_work) &&
++ mod_delayed_work(system_wq, &deferred_probe_timeout_work,
+ secs_to_jiffies(driver_deferred_probe_timeout)))
+ pr_debug("Extended deferred probe timeout by %d secs\n",
+ driver_deferred_probe_timeout);
--- /dev/null
+From bb2784d9ab49587ba4fbff37a319fff2924db289 Mon Sep 17 00:00:00 2001
+From: Easwar Hariharan <eahariha@linux.microsoft.com>
+Date: Thu, 30 Jan 2025 19:26:58 +0000
+Subject: jiffies: Cast to unsigned long in secs_to_jiffies() conversion
+
+From: Easwar Hariharan <eahariha@linux.microsoft.com>
+
+commit bb2784d9ab49587ba4fbff37a319fff2924db289 upstream.
+
+While converting users of msecs_to_jiffies(), lkp reported that some range
+checks would always be true because of the mismatch between the implied int
+value of secs_to_jiffies() vs the unsigned long return value of the
+msecs_to_jiffies() calls it was replacing.
+
+Fix this by casting the secs_to_jiffies() input value to unsigned long.
+
+Fixes: b35108a51cf7ba ("jiffies: Define secs_to_jiffies()")
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Easwar Hariharan <eahariha@linux.microsoft.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/all/20250130192701.99626-1-eahariha@linux.microsoft.com
+Closes: https://lore.kernel.org/oe-kbuild-all/202501301334.NB6NszQR-lkp@intel.com/
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/jiffies.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/linux/jiffies.h
++++ b/include/linux/jiffies.h
+@@ -382,7 +382,7 @@ static __always_inline unsigned long mse
+ *
+ * Return: jiffies value
+ */
+-#define secs_to_jiffies(_secs) ((_secs) * HZ)
++#define secs_to_jiffies(_secs) (unsigned long)((_secs) * HZ)
+
+ extern unsigned long __usecs_to_jiffies(const unsigned int u);
+ #if !(USEC_PER_SEC % HZ)
--- /dev/null
+From b35108a51cf7bab58d7eace1267d7965978bcdb8 Mon Sep 17 00:00:00 2001
+From: Easwar Hariharan <eahariha@linux.microsoft.com>
+Date: Wed, 30 Oct 2024 17:47:35 +0000
+Subject: jiffies: Define secs_to_jiffies()
+
+From: Easwar Hariharan <eahariha@linux.microsoft.com>
+
+commit b35108a51cf7bab58d7eace1267d7965978bcdb8 upstream.
+
+secs_to_jiffies() is defined in hci_event.c and cannot be reused by
+other call sites. Hoist it into the core code to allow conversion of the
+~1150 usages of msecs_to_jiffies() that either:
+
+ - use a multiplier value of 1000 or equivalently MSEC_PER_SEC, or
+ - have timeouts that are denominated in seconds (i.e. end in 000)
+
+It's implemented as a macro to allow usage in static initializers.
+
+This will also allow conversion of yet more sites that use (sec * HZ)
+directly, and improve their readability.
+
+Suggested-by: Michael Kelley <mhklinux@outlook.com>
+Signed-off-by: Easwar Hariharan <eahariha@linux.microsoft.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Link: https://lore.kernel.org/all/20241030-open-coded-timeouts-v3-1-9ba123facf88@linux.microsoft.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/jiffies.h | 13 +++++++++++++
+ net/bluetooth/hci_event.c | 2 --
+ 2 files changed, 13 insertions(+), 2 deletions(-)
+
+--- a/include/linux/jiffies.h
++++ b/include/linux/jiffies.h
+@@ -371,6 +371,19 @@ static __always_inline unsigned long mse
+ }
+ }
+
++/**
++ * secs_to_jiffies: - convert seconds to jiffies
++ * @_secs: time in seconds
++ *
++ * Conversion is done by simple multiplication with HZ
++ *
++ * secs_to_jiffies() is defined as a macro rather than a static inline
++ * function so it can be used in static initializers.
++ *
++ * Return: jiffies value
++ */
++#define secs_to_jiffies(_secs) ((_secs) * HZ)
++
+ extern unsigned long __usecs_to_jiffies(const unsigned int u);
+ #if !(USEC_PER_SEC % HZ)
+ static inline unsigned long _usecs_to_jiffies(const unsigned int u)
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -42,8 +42,6 @@
+ #define ZERO_KEY "\x00\x00\x00\x00\x00\x00\x00\x00" \
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+
+-#define secs_to_jiffies(_secs) msecs_to_jiffies((_secs) * 1000)
+-
+ /* Handle HCI Event packets */
+
+ static void *hci_ev_skb_pull(struct hci_dev *hdev, struct sk_buff *skb,
--- /dev/null
+From f88a31308db6a856229150039b0f56d59696ed31 Mon Sep 17 00:00:00 2001
+From: Randy Dunlap <rdunlap@infradead.org>
+Date: Fri, 23 Jan 2026 10:37:49 -0800
+Subject: seqlock: fix scoped_seqlock_read kernel-doc
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+commit f88a31308db6a856229150039b0f56d59696ed31 upstream.
+
+Eliminate all kernel-doc warnings in seqlock.h:
+
+- correct the macro to have "()" immediately following the macro name
+- don't include the macro parameters in the short description (first line)
+- make the parameter names in the comments match the actual macro
+ parameter names.
+- use "::" for the Example
+
+WARNING: include/linux/seqlock.h:1341 This comment starts with '/**', but isn't a kernel-doc comment.
+ * scoped_seqlock_read (lock, ss_state) - execute the read side critical
+Documentation/locking/seqlock:242: include/linux/seqlock.h:1351: WARNING:
+ Definition list ends without a blank line; unexpected unindent. [docutils]
+Warning: include/linux/seqlock.h:1357 function parameter '_seqlock' not described in 'scoped_seqlock_read'
+Warning: include/linux/seqlock.h:1357 function parameter '_target' not described in 'scoped_seqlock_read'
+
+Fixes: cc39f3872c08 ("seqlock: Introduce scoped_seqlock_read()")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://patch.msgid.link/20260123183749.3997533-1-rdunlap@infradead.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/seqlock.h | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+--- a/include/linux/seqlock.h
++++ b/include/linux/seqlock.h
+@@ -1357,15 +1357,14 @@ __scoped_seqlock_next(struct ss_tmp *sst
+ __scoped_seqlock_next(&_s, _seqlock, _target))
+
+ /**
+- * scoped_seqlock_read (lock, ss_state) - execute the read side critical
+- * section without manual sequence
+- * counter handling or calls to other
+- * helpers
+- * @lock: pointer to seqlock_t protecting the data
+- * @ss_state: one of {ss_lock, ss_lock_irqsave, ss_lockless} indicating
+- * the type of critical read section
++ * scoped_seqlock_read() - execute the read-side critical section
++ * without manual sequence counter handling
++ * or calls to other helpers
++ * @_seqlock: pointer to seqlock_t protecting the data
++ * @_target: an enum ss_state: one of {ss_lock, ss_lock_irqsave, ss_lockless}
++ * indicating the type of critical read section
+ *
+- * Example:
++ * Example::
+ *
+ * scoped_seqlock_read (&lock, ss_lock) {
+ * // read-side critical section
mm-damon-core-make-charge_addr_from-aware-of-end-address-exclusivity.patch
mm-damon-sysfs-schemes-fix-dir-put-orders-in-access_pattern_add_dirs.patch
kvm-move-kvm_io_bus_get_dev-locking-responsibilities-to-callers.patch
+seqlock-fix-scoped_seqlock_read-kernel-doc.patch
+bluetooth-l2cap-fix-regressions-caused-by-reusing-ident.patch
+bluetooth-l2cap-fix-tx-ident-leak-for-commands-without-a-response.patch
+writeback-fix-use-after-free-in-inode_switch_wbs_work_fn.patch
+writeback-drop-now-unnecessary-rcu_barrier-in-cgroup_writeback_umount.patch
+jiffies-define-secs_to_jiffies.patch
+jiffies-cast-to-unsigned-long-in-secs_to_jiffies-conversion.patch
+driver-core-fix-missing-jiffies-conversion-in-deferred_probe_extend_timeout.patch
+driver-core-guard-deferred-probe-timeout-extension-with-delayed_work_pending.patch
+alsa-seq-avoid-confusion-of-aligned-read-size.patch
--- /dev/null
+From e90a6d668e26e00a72df2d09c173b563468f09c9 Mon Sep 17 00:00:00 2001
+From: Baokun Li <libaokun@linux.alibaba.com>
+Date: Thu, 21 May 2026 17:50:15 +0800
+Subject: writeback: drop now-unnecessary rcu_barrier() in cgroup_writeback_umount()
+
+From: Baokun Li <libaokun@linux.alibaba.com>
+
+commit e90a6d668e26e00a72df2d09c173b563468f09c9 upstream.
+
+Commit e1b849cfa6b6 ("writeback: Avoid contention on wb->list_lock when
+switching inodes") replaced the queue_rcu_work() based scheduling of
+inode wb switches with a plain queue_work(). Since then no switcher
+goes through call_rcu(), so rcu_barrier() in cgroup_writeback_umount()
+has no callbacks of its own to wait for. It still drains unrelated
+call_rcu() callbacks from other subsystems on busy systems, which
+incidentally slows umount down; drop it.
+
+Fixes: e1b849cfa6b6 ("writeback: Avoid contention on wb->list_lock when switching inodes")
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
+Link: https://patch.msgid.link/20260521095016.2791354-3-libaokun@linux.alibaba.com
+Acked-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fs-writeback.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -1187,11 +1187,6 @@ void cgroup_writeback_umount(void)
+ * will then drain it.
+ */
+ synchronize_rcu();
+- /*
+- * Use rcu_barrier() to wait for all pending callbacks to
+- * ensure that all in-flight wb switches are in the workqueue.
+- */
+- rcu_barrier();
+ flush_workqueue(isw_wq);
+ }
+ }
--- /dev/null
+From 6689f01d6740cf358932b3e97ee968c6099800d9 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 13 Apr 2026 11:36:19 +0200
+Subject: writeback: Fix use after free in inode_switch_wbs_work_fn()
+
+From: Jan Kara <jack@suse.cz>
+
+commit 6689f01d6740cf358932b3e97ee968c6099800d9 upstream.
+
+inode_switch_wbs_work_fn() has a loop like:
+
+ wb_get(new_wb);
+ while (1) {
+ list = llist_del_all(&new_wb->switch_wbs_ctxs);
+ /* Nothing to do? */
+ if (!list)
+ break;
+ ... process the items ...
+ }
+
+Now adding of items to the list looks like:
+
+wb_queue_isw()
+ if (llist_add(&isw->list, &wb->switch_wbs_ctxs))
+ queue_work(isw_wq, &wb->switch_work);
+
+Because inode_switch_wbs_work_fn() loops when processing isw items, it
+can happen that wb->switch_work is pending while wb->switch_wbs_ctxs is
+empty. This is a problem because in that case wb can get freed (no isw
+items -> no wb reference) while the work is still pending causing
+use-after-free issues.
+
+We cannot just fix this by cancelling work when freeing wb because that
+could still trigger problematic 0 -> 1 transitions on wb refcount due to
+wb_get() in inode_switch_wbs_work_fn(). It could be all handled with
+more careful code but that seems unnecessarily complex so let's avoid
+that until it is proven that the looping actually brings practical
+benefit. Just remove the loop from inode_switch_wbs_work_fn() instead.
+That way when wb_queue_isw() queues work, we are guaranteed we have
+added the first item to wb->switch_wbs_ctxs and nobody is going to
+remove it (and drop the wb reference it holds) until the queued work
+runs.
+
+Fixes: e1b849cfa6b6 ("writeback: Avoid contention on wb->list_lock when switching inodes")
+CC: stable@vger.kernel.org
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20260413093618.17244-2-jack@suse.cz
+Acked-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fs-writeback.c | 36 +++++++++++++++++++-----------------
+ 1 file changed, 19 insertions(+), 17 deletions(-)
+
+--- a/fs/fs-writeback.c
++++ b/fs/fs-writeback.c
+@@ -533,28 +533,30 @@ void inode_switch_wbs_work_fn(struct wor
+ struct inode_switch_wbs_context *isw, *next_isw;
+ struct llist_node *list;
+
++ list = llist_del_all(&new_wb->switch_wbs_ctxs);
+ /*
+- * Grab out reference to wb so that it cannot get freed under us
++ * Nothing to do? That would be a problem as references held by isw
++ * items protect wb from freeing...
++ */
++ if (WARN_ON_ONCE(!list))
++ return;
++
++ /*
++ * Grab our reference to wb so that it cannot get freed under us
+ * after we process all the isw items.
+ */
+ wb_get(new_wb);
+- while (1) {
+- list = llist_del_all(&new_wb->switch_wbs_ctxs);
+- /* Nothing to do? */
+- if (!list)
+- break;
+- /*
+- * In addition to synchronizing among switchers, I_WB_SWITCH
+- * tells the RCU protected stat update paths to grab the i_page
+- * lock so that stat transfer can synchronize against them.
+- * Let's continue after I_WB_SWITCH is guaranteed to be
+- * visible.
+- */
+- synchronize_rcu();
++ /*
++ * In addition to synchronizing among switchers, I_WB_SWITCH
++ * tells the RCU protected stat update paths to grab the i_page
++ * lock so that stat transfer can synchronize against them.
++ * Let's continue after I_WB_SWITCH is guaranteed to be
++ * visible.
++ */
++ synchronize_rcu();
+
+- llist_for_each_entry_safe(isw, next_isw, list, list)
+- process_inode_switch_wbs(new_wb, isw);
+- }
++ llist_for_each_entry_safe(isw, next_isw, list, list)
++ process_inode_switch_wbs(new_wb, isw);
+ wb_put(new_wb);
+ }
+