From c7398583340a6d82b8bb7f7f21edcde27dc6a898 Mon Sep 17 00:00:00 2001 From: Long Li Date: Wed, 22 Nov 2017 17:38:44 -0700 Subject: CIFS: SMBD: Implement RDMA memory registration Memory registration is used for transferring payload via RDMA read or write. After I/O is done, memory registrations are recovered and reused. This process can be time consuming and is done in a work queue. Signed-off-by: Long Li Reviewed-by: Pavel Shilovsky Reviewed-by: Ronnie Sahlberg Signed-off-by: Steve French --- fs/cifs/smbdirect.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'fs/cifs/smbdirect.h') diff --git a/fs/cifs/smbdirect.h b/fs/cifs/smbdirect.h index 27453ef2181f..fdb8df84fa1f 100644 --- a/fs/cifs/smbdirect.h +++ b/fs/cifs/smbdirect.h @@ -90,6 +90,29 @@ struct smbd_connection { int receive_credit_target; int fragment_reassembly_remaining; + /* Memory registrations */ + /* Maximum number of RDMA read/write outstanding on this connection */ + int responder_resources; + /* Maximum number of SGEs in a RDMA write/read */ + int max_frmr_depth; + /* + * If payload is less than or equal to the threshold, + * use RDMA send/recv to send upper layer I/O. + * If payload is more than the threshold, + * use RDMA read/write through memory registration for I/O. + */ + int rdma_readwrite_threshold; + enum ib_mr_type mr_type; + struct list_head mr_list; + spinlock_t mr_list_lock; + /* The number of available MRs ready for memory registration */ + atomic_t mr_ready_count; + atomic_t mr_used_count; + wait_queue_head_t wait_mr; + struct work_struct mr_recovery_work; + /* Used by transport to wait until all MRs are returned */ + wait_queue_head_t wait_for_mr_cleanup; + /* Activity accoutning */ /* Pending reqeusts issued from upper layer */ int smbd_send_pending; @@ -262,6 +285,36 @@ void smbd_destroy(struct smbd_connection *info); int smbd_recv(struct smbd_connection *info, struct msghdr *msg); int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst); +enum mr_state { + MR_READY, + MR_REGISTERED, + MR_INVALIDATED, + MR_ERROR +}; + +struct smbd_mr { + struct smbd_connection *conn; + struct list_head list; + enum mr_state state; + struct ib_mr *mr; + struct scatterlist *sgl; + int sgl_count; + enum dma_data_direction dir; + union { + struct ib_reg_wr wr; + struct ib_send_wr inv_wr; + }; + struct ib_cqe cqe; + bool need_invalidate; + struct completion invalidate_done; +}; + +/* Interfaces to register and deregister MR for RDMA read/write */ +struct smbd_mr *smbd_register_mr( + struct smbd_connection *info, struct page *pages[], int num_pages, + int tailsz, bool writing, bool need_invalidate); +int smbd_deregister_mr(struct smbd_mr *mr); + #else #define cifs_rdma_enabled(server) 0 struct smbd_connection {}; -- cgit v1.2.3