blob: 27453ef2181f4eb8f57f606cfddef5e1c9a2d23d [file] [log] [blame]
Long Li03bee012017-11-07 01:54:56 -07001/*
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
Long Lif1981862017-11-04 18:17:24 -070019#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
27enum keep_alive_status {
28 KEEP_ALIVE_NONE,
29 KEEP_ALIVE_PENDING,
30 KEEP_ALIVE_SENT,
31};
32
33enum smbd_connection_status {
34 SMBD_CREATED,
35 SMBD_CONNECTING,
36 SMBD_CONNECTED,
37 SMBD_NEGOTIATE_FAILED,
38 SMBD_DISCONNECTING,
39 SMBD_DISCONNECTED,
40 SMBD_DESTROYED
41};
42
43/*
44 * The context for the SMBDirect transport
45 * Everything related to the transport is here. It has several logical parts
46 * 1. RDMA related structures
47 * 2. SMBDirect connection parameters
48 * 3. Memory registrations
49 * 4. Receive and reassembly queues for data receive path
50 * 5. mempools for allocating packets
51 */
52struct smbd_connection {
53 enum smbd_connection_status transport_status;
54
55 /* RDMA related */
56 struct rdma_cm_id *id;
57 struct ib_qp_init_attr qp_attr;
58 struct ib_pd *pd;
59 struct ib_cq *send_cq, *recv_cq;
60 struct ib_device_attr dev_attr;
61 int ri_rc;
62 struct completion ri_done;
63 wait_queue_head_t conn_wait;
64 wait_queue_head_t wait_destroy;
65
66 struct completion negotiate_completion;
67 bool negotiate_done;
68
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
74 spinlock_t lock_new_credits_offered;
75 int new_credits_offered;
76
77 /* Connection parameters defined in [MS-SMBD] 3.1.1.1 */
78 int receive_credit_max;
79 int send_credit_target;
80 int max_send_size;
81 int max_fragmented_recv_size;
82 int max_fragmented_send_size;
83 int max_receive_size;
84 int keep_alive_interval;
85 int max_readwrite_size;
86 enum keep_alive_status keep_alive_requested;
87 int protocol;
88 atomic_t send_credits;
89 atomic_t receive_credits;
90 int receive_credit_target;
91 int fragment_reassembly_remaining;
92
93 /* Activity accoutning */
Long Lif64b78f2017-11-22 17:38:40 -070094 /* Pending reqeusts issued from upper layer */
Long Lid649e1b2017-11-22 17:38:42 -070095 int smbd_send_pending;
96 wait_queue_head_t wait_smbd_send_pending;
97
Long Lif64b78f2017-11-22 17:38:40 -070098 int smbd_recv_pending;
99 wait_queue_head_t wait_smbd_recv_pending;
Long Lif1981862017-11-04 18:17:24 -0700100
101 atomic_t send_pending;
102 wait_queue_head_t wait_send_pending;
103 atomic_t send_payload_pending;
104 wait_queue_head_t wait_send_payload_pending;
105
106 /* Receive queue */
107 struct list_head receive_queue;
108 int count_receive_queue;
109 spinlock_t receive_queue_lock;
110
111 struct list_head empty_packet_queue;
112 int count_empty_packet_queue;
113 spinlock_t empty_packet_queue_lock;
114
115 wait_queue_head_t wait_receive_queues;
116
117 /* Reassembly queue */
118 struct list_head reassembly_queue;
119 spinlock_t reassembly_queue_lock;
120 wait_queue_head_t wait_reassembly_queue;
121
122 /* total data length of reassembly queue */
123 int reassembly_data_length;
124 int reassembly_queue_length;
125 /* the offset to first buffer in reassembly queue */
126 int first_entry_offset;
127
128 bool send_immediate;
129
130 wait_queue_head_t wait_send_queue;
131
132 /*
133 * Indicate if we have received a full packet on the connection
134 * This is used to identify the first SMBD packet of a assembled
135 * payload (SMB packet) in reassembly queue so we can return a
136 * RFC1002 length to upper layer to indicate the length of the SMB
137 * packet received
138 */
139 bool full_packet_received;
140
141 struct workqueue_struct *workqueue;
142 struct delayed_work idle_timer_work;
143 struct delayed_work send_immediate_work;
144
145 /* Memory pool for preallocating buffers */
146 /* request pool for RDMA send */
147 struct kmem_cache *request_cache;
148 mempool_t *request_mempool;
149
150 /* response pool for RDMA receive */
151 struct kmem_cache *response_cache;
152 mempool_t *response_mempool;
153
154 /* for debug purposes */
155 unsigned int count_get_receive_buffer;
156 unsigned int count_put_receive_buffer;
157 unsigned int count_reassembly_queue;
158 unsigned int count_enqueue_reassembly_queue;
159 unsigned int count_dequeue_reassembly_queue;
160 unsigned int count_send_empty;
161};
162
163enum smbd_message_type {
164 SMBD_NEGOTIATE_RESP,
165 SMBD_TRANSFER_DATA,
166};
167
168#define SMB_DIRECT_RESPONSE_REQUESTED 0x0001
169
170/* SMBD negotiation request packet [MS-SMBD] 2.2.1 */
171struct smbd_negotiate_req {
172 __le16 min_version;
173 __le16 max_version;
174 __le16 reserved;
175 __le16 credits_requested;
176 __le32 preferred_send_size;
177 __le32 max_receive_size;
178 __le32 max_fragmented_size;
179} __packed;
180
181/* SMBD negotiation response packet [MS-SMBD] 2.2.2 */
182struct smbd_negotiate_resp {
183 __le16 min_version;
184 __le16 max_version;
185 __le16 negotiated_version;
186 __le16 reserved;
187 __le16 credits_requested;
188 __le16 credits_granted;
189 __le32 status;
190 __le32 max_readwrite_size;
191 __le32 preferred_send_size;
192 __le32 max_receive_size;
193 __le32 max_fragmented_size;
194} __packed;
195
196/* SMBD data transfer packet with payload [MS-SMBD] 2.2.3 */
197struct 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
209/* The packet fields for a registered RDMA buffer */
210struct smbd_buffer_descriptor_v1 {
211 __le64 offset;
212 __le32 token;
213 __le32 length;
214} __packed;
215
Long Li03bee012017-11-07 01:54:56 -0700216/* Default maximum number of SGEs in a RDMA send/recv */
217#define SMBDIRECT_MAX_SGE 16
Long Lif1981862017-11-04 18:17:24 -0700218/* The context for a SMBD request */
219struct smbd_request {
220 struct smbd_connection *info;
221 struct ib_cqe cqe;
222
223 /* true if this request carries upper layer payload */
224 bool has_payload;
225
226 /* the SGE entries for this packet */
227 struct ib_sge sge[SMBDIRECT_MAX_SGE];
228 int num_sge;
229
230 /* SMBD packet header follows this structure */
231 u8 packet[];
232};
233
234/* The context for a SMBD response */
235struct smbd_response {
236 struct smbd_connection *info;
237 struct ib_cqe cqe;
238 struct ib_sge sge;
239
240 enum smbd_message_type type;
241
242 /* Link to receive queue or reassembly queue */
243 struct list_head list;
244
245 /* Indicate if this is the 1st packet of a payload */
246 bool first_segment;
247
248 /* SMBD packet header and payload follows this structure */
249 u8 packet[];
250};
251
Long Li399f9532017-11-17 17:26:52 -0800252/* Create a SMBDirect session */
253struct smbd_connection *smbd_get_connection(
254 struct TCP_Server_Info *server, struct sockaddr *dstaddr);
255
Long Liad57b8e2017-11-22 17:38:35 -0700256/* Reconnect SMBDirect session */
257int smbd_reconnect(struct TCP_Server_Info *server);
Long Li8ef130f2017-11-22 17:38:37 -0700258/* Destroy SMBDirect session */
259void smbd_destroy(struct smbd_connection *info);
Long Liad57b8e2017-11-22 17:38:35 -0700260
Long Lif64b78f2017-11-22 17:38:40 -0700261/* Interface for carrying upper layer I/O through send/recv */
262int smbd_recv(struct smbd_connection *info, struct msghdr *msg);
Long Lid649e1b2017-11-22 17:38:42 -0700263int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst);
Long Lif64b78f2017-11-22 17:38:40 -0700264
Long Lif1981862017-11-04 18:17:24 -0700265#else
266#define cifs_rdma_enabled(server) 0
267struct smbd_connection {};
Long Li399f9532017-11-17 17:26:52 -0800268static inline void *smbd_get_connection(
269 struct TCP_Server_Info *server, struct sockaddr *dstaddr) {return NULL;}
Long Liad57b8e2017-11-22 17:38:35 -0700270static inline int smbd_reconnect(struct TCP_Server_Info *server) {return -1; }
Long Li8ef130f2017-11-22 17:38:37 -0700271static inline void smbd_destroy(struct smbd_connection *info) {}
Long Lif64b78f2017-11-22 17:38:40 -0700272static inline int smbd_recv(struct smbd_connection *info, struct msghdr *msg) {return -1; }
Long Lid649e1b2017-11-22 17:38:42 -0700273static inline int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst) {return -1; }
Long Lif1981862017-11-04 18:17:24 -0700274#endif
275
Long Li03bee012017-11-07 01:54:56 -0700276#endif