From: Long Li <lon...@microsoft.com>

When SMB read is finished, deregister the memory regions if RDMA write is used
for this SMB read. smbd_deregister_mr may need to do local invalidation and
sleep, if server remote invalidation is not used.

There are situations where the MID may not be created on I/O failure, under
which memory region is deregistered when read data context is released.

Signed-off-by: Long Li <lon...@microsoft.com>
---
 fs/cifs/file.c    |  5 +++++
 fs/cifs/smb2pdu.c | 10 ++++++++++
 2 files changed, 15 insertions(+)

diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 41460a5..5a6df25 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2910,6 +2910,11 @@ cifs_readdata_release(struct kref *refcount)
        struct cifs_readdata *rdata = container_of(refcount,
                                        struct cifs_readdata, refcount);
 
+       if (rdata->mr) {
+               smbd_deregister_mr(rdata->mr);
+               rdata->mr = NULL;
+       }
+
        if (rdata->cfile)
                cifsFileInfo_put(rdata->cfile);
 
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 1f08c75..43a7b60 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -2504,6 +2504,16 @@ smb2_readv_callback(struct mid_q_entry *mid)
                        rdata->result = -EIO;
        }
 
+       /*
+        * If this rdata has a memmory registered, the MR can be freed
+        * MR needs to be freed as soon as I/O finishes to prevent deadlock
+        * because they have limited number and are used for future I/Os
+        */
+       if (rdata->mr) {
+               smbd_deregister_mr(rdata->mr);
+               rdata->mr = NULL;
+       }
+
        if (rdata->result)
                cifs_stats_fail_inc(tcon, SMB2_READ_HE);
 
-- 
2.7.4

Reply via email to