Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751899AbdH2TcY (ORCPT ); Tue, 29 Aug 2017 15:32:24 -0400 Received: from a2nlsmtp01-04.prod.iad2.secureserver.net ([198.71.225.38]:52044 "EHLO a2nlsmtp01-04.prod.iad2.secureserver.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751763AbdH2Tav (ORCPT ); Tue, 29 Aug 2017 15:30:51 -0400 x-originating-ip: 107.180.71.197 From: Long Li To: Steve French , linux-cifs@vger.kernel.org, samba-technical@lists.samba.org, linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org, Christoph Hellwig , Tom Talpey , Matthew Wilcox Cc: Long Li Subject: [Patch v3 17/19] CIFS: SMBD: Implement SMB read via RDMA write through memory registration Date: Tue, 29 Aug 2017 12:29:13 -0700 Message-Id: <20170829192915.26251-18-longli@exchange.microsoft.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170829192915.26251-1-longli@exchange.microsoft.com> References: <20170829192915.26251-1-longli@exchange.microsoft.com> X-CMAE-Envelope: MS4wfMVa9yDgDGo4O+dHvEYAncJ9m3mLe8h5U/Be+lYQ/2xdWVAPDuRxiKbAY/PU/CcjltsNLzDBeXxOC3Rq9J1Yc6fetvztW6TZxG2cnAHN9BjS6h1yczt4 We99ONmeODh/NZjd5OYHWy8Ume5JAARCEh2uWawVMGQacZPOUnu0Elqyk1bfjx98Os672YBvGIqgNWMzZiDhPVylJgUfK6vdPrYLRRTLa4nUC1Erb9MHB08+ 0Gu7+Rnl2kS2aVxa+nrjLA4E1VKHAKkrCwd+J8WDMyf8Vlsf0FoRqCzy6NeRQlq0uq/xmLg3u+RboQaAETxKiQ17ACm0lA+yuu8zX2J1sNsQ78qTFJY5n8wB 4pIlOGQiFzSypsri6qKU57CRWJd9rMJts4Q7kwyUK9151X/hA3LPtLjO5hr1lxybxAuKUQxH8xTpM/uUbyQyCA12AmuvhNkmC7C1VYPj/9LuguKTn86IQDao xJRUv6/OL9/wXh9w Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3016 Lines: 94 From: Long Li If I/O size is larger than rdma_readwrite_threshold, use RDMA write for SMB read by specifying channel SMB2_CHANNEL_RDMA_V1 or SMB2_CHANNEL_RDMA_V1_INVALIDATE in the SMB packet, depending on SMB dialect used. Append a smbd_buffer_descriptor_v1 to the end of the SMB packet and fill in other values to indicate this SMB read uses RDMA write. There is no need to read from the transport for incoming payload. At the time SMB read response comes back, the data is already transfered and placed in the pages by RDMA hardware. Signed-off-by: Long Li --- fs/cifs/file.c | 5 +++++ fs/cifs/smb2pdu.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index dec70b3..41460a5 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -42,6 +42,7 @@ #include "cifs_debug.h" #include "cifs_fs_sb.h" #include "fscache.h" +#include "smbdirect.h" static inline int cifs_convert_flags(unsigned int flags) @@ -3037,6 +3038,8 @@ uncached_fill_pages(struct TCP_Server_Info *server, } if (iter) result = copy_page_from_iter(page, 0, n, iter); + else if (rdata->mr) + result = n; else result = cifs_read_page_from_socket(server, page, n); if (result < 0) @@ -3606,6 +3609,8 @@ readpages_fill_pages(struct TCP_Server_Info *server, if (iter) result = copy_page_from_iter(page, 0, n, iter); + else if (rdata->mr) + result = n; else result = cifs_read_page_from_socket(server, page, n); if (result < 0) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index fbad987..1f08c75 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2392,6 +2392,39 @@ smb2_new_read_req(void **buf, unsigned int *total_len, req->Length = cpu_to_le32(io_parms->length); req->Offset = cpu_to_le64(io_parms->offset); + /* + * If we want to do a RDMA write, fill in and append + * smbd_buffer_descriptor_v1 to the end of read request + */ + if (server->rdma && rdata && + rdata->bytes > server->smbd_conn->rdma_readwrite_threshold) { + + struct smbd_buffer_descriptor_v1 *v1; + bool need_invalidate = + io_parms->tcon->ses->server->dialect == SMB30_PROT_ID; + + rdata->mr = smbd_register_mr( + server->smbd_conn, rdata->pages, + rdata->nr_pages, rdata->tailsz, + true, need_invalidate); + if (!rdata->mr) + return -ENOBUFS; + + req->Channel = SMB2_CHANNEL_RDMA_V1_INVALIDATE; + if (need_invalidate) + req->Channel = SMB2_CHANNEL_RDMA_V1; + req->ReadChannelInfoOffset = + offsetof(struct smb2_read_plain_req, Buffer); + req->ReadChannelInfoLength = + sizeof(struct smbd_buffer_descriptor_v1); + v1 = (struct smbd_buffer_descriptor_v1 *) &req->Buffer[0]; + v1->offset = rdata->mr->mr->iova; + v1->token = rdata->mr->mr->rkey; + v1->length = rdata->mr->mr->length; + + *total_len += sizeof(*v1) - 1; + } + if (request_type & CHAINED_REQUEST) { if (!(request_type & END_OF_CHAIN)) { /* next 8-byte aligned request */ -- 2.7.4