From 429bb0e9da0db34bf75d5335fe6b4011db8765ad Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 4 May 2017 07:54:04 -0500 Subject: [PATCH] [CIFS] Don't delay freeing mids when blocked on slow socket write of request When processing responses, and in particular freeing mids (DeleteMidQEntry), which is very important since it also frees the associated buffers (cifs_buf_release), we can block a long time if (writes to) socket is slow due to low memory or networking issues. We can block in send (smb request) waiting for memory, and be blocked in processing responess (which could free memory if we let it) - since they both grab the server->srv_mutex. In practice, in the DeleteMidQEntry case - there is no reason we need to grab the srv_mutex so remove these around DeleteMidQEntry, and it allows us to free memory faster. Signed-off-by: Steve French --- fs/cifs/cifssmb.c | 7 ------- fs/cifs/smb2pdu.c | 7 ------- fs/cifs/transport.c | 2 -- 3 files changed, 16 deletions(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 205fd94..5245723 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -697,9 +697,7 @@ static int validate_t2(struct smb_t2_rsp *pSMB) { struct TCP_Server_Info *server = mid->callback_data; - mutex_lock(&server->srv_mutex); DeleteMidQEntry(mid); - mutex_unlock(&server->srv_mutex); add_credits(server, 1, CIFS_ECHO_OP); } @@ -1599,9 +1597,7 @@ static __u16 convert_disposition(int disposition) } queue_work(cifsiod_wq, &rdata->work); - mutex_lock(&server->srv_mutex); DeleteMidQEntry(mid); - mutex_unlock(&server->srv_mutex); add_credits(server, 1, 0); } @@ -2058,7 +2054,6 @@ struct cifs_writedata * { struct cifs_writedata *wdata = mid->callback_data; struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); - struct TCP_Server_Info *server = tcon->ses->server; unsigned int written; WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf; @@ -2095,9 +2090,7 @@ struct cifs_writedata * } queue_work(cifsiod_wq, &wdata->work); - mutex_lock(&server->srv_mutex); DeleteMidQEntry(mid); - mutex_unlock(&server->srv_mutex); add_credits(tcon->ses->server, 1, 0); } diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 0fd63f0..e4007ee 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2172,9 +2172,7 @@ static inline void init_copy_chunk_defaults(struct cifs_tcon *tcon) if (mid->mid_state == MID_RESPONSE_RECEIVED) credits_received = le16_to_cpu(rsp->hdr.sync_hdr.CreditRequest); - mutex_lock(&server->srv_mutex); DeleteMidQEntry(mid); - mutex_unlock(&server->srv_mutex); add_credits(server, credits_received, CIFS_ECHO_OP); } @@ -2432,9 +2430,7 @@ void smb2_reconnect_server(struct work_struct *work) cifs_stats_fail_inc(tcon, SMB2_READ_HE); queue_work(cifsiod_wq, &rdata->work); - mutex_lock(&server->srv_mutex); DeleteMidQEntry(mid); - mutex_unlock(&server->srv_mutex); add_credits(server, credits_received, 0); } @@ -2593,7 +2589,6 @@ void smb2_reconnect_server(struct work_struct *work) { struct cifs_writedata *wdata = mid->callback_data; struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); - struct TCP_Server_Info *server = tcon->ses->server; unsigned int written; struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf; unsigned int credits_received = 1; @@ -2633,9 +2628,7 @@ void smb2_reconnect_server(struct work_struct *work) cifs_stats_fail_inc(tcon, SMB2_WRITE_HE); queue_work(cifsiod_wq, &wdata->work); - mutex_lock(&server->srv_mutex); DeleteMidQEntry(mid); - mutex_unlock(&server->srv_mutex); add_credits(tcon->ses->server, credits_received, 0); } diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 4d64b5b..de589d0 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -613,9 +613,7 @@ struct mid_q_entry * } spin_unlock(&GlobalMid_Lock); - mutex_lock(&server->srv_mutex); DeleteMidQEntry(mid); - mutex_unlock(&server->srv_mutex); return rc; } -- 1.9.1