--- /dev/null
+From 27e1fd343f80168ff456785c2443136b6b7ca3cc Mon Sep 17 00:00:00 2001
+From: Shyam Prasad N <sprasad@microsoft.com>
+Date: Fri, 29 Dec 2023 11:30:07 +0000
+Subject: cifs: after disabling multichannel, mark tcon for reconnect
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+commit 27e1fd343f80168ff456785c2443136b6b7ca3cc upstream.
+
+Once the server disables multichannel for an active multichannel
+session, on the following reconnect, the client would reduce
+the number of channels to 1. However, it could be the case that
+the tree connect was active on one of these disabled channels.
+This results in an unrecoverable state.
+
+This change fixes that by making sure that whenever a channel
+is being terminated, the session and tcon are marked for
+reconnect too. This could mean a few redundant tree connect
+calls to the server, but considering that this is not a frequent
+event, we should be okay.
+
+Fixes: ee1d21794e55 ("cifs: handle when server stops supporting multichannel")
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/connect.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+--- a/fs/smb/client/connect.c
++++ b/fs/smb/client/connect.c
+@@ -212,17 +212,21 @@ cifs_mark_tcp_ses_conns_for_reconnect(st
+ /* If server is a channel, select the primary channel */
+ pserver = SERVER_IS_CHAN(server) ? server->primary_server : server;
+
++ /*
++ * if the server has been marked for termination, there is a
++ * chance that the remaining channels all need reconnect. To be
++ * on the safer side, mark the session and trees for reconnect
++ * for this scenario. This might cause a few redundant session
++ * setup and tree connect requests, but it is better than not doing
++ * a tree connect when needed, and all following requests failing
++ */
++ if (server->terminate) {
++ mark_smb_session = true;
++ server = pserver;
++ }
+
+ spin_lock(&cifs_tcp_ses_lock);
+ list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) {
+- /*
+- * if channel has been marked for termination, nothing to do
+- * for the channel. in fact, we cannot find the channel for the
+- * server. So safe to exit here
+- */
+- if (server->terminate)
+- break;
+-
+ /* check if iface is still active */
+ spin_lock(&ses->chan_lock);
+ if (!cifs_chan_is_iface_active(ses, server)) {
--- /dev/null
+From f30bbc38704e279c06d073ecb18fea376791ecab Mon Sep 17 00:00:00 2001
+From: Shyam Prasad N <sprasad@microsoft.com>
+Date: Fri, 15 Dec 2023 17:16:55 +0000
+Subject: cifs: fix a pending undercount of srv_count
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+commit f30bbc38704e279c06d073ecb18fea376791ecab upstream.
+
+The following commit reverted the changes to ref count
+the server struct while scheduling a reconnect work:
+823342524868 Revert "cifs: reconnect work should have reference on server struct"
+
+However, a following change also introduced scheduling
+of reconnect work, and assumed ref counting. This change
+fixes that as well.
+
+Fixes umount problems like:
+
+[73496.157838] CPU: 5 PID: 1321389 Comm: umount Tainted: G W OE 6.7.0-060700rc6-generic #202312172332
+[73496.157841] Hardware name: LENOVO 20MAS08500/20MAS08500, BIOS N2CET67W (1.50 ) 12/15/2022
+[73496.157843] RIP: 0010:cifs_put_tcp_session+0x17d/0x190 [cifs]
+[73496.157906] Code: 5d 31 c0 31 d2 31 f6 31 ff c3 cc cc cc cc e8 4a 6e 14 e6 e9 f6 fe ff ff be 03 00 00 00 48 89 d7 e8 78 26 b3 e5 e9 e4 fe ff ff <0f> 0b e9 b1 fe ff ff 66 66 2e 0f 1f 84 00 00 00 00 00 90 90 90 90
+[73496.157908] RSP: 0018:ffffc90003bcbcb8 EFLAGS: 00010286
+[73496.157911] RAX: 00000000ffffffff RBX: ffff8885830fa800 RCX: 0000000000000000
+[73496.157913] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
+[73496.157915] RBP: ffffc90003bcbcc8 R08: 0000000000000000 R09: 0000000000000000
+[73496.157917] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
+[73496.157918] R13: ffff8887d56ba800 R14: 00000000ffffffff R15: ffff8885830fa800
+[73496.157920] FS: 00007f1ff0e33800(0000) GS:ffff88887ba80000(0000) knlGS:0000000000000000
+[73496.157922] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[73496.157924] CR2: 0000115f002e2010 CR3: 00000003d1e24005 CR4: 00000000003706f0
+[73496.157926] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[73496.157928] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[73496.157929] Call Trace:
+[73496.157931] <TASK>
+[73496.157933] ? show_regs+0x6d/0x80
+[73496.157936] ? __warn+0x89/0x160
+[73496.157939] ? cifs_put_tcp_session+0x17d/0x190 [cifs]
+[73496.157976] ? report_bug+0x17e/0x1b0
+[73496.157980] ? handle_bug+0x51/0xa0
+[73496.157983] ? exc_invalid_op+0x18/0x80
+[73496.157985] ? asm_exc_invalid_op+0x1b/0x20
+[73496.157989] ? cifs_put_tcp_session+0x17d/0x190 [cifs]
+[73496.158023] ? cifs_put_tcp_session+0x1e/0x190 [cifs]
+[73496.158057] __cifs_put_smb_ses+0x2b5/0x540 [cifs]
+[73496.158090] ? tconInfoFree+0xc2/0x120 [cifs]
+[73496.158130] cifs_put_tcon.part.0+0x108/0x2b0 [cifs]
+[73496.158173] cifs_put_tlink+0x49/0x90 [cifs]
+[73496.158220] cifs_umount+0x56/0xb0 [cifs]
+[73496.158258] cifs_kill_sb+0x52/0x60 [cifs]
+[73496.158306] deactivate_locked_super+0x32/0xc0
+[73496.158309] deactivate_super+0x46/0x60
+[73496.158311] cleanup_mnt+0xc3/0x170
+[73496.158314] __cleanup_mnt+0x12/0x20
+[73496.158330] task_work_run+0x5e/0xa0
+[73496.158333] exit_to_user_mode_loop+0x105/0x130
+[73496.158336] exit_to_user_mode_prepare+0xa5/0xb0
+[73496.158338] syscall_exit_to_user_mode+0x29/0x60
+[73496.158341] do_syscall_64+0x6c/0xf0
+[73496.158344] ? syscall_exit_to_user_mode+0x37/0x60
+[73496.158346] ? do_syscall_64+0x6c/0xf0
+[73496.158349] ? exit_to_user_mode_prepare+0x30/0xb0
+[73496.158353] ? syscall_exit_to_user_mode+0x37/0x60
+[73496.158355] ? do_syscall_64+0x6c/0xf0
+
+Reported-by: Robert Morris <rtm@csail.mit.edu>
+Fixes: 705fc522fe9d ("cifs: handle when server starts supporting multichannel")
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/smb2pdu.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -440,8 +440,7 @@ skip_sess_setup:
+ skip_add_channels:
+
+ if (smb2_command != SMB2_INTERNAL_CMD)
+- if (mod_delayed_work(cifsiod_wq, &server->reconnect, 0))
+- cifs_put_tcp_session(server, false);
++ mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
+
+ atomic_inc(&tconInfoReconnectCount);
+ out:
--- /dev/null
+From 5eef12c4e3230f2025dc46ad8c4a3bc19978e5d7 Mon Sep 17 00:00:00 2001
+From: Shyam Prasad N <sprasad@microsoft.com>
+Date: Tue, 14 Nov 2023 04:58:23 +0000
+Subject: cifs: fix lock ordering while disabling multichannel
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+commit 5eef12c4e3230f2025dc46ad8c4a3bc19978e5d7 upstream.
+
+The code to handle the case of server disabling multichannel
+was picking iface_lock with chan_lock held. This goes against
+the lock ordering rules, as iface_lock is a higher order lock
+(even if it isn't so obvious).
+
+This change fixes the lock ordering by doing the following in
+that order for each secondary channel:
+1. store iface and server pointers in local variable
+2. remove references to iface and server in channels
+3. unlock chan_lock
+4. lock iface_lock
+5. dec ref count for iface
+6. unlock iface_lock
+7. dec ref count for server
+8. lock chan_lock again
+
+Since this function can only be called in smb2_reconnect, and
+that cannot be called by two parallel processes, we should not
+have races due to dropping chan_lock between steps 3 and 8.
+
+Fixes: ee1d21794e55 ("cifs: handle when server stops supporting multichannel")
+Reported-by: Paulo Alcantara <pc@manguebit.com>
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/sess.c | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+--- a/fs/smb/client/sess.c
++++ b/fs/smb/client/sess.c
+@@ -316,28 +316,32 @@ cifs_disable_secondary_channels(struct c
+ iface = ses->chans[i].iface;
+ server = ses->chans[i].server;
+
++ /*
++ * remove these references first, since we need to unlock
++ * the chan_lock here, since iface_lock is a higher lock
++ */
++ ses->chans[i].iface = NULL;
++ ses->chans[i].server = NULL;
++ spin_unlock(&ses->chan_lock);
++
+ if (iface) {
+ spin_lock(&ses->iface_lock);
+ kref_put(&iface->refcount, release_iface);
+- ses->chans[i].iface = NULL;
+ iface->num_channels--;
+ if (iface->weight_fulfilled)
+ iface->weight_fulfilled--;
+ spin_unlock(&ses->iface_lock);
+ }
+
+- spin_unlock(&ses->chan_lock);
+- if (server && !server->terminate) {
+- server->terminate = true;
+- cifs_signal_cifsd_for_reconnect(server, false);
+- }
+- spin_lock(&ses->chan_lock);
+-
+ if (server) {
+- ses->chans[i].server = NULL;
++ if (!server->terminate) {
++ server->terminate = true;
++ cifs_signal_cifsd_for_reconnect(server, false);
++ }
+ cifs_put_tcp_session(server, false);
+ }
+
++ spin_lock(&ses->chan_lock);
+ }
+
+ done:
bpf-keep-track-of-max-number-of-bpf_loop-callback-iterations.patch
selftests-bpf-check-if-max-number-of-bpf_loop-iterations-is-tracked.patch
revert-drm-amd-enable-pcie-pme-from-d3.patch
+cifs-fix-lock-ordering-while-disabling-multichannel.patch
+cifs-fix-a-pending-undercount-of-srv_count.patch
+cifs-after-disabling-multichannel-mark-tcon-for-reconnect.patch