1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Copyright (C) 2017, Microsoft Corporation. 4 * 5 * Author(s): Long Li <longli@microsoft.com> 6 */ 7 #ifndef _SMBDIRECT_H 8 #define _SMBDIRECT_H 9 10 #ifdef CONFIG_CIFS_SMB_DIRECT 11 #define cifs_rdma_enabled(server) ((server)->rdma) 12 13 #include "cifsglob.h" 14 #include <rdma/ib_verbs.h> 15 #include <rdma/rdma_cm.h> 16 #include <linux/mempool.h> 17 18 #include "../common/smbdirect/smbdirect.h" 19 #include "../common/smbdirect/smbdirect_socket.h" 20 21 extern int rdma_readwrite_threshold; 22 extern int smbd_max_frmr_depth; 23 extern int smbd_keep_alive_interval; 24 extern int smbd_max_receive_size; 25 extern int smbd_max_fragmented_recv_size; 26 extern int smbd_max_send_size; 27 extern int smbd_send_credit_target; 28 extern int smbd_receive_credit_max; 29 30 enum keep_alive_status { 31 KEEP_ALIVE_NONE, 32 KEEP_ALIVE_PENDING, 33 KEEP_ALIVE_SENT, 34 }; 35 36 /* 37 * The context for the SMBDirect transport 38 * Everything related to the transport is here. It has several logical parts 39 * 1. RDMA related structures 40 * 2. SMBDirect connection parameters 41 * 3. Memory registrations 42 * 4. Receive and reassembly queues for data receive path 43 * 5. mempools for allocating packets 44 */ 45 struct smbd_connection { 46 struct smbdirect_socket socket; 47 48 int ri_rc; 49 struct completion ri_done; 50 wait_queue_head_t status_wait; 51 52 struct completion negotiate_completion; 53 bool negotiate_done; 54 55 struct work_struct disconnect_work; 56 struct work_struct post_send_credits_work; 57 58 spinlock_t lock_new_credits_offered; 59 int new_credits_offered; 60 61 /* dynamic connection parameters defined in [MS-SMBD] 3.1.1.1 */ 62 enum keep_alive_status keep_alive_requested; 63 int protocol; 64 atomic_t send_credits; 65 atomic_t receive_credits; 66 int receive_credit_target; 67 68 /* Memory registrations */ 69 /* Maximum number of RDMA read/write outstanding on this connection */ 70 int responder_resources; 71 /* Maximum number of pages in a single RDMA write/read on this connection */ 72 int max_frmr_depth; 73 /* 74 * If payload is less than or equal to the threshold, 75 * use RDMA send/recv to send upper layer I/O. 76 * If payload is more than the threshold, 77 * use RDMA read/write through memory registration for I/O. 78 */ 79 int rdma_readwrite_threshold; 80 enum ib_mr_type mr_type; 81 struct list_head mr_list; 82 spinlock_t mr_list_lock; 83 /* The number of available MRs ready for memory registration */ 84 atomic_t mr_ready_count; 85 atomic_t mr_used_count; 86 wait_queue_head_t wait_mr; 87 struct work_struct mr_recovery_work; 88 /* Used by transport to wait until all MRs are returned */ 89 wait_queue_head_t wait_for_mr_cleanup; 90 91 /* Activity accounting */ 92 atomic_t send_pending; 93 wait_queue_head_t wait_send_pending; 94 wait_queue_head_t wait_post_send; 95 96 /* Receive queue */ 97 int count_receive_queue; 98 wait_queue_head_t wait_receive_queues; 99 100 bool send_immediate; 101 102 wait_queue_head_t wait_send_queue; 103 104 struct workqueue_struct *workqueue; 105 struct delayed_work idle_timer_work; 106 107 /* for debug purposes */ 108 unsigned int count_get_receive_buffer; 109 unsigned int count_put_receive_buffer; 110 unsigned int count_reassembly_queue; 111 unsigned int count_enqueue_reassembly_queue; 112 unsigned int count_dequeue_reassembly_queue; 113 unsigned int count_send_empty; 114 }; 115 116 /* Create a SMBDirect session */ 117 struct smbd_connection *smbd_get_connection( 118 struct TCP_Server_Info *server, struct sockaddr *dstaddr); 119 120 /* Reconnect SMBDirect session */ 121 int smbd_reconnect(struct TCP_Server_Info *server); 122 /* Destroy SMBDirect session */ 123 void smbd_destroy(struct TCP_Server_Info *server); 124 125 /* Interface for carrying upper layer I/O through send/recv */ 126 int smbd_recv(struct smbd_connection *info, struct msghdr *msg); 127 int smbd_send(struct TCP_Server_Info *server, 128 int num_rqst, struct smb_rqst *rqst); 129 130 enum mr_state { 131 MR_READY, 132 MR_REGISTERED, 133 MR_INVALIDATED, 134 MR_ERROR 135 }; 136 137 struct smbd_mr { 138 struct smbd_connection *conn; 139 struct list_head list; 140 enum mr_state state; 141 struct ib_mr *mr; 142 struct sg_table sgt; 143 enum dma_data_direction dir; 144 union { 145 struct ib_reg_wr wr; 146 struct ib_send_wr inv_wr; 147 }; 148 struct ib_cqe cqe; 149 bool need_invalidate; 150 struct completion invalidate_done; 151 }; 152 153 /* Interfaces to register and deregister MR for RDMA read/write */ 154 struct smbd_mr *smbd_register_mr( 155 struct smbd_connection *info, struct iov_iter *iter, 156 bool writing, bool need_invalidate); 157 int smbd_deregister_mr(struct smbd_mr *mr); 158 159 #else 160 #define cifs_rdma_enabled(server) 0 161 struct smbd_connection {}; 162 static inline void *smbd_get_connection( 163 struct TCP_Server_Info *server, struct sockaddr *dstaddr) {return NULL;} 164 static inline int smbd_reconnect(struct TCP_Server_Info *server) {return -1; } 165 static inline void smbd_destroy(struct TCP_Server_Info *server) {} 166 static inline int smbd_recv(struct smbd_connection *info, struct msghdr *msg) {return -1; } 167 static inline int smbd_send(struct TCP_Server_Info *server, int num_rqst, struct smb_rqst *rqst) {return -1; } 168 #endif 169 170 #endif 171