smbdirect.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /*
  2. * Copyright (C) 2017, Microsoft Corporation.
  3. *
  4. * Author(s): Long Li <longli@microsoft.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
  14. * the GNU General Public License for more details.
  15. */
  16. #ifndef _SMBDIRECT_H
  17. #define _SMBDIRECT_H
  18. #ifdef CONFIG_CIFS_SMB_DIRECT
  19. #define cifs_rdma_enabled(server) ((server)->rdma)
  20. #include "cifsglob.h"
  21. #include <rdma/ib_verbs.h>
  22. #include <rdma/rdma_cm.h>
  23. #include <linux/mempool.h>
  24. extern int rdma_readwrite_threshold;
  25. extern int smbd_max_frmr_depth;
  26. extern int smbd_keep_alive_interval;
  27. extern int smbd_max_receive_size;
  28. extern int smbd_max_fragmented_recv_size;
  29. extern int smbd_max_send_size;
  30. extern int smbd_send_credit_target;
  31. extern int smbd_receive_credit_max;
  32. enum keep_alive_status {
  33. KEEP_ALIVE_NONE,
  34. KEEP_ALIVE_PENDING,
  35. KEEP_ALIVE_SENT,
  36. };
  37. enum smbd_connection_status {
  38. SMBD_CREATED,
  39. SMBD_CONNECTING,
  40. SMBD_CONNECTED,
  41. SMBD_NEGOTIATE_FAILED,
  42. SMBD_DISCONNECTING,
  43. SMBD_DISCONNECTED,
  44. SMBD_DESTROYED
  45. };
  46. /*
  47. * The context for the SMBDirect transport
  48. * Everything related to the transport is here. It has several logical parts
  49. * 1. RDMA related structures
  50. * 2. SMBDirect connection parameters
  51. * 3. Memory registrations
  52. * 4. Receive and reassembly queues for data receive path
  53. * 5. mempools for allocating packets
  54. */
  55. struct smbd_connection {
  56. enum smbd_connection_status transport_status;
  57. /* RDMA related */
  58. struct rdma_cm_id *id;
  59. struct ib_qp_init_attr qp_attr;
  60. struct ib_pd *pd;
  61. struct ib_cq *send_cq, *recv_cq;
  62. struct ib_device_attr dev_attr;
  63. int ri_rc;
  64. struct completion ri_done;
  65. wait_queue_head_t conn_wait;
  66. wait_queue_head_t wait_destroy;
  67. struct completion negotiate_completion;
  68. bool negotiate_done;
  69. struct work_struct destroy_work;
  70. struct work_struct disconnect_work;
  71. struct work_struct recv_done_work;
  72. struct work_struct post_send_credits_work;
  73. spinlock_t lock_new_credits_offered;
  74. int new_credits_offered;
  75. /* Connection parameters defined in [MS-SMBD] 3.1.1.1 */
  76. int receive_credit_max;
  77. int send_credit_target;
  78. int max_send_size;
  79. int max_fragmented_recv_size;
  80. int max_fragmented_send_size;
  81. int max_receive_size;
  82. int keep_alive_interval;
  83. int max_readwrite_size;
  84. enum keep_alive_status keep_alive_requested;
  85. int protocol;
  86. atomic_t send_credits;
  87. atomic_t receive_credits;
  88. int receive_credit_target;
  89. int fragment_reassembly_remaining;
  90. /* Memory registrations */
  91. /* Maximum number of RDMA read/write outstanding on this connection */
  92. int responder_resources;
  93. /* Maximum number of SGEs in a RDMA write/read */
  94. int max_frmr_depth;
  95. /*
  96. * If payload is less than or equal to the threshold,
  97. * use RDMA send/recv to send upper layer I/O.
  98. * If payload is more than the threshold,
  99. * use RDMA read/write through memory registration for I/O.
  100. */
  101. int rdma_readwrite_threshold;
  102. enum ib_mr_type mr_type;
  103. struct list_head mr_list;
  104. spinlock_t mr_list_lock;
  105. /* The number of available MRs ready for memory registration */
  106. atomic_t mr_ready_count;
  107. atomic_t mr_used_count;
  108. wait_queue_head_t wait_mr;
  109. struct work_struct mr_recovery_work;
  110. /* Used by transport to wait until all MRs are returned */
  111. wait_queue_head_t wait_for_mr_cleanup;
  112. /* Activity accoutning */
  113. /* Pending reqeusts issued from upper layer */
  114. int smbd_send_pending;
  115. wait_queue_head_t wait_smbd_send_pending;
  116. int smbd_recv_pending;
  117. wait_queue_head_t wait_smbd_recv_pending;
  118. atomic_t send_pending;
  119. wait_queue_head_t wait_send_pending;
  120. atomic_t send_payload_pending;
  121. wait_queue_head_t wait_send_payload_pending;
  122. /* Receive queue */
  123. struct list_head receive_queue;
  124. int count_receive_queue;
  125. spinlock_t receive_queue_lock;
  126. struct list_head empty_packet_queue;
  127. int count_empty_packet_queue;
  128. spinlock_t empty_packet_queue_lock;
  129. wait_queue_head_t wait_receive_queues;
  130. /* Reassembly queue */
  131. struct list_head reassembly_queue;
  132. spinlock_t reassembly_queue_lock;
  133. wait_queue_head_t wait_reassembly_queue;
  134. /* total data length of reassembly queue */
  135. int reassembly_data_length;
  136. int reassembly_queue_length;
  137. /* the offset to first buffer in reassembly queue */
  138. int first_entry_offset;
  139. bool send_immediate;
  140. wait_queue_head_t wait_send_queue;
  141. /*
  142. * Indicate if we have received a full packet on the connection
  143. * This is used to identify the first SMBD packet of a assembled
  144. * payload (SMB packet) in reassembly queue so we can return a
  145. * RFC1002 length to upper layer to indicate the length of the SMB
  146. * packet received
  147. */
  148. bool full_packet_received;
  149. struct workqueue_struct *workqueue;
  150. struct delayed_work idle_timer_work;
  151. struct delayed_work send_immediate_work;
  152. /* Memory pool for preallocating buffers */
  153. /* request pool for RDMA send */
  154. struct kmem_cache *request_cache;
  155. mempool_t *request_mempool;
  156. /* response pool for RDMA receive */
  157. struct kmem_cache *response_cache;
  158. mempool_t *response_mempool;
  159. /* for debug purposes */
  160. unsigned int count_get_receive_buffer;
  161. unsigned int count_put_receive_buffer;
  162. unsigned int count_reassembly_queue;
  163. unsigned int count_enqueue_reassembly_queue;
  164. unsigned int count_dequeue_reassembly_queue;
  165. unsigned int count_send_empty;
  166. };
  167. enum smbd_message_type {
  168. SMBD_NEGOTIATE_RESP,
  169. SMBD_TRANSFER_DATA,
  170. };
  171. #define SMB_DIRECT_RESPONSE_REQUESTED 0x0001
  172. /* SMBD negotiation request packet [MS-SMBD] 2.2.1 */
  173. struct smbd_negotiate_req {
  174. __le16 min_version;
  175. __le16 max_version;
  176. __le16 reserved;
  177. __le16 credits_requested;
  178. __le32 preferred_send_size;
  179. __le32 max_receive_size;
  180. __le32 max_fragmented_size;
  181. } __packed;
  182. /* SMBD negotiation response packet [MS-SMBD] 2.2.2 */
  183. struct smbd_negotiate_resp {
  184. __le16 min_version;
  185. __le16 max_version;
  186. __le16 negotiated_version;
  187. __le16 reserved;
  188. __le16 credits_requested;
  189. __le16 credits_granted;
  190. __le32 status;
  191. __le32 max_readwrite_size;
  192. __le32 preferred_send_size;
  193. __le32 max_receive_size;
  194. __le32 max_fragmented_size;
  195. } __packed;
  196. /* SMBD data transfer packet with payload [MS-SMBD] 2.2.3 */
  197. struct smbd_data_transfer {
  198. __le16 credits_requested;
  199. __le16 credits_granted;
  200. __le16 flags;
  201. __le16 reserved;
  202. __le32 remaining_data_length;
  203. __le32 data_offset;
  204. __le32 data_length;
  205. __le32 padding;
  206. __u8 buffer[];
  207. } __packed;
  208. /* The packet fields for a registered RDMA buffer */
  209. struct smbd_buffer_descriptor_v1 {
  210. __le64 offset;
  211. __le32 token;
  212. __le32 length;
  213. } __packed;
  214. /* Default maximum number of SGEs in a RDMA send/recv */
  215. #define SMBDIRECT_MAX_SGE 16
  216. /* The context for a SMBD request */
  217. struct smbd_request {
  218. struct smbd_connection *info;
  219. struct ib_cqe cqe;
  220. /* true if this request carries upper layer payload */
  221. bool has_payload;
  222. /* the SGE entries for this packet */
  223. struct ib_sge sge[SMBDIRECT_MAX_SGE];
  224. int num_sge;
  225. /* SMBD packet header follows this structure */
  226. u8 packet[];
  227. };
  228. /* The context for a SMBD response */
  229. struct smbd_response {
  230. struct smbd_connection *info;
  231. struct ib_cqe cqe;
  232. struct ib_sge sge;
  233. enum smbd_message_type type;
  234. /* Link to receive queue or reassembly queue */
  235. struct list_head list;
  236. /* Indicate if this is the 1st packet of a payload */
  237. bool first_segment;
  238. /* SMBD packet header and payload follows this structure */
  239. u8 packet[];
  240. };
  241. /* Create a SMBDirect session */
  242. struct smbd_connection *smbd_get_connection(
  243. struct TCP_Server_Info *server, struct sockaddr *dstaddr);
  244. /* Reconnect SMBDirect session */
  245. int smbd_reconnect(struct TCP_Server_Info *server);
  246. /* Destroy SMBDirect session */
  247. void smbd_destroy(struct smbd_connection *info);
  248. /* Interface for carrying upper layer I/O through send/recv */
  249. int smbd_recv(struct smbd_connection *info, struct msghdr *msg);
  250. int smbd_send(struct TCP_Server_Info *server,
  251. int num_rqst, struct smb_rqst *rqst);
  252. enum mr_state {
  253. MR_READY,
  254. MR_REGISTERED,
  255. MR_INVALIDATED,
  256. MR_ERROR
  257. };
  258. struct smbd_mr {
  259. struct smbd_connection *conn;
  260. struct list_head list;
  261. enum mr_state state;
  262. struct ib_mr *mr;
  263. struct scatterlist *sgl;
  264. int sgl_count;
  265. enum dma_data_direction dir;
  266. union {
  267. struct ib_reg_wr wr;
  268. struct ib_send_wr inv_wr;
  269. };
  270. struct ib_cqe cqe;
  271. bool need_invalidate;
  272. struct completion invalidate_done;
  273. };
  274. /* Interfaces to register and deregister MR for RDMA read/write */
  275. struct smbd_mr *smbd_register_mr(
  276. struct smbd_connection *info, struct page *pages[], int num_pages,
  277. int offset, int tailsz, bool writing, bool need_invalidate);
  278. int smbd_deregister_mr(struct smbd_mr *mr);
  279. #else
  280. #define cifs_rdma_enabled(server) 0
  281. struct smbd_connection {};
  282. static inline void *smbd_get_connection(
  283. struct TCP_Server_Info *server, struct sockaddr *dstaddr) {return NULL;}
  284. static inline int smbd_reconnect(struct TCP_Server_Info *server) {return -1; }
  285. static inline void smbd_destroy(struct smbd_connection *info) {}
  286. static inline int smbd_recv(struct smbd_connection *info, struct msghdr *msg) {return -1; }
  287. static inline int smbd_send(struct TCP_Server_Info *server, int num_rqst, struct smb_rqst *rqst) {return -1; }
  288. #endif
  289. #endif