blob: c072a68e13216a062b66dc311cd6188ff12e7237 [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 */
95 int smbd_recv_pending;
96 wait_queue_head_t wait_smbd_recv_pending;
Long Lif1981862017-11-04 18:17:24 -070097
98 atomic_t send_pending;
99 wait_queue_head_t wait_send_pending;
100 atomic_t send_payload_pending;
101 wait_queue_head_t wait_send_payload_pending;
102
103 /* Receive queue */
104 struct list_head receive_queue;
105 int count_receive_queue;
106 spinlock_t receive_queue_lock;
107
108 struct list_head empty_packet_queue;
109 int count_empty_packet_queue;
110 spinlock_t empty_packet_queue_lock;
111
112 wait_queue_head_t wait_receive_queues;
113
114 /* Reassembly queue */
115 struct list_head reassembly_queue;
116 spinlock_t reassembly_queue_lock;
117 wait_queue_head_t wait_reassembly_queue;
118
119 /* total data length of reassembly queue */
120 int reassembly_data_length;
121 int reassembly_queue_length;
122 /* the offset to first buffer in reassembly queue */
123 int first_entry_offset;
124
125 bool send_immediate;
126
127 wait_queue_head_t wait_send_queue;
128
129 /*
130 * Indicate if we have received a full packet on the connection
131 * This is used to identify the first SMBD packet of a assembled
132 * payload (SMB packet) in reassembly queue so we can return a
133 * RFC1002 length to upper layer to indicate the length of the SMB
134 * packet received
135 */
136 bool full_packet_received;
137
138 struct workqueue_struct *workqueue;
139 struct delayed_work idle_timer_work;
140 struct delayed_work send_immediate_work;
141
142 /* Memory pool for preallocating buffers */
143 /* request pool for RDMA send */
144 struct kmem_cache *request_cache;
145 mempool_t *request_mempool;
146
147 /* response pool for RDMA receive */
148 struct kmem_cache *response_cache;
149 mempool_t *response_mempool;
150
151 /* for debug purposes */
152 unsigned int count_get_receive_buffer;
153 unsigned int count_put_receive_buffer;
154 unsigned int count_reassembly_queue;
155 unsigned int count_enqueue_reassembly_queue;
156 unsigned int count_dequeue_reassembly_queue;
157 unsigned int count_send_empty;
158};
159
160enum smbd_message_type {
161 SMBD_NEGOTIATE_RESP,
162 SMBD_TRANSFER_DATA,
163};
164
165#define SMB_DIRECT_RESPONSE_REQUESTED 0x0001
166
167/* SMBD negotiation request packet [MS-SMBD] 2.2.1 */
168struct smbd_negotiate_req {
169 __le16 min_version;
170 __le16 max_version;
171 __le16 reserved;
172 __le16 credits_requested;
173 __le32 preferred_send_size;
174 __le32 max_receive_size;
175 __le32 max_fragmented_size;
176} __packed;
177
178/* SMBD negotiation response packet [MS-SMBD] 2.2.2 */
179struct smbd_negotiate_resp {
180 __le16 min_version;
181 __le16 max_version;
182 __le16 negotiated_version;
183 __le16 reserved;
184 __le16 credits_requested;
185 __le16 credits_granted;
186 __le32 status;
187 __le32 max_readwrite_size;
188 __le32 preferred_send_size;
189 __le32 max_receive_size;
190 __le32 max_fragmented_size;
191} __packed;
192
193/* SMBD data transfer packet with payload [MS-SMBD] 2.2.3 */
194struct smbd_data_transfer {
195 __le16 credits_requested;
196 __le16 credits_granted;
197 __le16 flags;
198 __le16 reserved;
199 __le32 remaining_data_length;
200 __le32 data_offset;
201 __le32 data_length;
202 __le32 padding;
203 __u8 buffer[];
204} __packed;
205
206/* The packet fields for a registered RDMA buffer */
207struct smbd_buffer_descriptor_v1 {
208 __le64 offset;
209 __le32 token;
210 __le32 length;
211} __packed;
212
Long Li03bee012017-11-07 01:54:56 -0700213/* Default maximum number of SGEs in a RDMA send/recv */
214#define SMBDIRECT_MAX_SGE 16
Long Lif1981862017-11-04 18:17:24 -0700215/* The context for a SMBD request */
216struct smbd_request {
217 struct smbd_connection *info;
218 struct ib_cqe cqe;
219
220 /* true if this request carries upper layer payload */
221 bool has_payload;
222
223 /* the SGE entries for this packet */
224 struct ib_sge sge[SMBDIRECT_MAX_SGE];
225 int num_sge;
226
227 /* SMBD packet header follows this structure */
228 u8 packet[];
229};
230
231/* The context for a SMBD response */
232struct smbd_response {
233 struct smbd_connection *info;
234 struct ib_cqe cqe;
235 struct ib_sge sge;
236
237 enum smbd_message_type type;
238
239 /* Link to receive queue or reassembly queue */
240 struct list_head list;
241
242 /* Indicate if this is the 1st packet of a payload */
243 bool first_segment;
244
245 /* SMBD packet header and payload follows this structure */
246 u8 packet[];
247};
248
Long Li399f9532017-11-17 17:26:52 -0800249/* Create a SMBDirect session */
250struct smbd_connection *smbd_get_connection(
251 struct TCP_Server_Info *server, struct sockaddr *dstaddr);
252
Long Liad57b8e2017-11-22 17:38:35 -0700253/* Reconnect SMBDirect session */
254int smbd_reconnect(struct TCP_Server_Info *server);
Long Li8ef130f2017-11-22 17:38:37 -0700255/* Destroy SMBDirect session */
256void smbd_destroy(struct smbd_connection *info);
Long Liad57b8e2017-11-22 17:38:35 -0700257
Long Lif64b78f2017-11-22 17:38:40 -0700258/* Interface for carrying upper layer I/O through send/recv */
259int smbd_recv(struct smbd_connection *info, struct msghdr *msg);
260
Long Lif1981862017-11-04 18:17:24 -0700261#else
262#define cifs_rdma_enabled(server) 0
263struct smbd_connection {};
Long Li399f9532017-11-17 17:26:52 -0800264static inline void *smbd_get_connection(
265 struct TCP_Server_Info *server, struct sockaddr *dstaddr) {return NULL;}
Long Liad57b8e2017-11-22 17:38:35 -0700266static inline int smbd_reconnect(struct TCP_Server_Info *server) {return -1; }
Long Li8ef130f2017-11-22 17:38:37 -0700267static inline void smbd_destroy(struct smbd_connection *info) {}
Long Lif64b78f2017-11-22 17:38:40 -0700268static inline int smbd_recv(struct smbd_connection *info, struct msghdr *msg) {return -1; }
Long Lif1981862017-11-04 18:17:24 -0700269#endif
270
Long Li03bee012017-11-07 01:54:56 -0700271#endif