diff mbox

Message ID CAH2r5mtBQ3gRpvcx593sr3mUF6+pgy6cKcu3ipq7M13A7rVhwQ@mail.gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Steve French May 4, 2017, 1:20 p.m. UTC
Any thoughts on removing the dependency on srv_mutex in deleting
completed requests (and freeing its memory) ? Otherwise it can cause
problems with long running socket writes (on sending new requests)
which don't get the benefit of finishing up response processing due to
the blocking of DeleteMidQEntry on server->srv_mutex

This should improve performance as well.

(Long Li was noticing this looking at RDMA with cifs.ko)

See attached patch
diff mbox

Patch

From 429bb0e9da0db34bf75d5335fe6b4011db8765ad Mon Sep 17 00:00:00 2001
From: Steve French <smfrench@gmail.com>
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 <steve.french@primarydata.com>
---
 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