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