From d7d7a66aacd6fd8ca57baf08a7bac5421282f6f8 Mon Sep 17 00:00:00 2001 From: Shyam Prasad N Date: Wed, 27 Jul 2022 14:49:56 -0500 Subject: cifs: avoid use of global locks for high contention data During analysis of multichannel perf, it was seen that the global locks cifs_tcp_ses_lock and GlobalMid_Lock, which were shared between various data structures were causing a lot of contention points. With this change, we're breaking down the use of these locks by introducing new locks at more granular levels. i.e. server->srv_lock, ses->ses_lock and tcon->tc_lock to protect the unprotected fields of server, session and tcon structs; and server->mid_lock to protect mid related lists and entries at server level. Signed-off-by: Shyam Prasad N Signed-off-by: Steve French --- fs/cifs/cifssmb.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'fs/cifs/cifssmb.c') diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 9ed21752f2df..04a4c304d004 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -74,13 +74,13 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon) struct list_head *tmp1; /* only send once per connect */ - spin_lock(&cifs_tcp_ses_lock); + spin_lock(&tcon->ses->ses_lock); if ((tcon->ses->ses_status != SES_GOOD) || (tcon->status != TID_NEED_RECON)) { - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&tcon->ses->ses_lock); return; } tcon->status = TID_IN_FILES_INVALIDATE; - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&tcon->ses->ses_lock); /* list all files open on tree connection and mark them invalid */ spin_lock(&tcon->open_file_lock); @@ -98,10 +98,10 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon) memset(tcon->crfid.fid, 0, sizeof(struct cifs_fid)); mutex_unlock(&tcon->crfid.fid_mutex); - spin_lock(&cifs_tcp_ses_lock); + spin_lock(&tcon->tc_lock); if (tcon->status == TID_IN_FILES_INVALIDATE) tcon->status = TID_NEED_TCON; - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&tcon->tc_lock); /* * BB Add call to invalidate_inodes(sb) for all superblocks mounted @@ -134,18 +134,18 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) * only tree disconnect, open, and write, (and ulogoff which does not * have tcon) are allowed as we start force umount */ - spin_lock(&cifs_tcp_ses_lock); + spin_lock(&tcon->tc_lock); if (tcon->status == TID_EXITING) { if (smb_command != SMB_COM_WRITE_ANDX && smb_command != SMB_COM_OPEN_ANDX && smb_command != SMB_COM_TREE_DISCONNECT) { - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&tcon->tc_lock); cifs_dbg(FYI, "can not send cmd %d while umounting\n", smb_command); return -ENODEV; } } - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&tcon->tc_lock); retries = server->nr_targets; @@ -165,12 +165,12 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) } /* are we still trying to reconnect? */ - spin_lock(&cifs_tcp_ses_lock); + spin_lock(&server->srv_lock); if (server->tcpStatus != CifsNeedReconnect) { - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&server->srv_lock); break; } - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&server->srv_lock); if (retries && --retries) continue; @@ -201,13 +201,13 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) * and the server never sends an answer the socket will be closed * and tcpStatus set to reconnect. */ - spin_lock(&cifs_tcp_ses_lock); + spin_lock(&server->srv_lock); if (server->tcpStatus == CifsNeedReconnect) { - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&server->srv_lock); rc = -EHOSTDOWN; goto out; } - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&server->srv_lock); /* * need to prevent multiple threads trying to simultaneously -- cgit v1.2.3