diff options
author | Shyam Prasad N <sprasad@microsoft.com> | 2022-07-27 21:49:56 +0200 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2022-08-01 08:34:45 +0200 |
commit | d7d7a66aacd6fd8ca57baf08a7bac5421282f6f8 (patch) | |
tree | 2565cb830065b2c06cefd085866c3de926d688b5 /fs/cifs/smb2transport.c | |
parent | cifs: remove remaining build warnings (diff) | |
download | linux-d7d7a66aacd6fd8ca57baf08a7bac5421282f6f8.tar.xz linux-d7d7a66aacd6fd8ca57baf08a7bac5421282f6f8.zip |
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 <sprasad@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/smb2transport.c')
-rw-r--r-- | fs/cifs/smb2transport.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index 53ff6bc11939..f64922f340b3 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c @@ -640,13 +640,13 @@ smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server) if (!is_signed) return 0; - spin_lock(&cifs_tcp_ses_lock); + spin_lock(&server->srv_lock); if (server->ops->need_neg && server->ops->need_neg(server)) { - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&server->srv_lock); return 0; } - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&server->srv_lock); if (!is_binding && !server->session_estab) { strncpy(shdr->Signature, "BSRSPYL", 8); return 0; @@ -762,28 +762,30 @@ static int smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server, struct smb2_hdr *shdr, struct mid_q_entry **mid) { - spin_lock(&cifs_tcp_ses_lock); + spin_lock(&server->srv_lock); if (server->tcpStatus == CifsExiting) { - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&server->srv_lock); return -ENOENT; } if (server->tcpStatus == CifsNeedReconnect) { - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&server->srv_lock); cifs_dbg(FYI, "tcp session dead - return to caller to retry\n"); return -EAGAIN; } if (server->tcpStatus == CifsNeedNegotiate && shdr->Command != SMB2_NEGOTIATE) { - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&server->srv_lock); return -EAGAIN; } + spin_unlock(&server->srv_lock); + spin_lock(&ses->ses_lock); if (ses->ses_status == SES_NEW) { if ((shdr->Command != SMB2_SESSION_SETUP) && (shdr->Command != SMB2_NEGOTIATE)) { - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&ses->ses_lock); return -EAGAIN; } /* else ok - we are setting up session */ @@ -791,19 +793,19 @@ smb2_get_mid_entry(struct cifs_ses *ses, struct TCP_Server_Info *server, if (ses->ses_status == SES_EXITING) { if (shdr->Command != SMB2_LOGOFF) { - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&ses->ses_lock); return -EAGAIN; } /* else ok - we are shutting down the session */ } - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&ses->ses_lock); *mid = smb2_mid_entry_alloc(shdr, server); if (*mid == NULL) return -ENOMEM; - spin_lock(&GlobalMid_Lock); + spin_lock(&server->mid_lock); list_add_tail(&(*mid)->qhead, &server->pending_mid_q); - spin_unlock(&GlobalMid_Lock); + spin_unlock(&server->mid_lock); return 0; } @@ -869,13 +871,13 @@ smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst) (struct smb2_hdr *)rqst->rq_iov[0].iov_base; struct mid_q_entry *mid; - spin_lock(&cifs_tcp_ses_lock); + spin_lock(&server->srv_lock); if (server->tcpStatus == CifsNeedNegotiate && shdr->Command != SMB2_NEGOTIATE) { - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&server->srv_lock); return ERR_PTR(-EAGAIN); } - spin_unlock(&cifs_tcp_ses_lock); + spin_unlock(&server->srv_lock); smb2_seq_num_into_buf(server, shdr); |