linux/fs/cifs
Vincent Whitchurch cc391b694f cifs: fix potential deadlock in direct reclaim
The srv_mutex is used during writeback so cifs should ensure that
allocations done when that mutex is held are done with GFP_NOFS, to
avoid having direct reclaim ending up waiting for the same mutex and
causing a deadlock.  This is detected by lockdep with the splat below:

 ======================================================
 WARNING: possible circular locking dependency detected
 5.18.0 #70 Not tainted
 ------------------------------------------------------
 kswapd0/49 is trying to acquire lock:
 ffff8880195782e0 (&tcp_ses->srv_mutex){+.+.}-{3:3}, at: compound_send_recv

 but task is already holding lock:
 ffffffffa98e66c0 (fs_reclaim){+.+.}-{0:0}, at: balance_pgdat

 which lock already depends on the new lock.

 the existing dependency chain (in reverse order) is:

 -> #1 (fs_reclaim){+.+.}-{0:0}:
        fs_reclaim_acquire
        kmem_cache_alloc_trace
        __request_module
        crypto_alg_mod_lookup
        crypto_alloc_tfm_node
        crypto_alloc_shash
        cifs_alloc_hash
        smb311_crypto_shash_allocate
        smb311_update_preauth_hash
        compound_send_recv
        cifs_send_recv
        SMB2_negotiate
        smb2_negotiate
        cifs_negotiate_protocol
        cifs_get_smb_ses
        cifs_mount
        cifs_smb3_do_mount
        smb3_get_tree
        vfs_get_tree
        path_mount
        __x64_sys_mount
        do_syscall_64
        entry_SYSCALL_64_after_hwframe

 -> #0 (&tcp_ses->srv_mutex){+.+.}-{3:3}:
        __lock_acquire
        lock_acquire
        __mutex_lock
        mutex_lock_nested
        compound_send_recv
        cifs_send_recv
        SMB2_write
        smb2_sync_write
        cifs_write
        cifs_writepage_locked
        cifs_writepage
        shrink_page_list
        shrink_lruvec
        shrink_node
        balance_pgdat
        kswapd
        kthread
        ret_from_fork

 other info that might help us debug this:

  Possible unsafe locking scenario:

        CPU0                    CPU1
        ----                    ----
   lock(fs_reclaim);
                                lock(&tcp_ses->srv_mutex);
                                lock(fs_reclaim);
   lock(&tcp_ses->srv_mutex);

  *** DEADLOCK ***

 1 lock held by kswapd0/49:
  #0: ffffffffa98e66c0 (fs_reclaim){+.+.}-{0:0}, at: balance_pgdat

 stack backtrace:
 CPU: 2 PID: 49 Comm: kswapd0 Not tainted 5.18.0 #70
 Call Trace:
  <TASK>
  dump_stack_lvl
  dump_stack
  print_circular_bug.cold
  check_noncircular
  __lock_acquire
  lock_acquire
  __mutex_lock
  mutex_lock_nested
  compound_send_recv
  cifs_send_recv
  SMB2_write
  smb2_sync_write
  cifs_write
  cifs_writepage_locked
  cifs_writepage
  shrink_page_list
  shrink_lruvec
  shrink_node
  balance_pgdat
  kswapd
  kthread
  ret_from_fork
  </TASK>

Fix this by using the memalloc_nofs_save/restore APIs around the places
where the srv_mutex is held.  Do this in a wrapper function for the
lock/unlock of the srv_mutex, and rename the srv_mutex to avoid missing
call sites in the conversion.

Note that there is another lockdep warning involving internal crypto
locks, which was masked by this problem and is visible after this fix,
see the discussion in this thread:

 https://lore.kernel.org/all/20220523123755.GA13668@axis.com/

Link: https://lore.kernel.org/r/CANT5p=rqcYfYMVHirqvdnnca4Mo+JQSw5Qu12v=kPfpk5yhhmg@mail.gmail.com/
Reported-by: Shyam Prasad N <nspmangalore@gmail.com>
Suggested-by: Lars Persson <larper@axis.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Reviewed-by: Enzo Matsumiya <ematsumiya@suse.de>
Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
2022-06-01 00:03:18 -05:00
..
asn1.c cifs: decoding negTokenInit with generic ASN1 decoder 2021-06-20 21:28:17 -05:00
cifs_debug.c cifs: avoid parallel session setups on same channel 2022-05-24 14:16:32 -05:00
cifs_debug.h cifs: use SPDX-Licence-Identifier 2021-06-20 21:28:17 -05:00
cifs_dfs_ref.c cifs: support nested dfs links over reconnect 2021-11-10 16:30:13 -06:00
cifs_fs_sb.h cifs: support nested dfs links over reconnect 2021-11-10 16:30:13 -06:00
cifs_ioctl.h cifs: remove pathname for file from SPDX header 2021-09-13 14:51:10 -05:00
cifs_spnego_negtokeninit.asn1 cifs: decoding negTokenInit with generic ASN1 decoder 2021-06-20 21:28:17 -05:00
cifs_spnego.c cifs: use the chans_need_reconnect bitmap for reconnect status 2022-01-02 20:38:46 -06:00
cifs_spnego.h cifs: use the chans_need_reconnect bitmap for reconnect status 2022-01-02 20:38:46 -06:00
cifs_swn.c cifs: fix potential deadlock in direct reclaim 2022-06-01 00:03:18 -05:00
cifs_swn.h cifs: simplify SWN code with dummy funcs instead of ifdefs 2021-04-25 16:28:22 -05:00
cifs_unicode.c cifs: remove pathname for file from SPDX header 2021-09-13 14:51:10 -05:00
cifs_unicode.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
cifs_uniupr.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156 2019-05-30 11:26:35 -07:00
cifsacl.c cifs: modefromsids must add an ACE for authenticated users 2022-02-14 09:55:51 -06:00
cifsacl.h cifs: remove pathname for file from SPDX header 2021-09-13 14:51:10 -05:00
cifsencrypt.c cifs: fix potential deadlock in direct reclaim 2022-06-01 00:03:18 -05:00
cifsfs.c cifs: fix potential double free during failed mount 2022-05-30 23:04:58 -05:00
cifsfs.h cifs: update internal module number 2022-04-04 22:40:14 -05:00
cifsglob.h cifs: fix potential deadlock in direct reclaim 2022-06-01 00:03:18 -05:00
cifspdu.h smb3: move defines for query info and query fsinfo to smbfs_common 2022-03-26 23:09:51 -05:00
cifsproto.h cifs: avoid parallel session setups on same channel 2022-05-24 14:16:32 -05:00
cifsroot.c cifs: Standardize logging output 2020-06-01 00:10:18 -05:00
cifssmb.c cifs: use new enum for ses_status 2022-05-24 14:11:17 -05:00
connect.c cifs: fix potential deadlock in direct reclaim 2022-06-01 00:03:18 -05:00
dfs_cache.c cifs: fix potential deadlock in direct reclaim 2022-06-01 00:03:18 -05:00
dfs_cache.h cifs: support share failover when remounting 2021-07-22 11:43:23 -05:00
dir.c cifs: Support fscache indexing rewrite 2022-01-19 11:21:08 -06:00
dns_resolve.c cifs: remove pathname for file from SPDX header 2021-09-13 14:51:10 -05:00
dns_resolve.h cifs: remove pathname for file from SPDX header 2021-09-13 14:51:10 -05:00
export.c cifs: remove pathname for file from SPDX header 2021-09-13 14:51:10 -05:00
file.c Twenty four cifs/smb3 client fixes, including multichannel but does not include the iov_iter ones 2022-05-27 16:05:57 -07:00
fs_context.c cifs: fix ntlmssp on old servers 2022-05-25 07:41:22 -05:00
fs_context.h cifs: fix ntlmssp on old servers 2022-05-25 07:41:22 -05:00
fscache.c netfs: Add a netfs inode context 2022-03-18 09:29:05 +00:00
fscache.h netfs: Add a netfs inode context 2022-03-18 09:29:05 +00:00
inode.c fs: Remove ->readpages address space operation 2022-04-01 13:45:33 -04:00
ioctl.c cifs: fix incorrect kernel doc comments 2021-09-13 18:29:46 -05:00
Kconfig cifs: Support fscache indexing rewrite 2022-01-19 11:21:08 -06:00
link.c cifs: potential buffer overflow in handling symlinks 2022-04-13 12:00:49 -05:00
Makefile cifs: Support fscache indexing rewrite 2022-01-19 11:21:08 -06:00
misc.c cifs: fix ntlmssp on old servers 2022-05-25 07:41:22 -05:00
netlink.c cifs: Constify static struct genl_ops 2021-06-20 21:28:16 -05:00
netlink.h cifs: Register generic netlink family 2020-12-14 09:16:22 -06:00
netmisc.c cifs: fix potential race with cifsd thread 2022-04-04 12:01:22 -05:00
nterr.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 61 2019-05-24 17:36:45 +02:00
nterr.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 61 2019-05-24 17:36:45 +02:00
ntlmssp.h treewide: Replace zero-length arrays with flexible-array members 2022-02-17 07:00:39 -06:00
readdir.c smb3: remove unneeded null check in cifs_readdir 2022-05-27 12:05:47 -05:00
rfc1002pdu.h cifs: remove pathname for file from SPDX header 2021-09-13 14:51:10 -05:00
sess.c cifs: fix potential deadlock in direct reclaim 2022-06-01 00:03:18 -05:00
smb1ops.c cifs: fix potential deadlock in direct reclaim 2022-06-01 00:03:18 -05:00
smb2file.c cifs: remove pathname for file from SPDX header 2021-09-13 14:51:10 -05:00
smb2glob.h smb3: move defines for ioctl protocol header and SMB2 sizes to smbfs_common 2022-03-26 23:09:20 -05:00
smb2inode.c cifs: set the CREATE_NOT_FILE when opening the directory in use_cached_dir() 2022-05-21 12:23:24 -05:00
smb2maperror.c cifs: Create a new shared file holding smb2 pdu definitions 2021-11-05 09:50:57 -05:00
smb2misc.c smb3: add trace point for oplock not found 2022-05-22 00:46:08 -05:00
smb2ops.c cifs: when extending a file with falloc we should make files not-sparse 2022-05-31 18:04:06 -05:00
smb2pdu.c cifs: fix potential deadlock in direct reclaim 2022-06-01 00:03:18 -05:00
smb2pdu.h Add various fsctl structs 2022-05-23 20:24:12 -05:00
smb2proto.h cifs: convert the path to utf16 in smb2_query_info_compound 2022-03-23 15:17:22 -05:00
smb2status.h cifs: remove pathname for file from SPDX header 2021-09-13 14:51:10 -05:00
smb2transport.c cifs: use new enum for ses_status 2022-05-24 14:11:17 -05:00
smbdirect.c cifs: fix potential deadlock in direct reclaim 2022-06-01 00:03:18 -05:00
smbdirect.h cifs: smbd: Do not schedule work to send immediate packet on every receive 2020-04-07 12:41:16 -05:00
smbencrypt.c cifs: rename cifs_common to smbfs_common 2021-09-08 23:59:26 -05:00
smberr.h cifs: remove pathname for file from SPDX header 2021-09-13 14:51:10 -05:00
trace.c smb3: Cleanup license mess 2019-01-24 09:37:33 -06:00
trace.h smb3: add trace point for oplock not found 2022-05-22 00:46:08 -05:00
transport.c cifs: fix potential deadlock in direct reclaim 2022-06-01 00:03:18 -05:00
unc.c cifs: don't cargo-cult strndup() 2021-04-25 16:28:23 -05:00
winucase.c cifs: remove pathname for file from SPDX header 2021-09-13 14:51:10 -05:00
xattr.c cifs: fix set of group SID via NTSD xattrs 2022-02-13 14:56:34 -06:00