xref: /linux/fs/smb/smbdirect/socket.h (revision 0fc8f6200d2313278fbf4539bbab74677c685531)
1*1249c01aSStefan Metzmacher /* SPDX-License-Identifier: GPL-2.0-or-later */
2*1249c01aSStefan Metzmacher /*
3*1249c01aSStefan Metzmacher  *   Copyright (c) 2025 Stefan Metzmacher
4*1249c01aSStefan Metzmacher  */
5*1249c01aSStefan Metzmacher 
6*1249c01aSStefan Metzmacher #ifndef __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__
7*1249c01aSStefan Metzmacher #define __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__
8*1249c01aSStefan Metzmacher 
9*1249c01aSStefan Metzmacher #include <linux/wait.h>
10*1249c01aSStefan Metzmacher #include <linux/workqueue.h>
11*1249c01aSStefan Metzmacher #include <linux/kref.h>
12*1249c01aSStefan Metzmacher #include <linux/mempool.h>
13*1249c01aSStefan Metzmacher #include <linux/spinlock.h>
14*1249c01aSStefan Metzmacher #include <linux/mutex.h>
15*1249c01aSStefan Metzmacher #include <linux/completion.h>
16*1249c01aSStefan Metzmacher #include <rdma/rw.h>
17*1249c01aSStefan Metzmacher 
18*1249c01aSStefan Metzmacher enum smbdirect_socket_status {
19*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_CREATED,
20*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_LISTENING,
21*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_RESOLVE_ADDR_NEEDED,
22*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING,
23*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED,
24*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED,
25*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING,
26*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED,
27*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED,
28*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING,
29*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED,
30*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_NEGOTIATE_NEEDED,
31*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_NEGOTIATE_RUNNING,
32*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_NEGOTIATE_FAILED,
33*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_CONNECTED,
34*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_ERROR,
35*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_DISCONNECTING,
36*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_DISCONNECTED,
37*1249c01aSStefan Metzmacher 	SMBDIRECT_SOCKET_DESTROYED
38*1249c01aSStefan Metzmacher };
39*1249c01aSStefan Metzmacher 
40*1249c01aSStefan Metzmacher static __always_inline
41*1249c01aSStefan Metzmacher const char *smbdirect_socket_status_string(enum smbdirect_socket_status status)
42*1249c01aSStefan Metzmacher {
43*1249c01aSStefan Metzmacher 	switch (status) {
44*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_CREATED:
45*1249c01aSStefan Metzmacher 		return "CREATED";
46*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_LISTENING:
47*1249c01aSStefan Metzmacher 		return "LISTENING";
48*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_RESOLVE_ADDR_NEEDED:
49*1249c01aSStefan Metzmacher 		return "RESOLVE_ADDR_NEEDED";
50*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING:
51*1249c01aSStefan Metzmacher 		return "RESOLVE_ADDR_RUNNING";
52*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED:
53*1249c01aSStefan Metzmacher 		return "RESOLVE_ADDR_FAILED";
54*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED:
55*1249c01aSStefan Metzmacher 		return "RESOLVE_ROUTE_NEEDED";
56*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING:
57*1249c01aSStefan Metzmacher 		return "RESOLVE_ROUTE_RUNNING";
58*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED:
59*1249c01aSStefan Metzmacher 		return "RESOLVE_ROUTE_FAILED";
60*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED:
61*1249c01aSStefan Metzmacher 		return "RDMA_CONNECT_NEEDED";
62*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING:
63*1249c01aSStefan Metzmacher 		return "RDMA_CONNECT_RUNNING";
64*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED:
65*1249c01aSStefan Metzmacher 		return "RDMA_CONNECT_FAILED";
66*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_NEGOTIATE_NEEDED:
67*1249c01aSStefan Metzmacher 		return "NEGOTIATE_NEEDED";
68*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_NEGOTIATE_RUNNING:
69*1249c01aSStefan Metzmacher 		return "NEGOTIATE_RUNNING";
70*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_NEGOTIATE_FAILED:
71*1249c01aSStefan Metzmacher 		return "NEGOTIATE_FAILED";
72*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_CONNECTED:
73*1249c01aSStefan Metzmacher 		return "CONNECTED";
74*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_ERROR:
75*1249c01aSStefan Metzmacher 		return "ERROR";
76*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_DISCONNECTING:
77*1249c01aSStefan Metzmacher 		return "DISCONNECTING";
78*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_DISCONNECTED:
79*1249c01aSStefan Metzmacher 		return "DISCONNECTED";
80*1249c01aSStefan Metzmacher 	case SMBDIRECT_SOCKET_DESTROYED:
81*1249c01aSStefan Metzmacher 		return "DESTROYED";
82*1249c01aSStefan Metzmacher 	}
83*1249c01aSStefan Metzmacher 
84*1249c01aSStefan Metzmacher 	return "<unknown>";
85*1249c01aSStefan Metzmacher }
86*1249c01aSStefan Metzmacher 
87*1249c01aSStefan Metzmacher /*
88*1249c01aSStefan Metzmacher  * This can be used with %1pe to print errors as strings or '0'
89*1249c01aSStefan Metzmacher  * And it avoids warnings like: warn: passing zero to 'ERR_PTR'
90*1249c01aSStefan Metzmacher  * from smatch -p=kernel --pedantic
91*1249c01aSStefan Metzmacher  */
92*1249c01aSStefan Metzmacher static __always_inline
93*1249c01aSStefan Metzmacher const void * __must_check SMBDIRECT_DEBUG_ERR_PTR(long error)
94*1249c01aSStefan Metzmacher {
95*1249c01aSStefan Metzmacher 	if (error == 0)
96*1249c01aSStefan Metzmacher 		return NULL;
97*1249c01aSStefan Metzmacher 	return ERR_PTR(error);
98*1249c01aSStefan Metzmacher }
99*1249c01aSStefan Metzmacher 
100*1249c01aSStefan Metzmacher enum smbdirect_keepalive_status {
101*1249c01aSStefan Metzmacher 	SMBDIRECT_KEEPALIVE_NONE,
102*1249c01aSStefan Metzmacher 	SMBDIRECT_KEEPALIVE_PENDING,
103*1249c01aSStefan Metzmacher 	SMBDIRECT_KEEPALIVE_SENT
104*1249c01aSStefan Metzmacher };
105*1249c01aSStefan Metzmacher 
106*1249c01aSStefan Metzmacher struct smbdirect_socket {
107*1249c01aSStefan Metzmacher 	enum smbdirect_socket_status status;
108*1249c01aSStefan Metzmacher 	wait_queue_head_t status_wait;
109*1249c01aSStefan Metzmacher 	int first_error;
110*1249c01aSStefan Metzmacher 
111*1249c01aSStefan Metzmacher 	/*
112*1249c01aSStefan Metzmacher 	 * This points to the workqueues to
113*1249c01aSStefan Metzmacher 	 * be used for this socket.
114*1249c01aSStefan Metzmacher 	 */
115*1249c01aSStefan Metzmacher 	struct {
116*1249c01aSStefan Metzmacher 		struct workqueue_struct *accept;
117*1249c01aSStefan Metzmacher 		struct workqueue_struct *connect;
118*1249c01aSStefan Metzmacher 		struct workqueue_struct *idle;
119*1249c01aSStefan Metzmacher 		struct workqueue_struct *refill;
120*1249c01aSStefan Metzmacher 		struct workqueue_struct *immediate;
121*1249c01aSStefan Metzmacher 		struct workqueue_struct *cleanup;
122*1249c01aSStefan Metzmacher 	} workqueues;
123*1249c01aSStefan Metzmacher 
124*1249c01aSStefan Metzmacher 	struct work_struct disconnect_work;
125*1249c01aSStefan Metzmacher 
126*1249c01aSStefan Metzmacher 	/*
127*1249c01aSStefan Metzmacher 	 * The reference counts.
128*1249c01aSStefan Metzmacher 	 */
129*1249c01aSStefan Metzmacher 	struct {
130*1249c01aSStefan Metzmacher 		/*
131*1249c01aSStefan Metzmacher 		 * This holds the references by the
132*1249c01aSStefan Metzmacher 		 * frontend, typically the smb layer.
133*1249c01aSStefan Metzmacher 		 *
134*1249c01aSStefan Metzmacher 		 * It is typically 1 and a disconnect
135*1249c01aSStefan Metzmacher 		 * will happen if it reaches 0.
136*1249c01aSStefan Metzmacher 		 */
137*1249c01aSStefan Metzmacher 		struct kref disconnect;
138*1249c01aSStefan Metzmacher 
139*1249c01aSStefan Metzmacher 		/*
140*1249c01aSStefan Metzmacher 		 * This holds the reference by the
141*1249c01aSStefan Metzmacher 		 * backend, the code that manages
142*1249c01aSStefan Metzmacher 		 * the lifetime of the whole
143*1249c01aSStefan Metzmacher 		 * struct smbdirect_socket,
144*1249c01aSStefan Metzmacher 		 * if this reaches 0 it can will
145*1249c01aSStefan Metzmacher 		 * be freed.
146*1249c01aSStefan Metzmacher 		 *
147*1249c01aSStefan Metzmacher 		 * Can be REFCOUNT_MAX is part
148*1249c01aSStefan Metzmacher 		 * of another structure.
149*1249c01aSStefan Metzmacher 		 *
150*1249c01aSStefan Metzmacher 		 * This is equal or higher than
151*1249c01aSStefan Metzmacher 		 * the disconnect refcount.
152*1249c01aSStefan Metzmacher 		 */
153*1249c01aSStefan Metzmacher 		struct kref destroy;
154*1249c01aSStefan Metzmacher 	} refs;
155*1249c01aSStefan Metzmacher 
156*1249c01aSStefan Metzmacher 	/* RDMA related */
157*1249c01aSStefan Metzmacher 	struct {
158*1249c01aSStefan Metzmacher 		struct rdma_cm_id *cm_id;
159*1249c01aSStefan Metzmacher 		/*
160*1249c01aSStefan Metzmacher 		 * The expected event in our current
161*1249c01aSStefan Metzmacher 		 * cm_id->event_handler, all other events
162*1249c01aSStefan Metzmacher 		 * are treated as an error.
163*1249c01aSStefan Metzmacher 		 */
164*1249c01aSStefan Metzmacher 		enum rdma_cm_event_type expected_event;
165*1249c01aSStefan Metzmacher 		/*
166*1249c01aSStefan Metzmacher 		 * This is for iWarp MPA v1
167*1249c01aSStefan Metzmacher 		 */
168*1249c01aSStefan Metzmacher 		bool legacy_iwarp;
169*1249c01aSStefan Metzmacher 	} rdma;
170*1249c01aSStefan Metzmacher 
171*1249c01aSStefan Metzmacher 	/* IB verbs related */
172*1249c01aSStefan Metzmacher 	struct {
173*1249c01aSStefan Metzmacher 		struct ib_pd *pd;
174*1249c01aSStefan Metzmacher 		enum ib_poll_context poll_ctx;
175*1249c01aSStefan Metzmacher 		struct ib_cq *send_cq;
176*1249c01aSStefan Metzmacher 		struct ib_cq *recv_cq;
177*1249c01aSStefan Metzmacher 
178*1249c01aSStefan Metzmacher 		/*
179*1249c01aSStefan Metzmacher 		 * shortcuts for rdma.cm_id->{qp,device};
180*1249c01aSStefan Metzmacher 		 */
181*1249c01aSStefan Metzmacher 		struct ib_qp *qp;
182*1249c01aSStefan Metzmacher 		struct ib_device *dev;
183*1249c01aSStefan Metzmacher 	} ib;
184*1249c01aSStefan Metzmacher 
185*1249c01aSStefan Metzmacher 	struct smbdirect_socket_parameters parameters;
186*1249c01aSStefan Metzmacher 
187*1249c01aSStefan Metzmacher 	/*
188*1249c01aSStefan Metzmacher 	 * The state for connect/negotiation
189*1249c01aSStefan Metzmacher 	 */
190*1249c01aSStefan Metzmacher 	struct {
191*1249c01aSStefan Metzmacher 		spinlock_t lock;
192*1249c01aSStefan Metzmacher 		struct work_struct work;
193*1249c01aSStefan Metzmacher 	} connect;
194*1249c01aSStefan Metzmacher 
195*1249c01aSStefan Metzmacher 	/*
196*1249c01aSStefan Metzmacher 	 * The state for keepalive and timeout handling
197*1249c01aSStefan Metzmacher 	 */
198*1249c01aSStefan Metzmacher 	struct {
199*1249c01aSStefan Metzmacher 		enum smbdirect_keepalive_status keepalive;
200*1249c01aSStefan Metzmacher 		struct work_struct immediate_work;
201*1249c01aSStefan Metzmacher 		struct delayed_work timer_work;
202*1249c01aSStefan Metzmacher 	} idle;
203*1249c01aSStefan Metzmacher 
204*1249c01aSStefan Metzmacher 	/*
205*1249c01aSStefan Metzmacher 	 * The state for listen sockets
206*1249c01aSStefan Metzmacher 	 */
207*1249c01aSStefan Metzmacher 	struct {
208*1249c01aSStefan Metzmacher 		spinlock_t lock;
209*1249c01aSStefan Metzmacher 		struct list_head pending;
210*1249c01aSStefan Metzmacher 		struct list_head ready;
211*1249c01aSStefan Metzmacher 		wait_queue_head_t wait_queue;
212*1249c01aSStefan Metzmacher 		/*
213*1249c01aSStefan Metzmacher 		 * This starts as -1 and a value != -1
214*1249c01aSStefan Metzmacher 		 * means this socket was in LISTENING state
215*1249c01aSStefan Metzmacher 		 * before. Note the valid backlog can
216*1249c01aSStefan Metzmacher 		 * only be > 0.
217*1249c01aSStefan Metzmacher 		 */
218*1249c01aSStefan Metzmacher 		int backlog;
219*1249c01aSStefan Metzmacher 	} listen;
220*1249c01aSStefan Metzmacher 
221*1249c01aSStefan Metzmacher 	/*
222*1249c01aSStefan Metzmacher 	 * The state for sockets waiting
223*1249c01aSStefan Metzmacher 	 * for accept, either still waiting
224*1249c01aSStefan Metzmacher 	 * for the negotiation to finish
225*1249c01aSStefan Metzmacher 	 * or already ready with a usable
226*1249c01aSStefan Metzmacher 	 * connection.
227*1249c01aSStefan Metzmacher 	 */
228*1249c01aSStefan Metzmacher 	struct {
229*1249c01aSStefan Metzmacher 		struct smbdirect_socket *listener;
230*1249c01aSStefan Metzmacher 		struct list_head list;
231*1249c01aSStefan Metzmacher 	} accept;
232*1249c01aSStefan Metzmacher 
233*1249c01aSStefan Metzmacher 	/*
234*1249c01aSStefan Metzmacher 	 * The state for posted send buffers
235*1249c01aSStefan Metzmacher 	 */
236*1249c01aSStefan Metzmacher 	struct {
237*1249c01aSStefan Metzmacher 		/*
238*1249c01aSStefan Metzmacher 		 * Memory pools for preallocating
239*1249c01aSStefan Metzmacher 		 * smbdirect_send_io buffers
240*1249c01aSStefan Metzmacher 		 */
241*1249c01aSStefan Metzmacher 		struct {
242*1249c01aSStefan Metzmacher 			struct kmem_cache *cache;
243*1249c01aSStefan Metzmacher 			mempool_t *pool;
244*1249c01aSStefan Metzmacher 			gfp_t gfp_mask;
245*1249c01aSStefan Metzmacher 		} mem;
246*1249c01aSStefan Metzmacher 
247*1249c01aSStefan Metzmacher 		/*
248*1249c01aSStefan Metzmacher 		 * This is a coordination for smbdirect_send_batch.
249*1249c01aSStefan Metzmacher 		 *
250*1249c01aSStefan Metzmacher 		 * There's only one possible credit, which means
251*1249c01aSStefan Metzmacher 		 * only one instance is running at a time.
252*1249c01aSStefan Metzmacher 		 */
253*1249c01aSStefan Metzmacher 		struct {
254*1249c01aSStefan Metzmacher 			atomic_t count;
255*1249c01aSStefan Metzmacher 			wait_queue_head_t wait_queue;
256*1249c01aSStefan Metzmacher 		} bcredits;
257*1249c01aSStefan Metzmacher 
258*1249c01aSStefan Metzmacher 		/*
259*1249c01aSStefan Metzmacher 		 * The local credit state for ib_post_send()
260*1249c01aSStefan Metzmacher 		 */
261*1249c01aSStefan Metzmacher 		struct {
262*1249c01aSStefan Metzmacher 			atomic_t count;
263*1249c01aSStefan Metzmacher 			wait_queue_head_t wait_queue;
264*1249c01aSStefan Metzmacher 		} lcredits;
265*1249c01aSStefan Metzmacher 
266*1249c01aSStefan Metzmacher 		/*
267*1249c01aSStefan Metzmacher 		 * The remote credit state for the send side
268*1249c01aSStefan Metzmacher 		 */
269*1249c01aSStefan Metzmacher 		struct {
270*1249c01aSStefan Metzmacher 			atomic_t count;
271*1249c01aSStefan Metzmacher 			wait_queue_head_t wait_queue;
272*1249c01aSStefan Metzmacher 		} credits;
273*1249c01aSStefan Metzmacher 
274*1249c01aSStefan Metzmacher 		/*
275*1249c01aSStefan Metzmacher 		 * The state about posted/pending sends
276*1249c01aSStefan Metzmacher 		 */
277*1249c01aSStefan Metzmacher 		struct {
278*1249c01aSStefan Metzmacher 			atomic_t count;
279*1249c01aSStefan Metzmacher 			/*
280*1249c01aSStefan Metzmacher 			 * woken when count reached zero
281*1249c01aSStefan Metzmacher 			 */
282*1249c01aSStefan Metzmacher 			wait_queue_head_t zero_wait_queue;
283*1249c01aSStefan Metzmacher 		} pending;
284*1249c01aSStefan Metzmacher 	} send_io;
285*1249c01aSStefan Metzmacher 
286*1249c01aSStefan Metzmacher 	/*
287*1249c01aSStefan Metzmacher 	 * The state for posted receive buffers
288*1249c01aSStefan Metzmacher 	 */
289*1249c01aSStefan Metzmacher 	struct {
290*1249c01aSStefan Metzmacher 		/*
291*1249c01aSStefan Metzmacher 		 * The type of PDU we are expecting
292*1249c01aSStefan Metzmacher 		 */
293*1249c01aSStefan Metzmacher 		enum {
294*1249c01aSStefan Metzmacher 			SMBDIRECT_EXPECT_NEGOTIATE_REQ = 1,
295*1249c01aSStefan Metzmacher 			SMBDIRECT_EXPECT_NEGOTIATE_REP = 2,
296*1249c01aSStefan Metzmacher 			SMBDIRECT_EXPECT_DATA_TRANSFER = 3,
297*1249c01aSStefan Metzmacher 		} expected;
298*1249c01aSStefan Metzmacher 
299*1249c01aSStefan Metzmacher 		/*
300*1249c01aSStefan Metzmacher 		 * Memory pools for preallocating
301*1249c01aSStefan Metzmacher 		 * smbdirect_recv_io buffers
302*1249c01aSStefan Metzmacher 		 */
303*1249c01aSStefan Metzmacher 		struct {
304*1249c01aSStefan Metzmacher 			struct kmem_cache *cache;
305*1249c01aSStefan Metzmacher 			mempool_t *pool;
306*1249c01aSStefan Metzmacher 			gfp_t gfp_mask;
307*1249c01aSStefan Metzmacher 		} mem;
308*1249c01aSStefan Metzmacher 
309*1249c01aSStefan Metzmacher 		/*
310*1249c01aSStefan Metzmacher 		 * The list of free smbdirect_recv_io
311*1249c01aSStefan Metzmacher 		 * structures
312*1249c01aSStefan Metzmacher 		 */
313*1249c01aSStefan Metzmacher 		struct {
314*1249c01aSStefan Metzmacher 			struct list_head list;
315*1249c01aSStefan Metzmacher 			spinlock_t lock;
316*1249c01aSStefan Metzmacher 		} free;
317*1249c01aSStefan Metzmacher 
318*1249c01aSStefan Metzmacher 		/*
319*1249c01aSStefan Metzmacher 		 * The state for posted recv_io messages
320*1249c01aSStefan Metzmacher 		 * and the refill work struct.
321*1249c01aSStefan Metzmacher 		 */
322*1249c01aSStefan Metzmacher 		struct {
323*1249c01aSStefan Metzmacher 			atomic_t count;
324*1249c01aSStefan Metzmacher 			struct work_struct refill_work;
325*1249c01aSStefan Metzmacher 		} posted;
326*1249c01aSStefan Metzmacher 
327*1249c01aSStefan Metzmacher 		/*
328*1249c01aSStefan Metzmacher 		 * The credit state for the recv side
329*1249c01aSStefan Metzmacher 		 */
330*1249c01aSStefan Metzmacher 		struct {
331*1249c01aSStefan Metzmacher 			u16 target;
332*1249c01aSStefan Metzmacher 			atomic_t available;
333*1249c01aSStefan Metzmacher 			atomic_t count;
334*1249c01aSStefan Metzmacher 		} credits;
335*1249c01aSStefan Metzmacher 
336*1249c01aSStefan Metzmacher 		/*
337*1249c01aSStefan Metzmacher 		 * The list of arrived non-empty smbdirect_recv_io
338*1249c01aSStefan Metzmacher 		 * structures
339*1249c01aSStefan Metzmacher 		 *
340*1249c01aSStefan Metzmacher 		 * This represents the reassembly queue.
341*1249c01aSStefan Metzmacher 		 */
342*1249c01aSStefan Metzmacher 		struct {
343*1249c01aSStefan Metzmacher 			struct list_head list;
344*1249c01aSStefan Metzmacher 			spinlock_t lock;
345*1249c01aSStefan Metzmacher 			wait_queue_head_t wait_queue;
346*1249c01aSStefan Metzmacher 			/* total data length of reassembly queue */
347*1249c01aSStefan Metzmacher 			int data_length;
348*1249c01aSStefan Metzmacher 			int queue_length;
349*1249c01aSStefan Metzmacher 			/* the offset to first buffer in reassembly queue */
350*1249c01aSStefan Metzmacher 			int first_entry_offset;
351*1249c01aSStefan Metzmacher 			/*
352*1249c01aSStefan Metzmacher 			 * Indicate if we have received a full packet on the
353*1249c01aSStefan Metzmacher 			 * connection This is used to identify the first SMBD
354*1249c01aSStefan Metzmacher 			 * packet of a assembled payload (SMB packet) in
355*1249c01aSStefan Metzmacher 			 * reassembly queue so we can return a RFC1002 length to
356*1249c01aSStefan Metzmacher 			 * upper layer to indicate the length of the SMB packet
357*1249c01aSStefan Metzmacher 			 * received
358*1249c01aSStefan Metzmacher 			 */
359*1249c01aSStefan Metzmacher 			bool full_packet_received;
360*1249c01aSStefan Metzmacher 		} reassembly;
361*1249c01aSStefan Metzmacher 	} recv_io;
362*1249c01aSStefan Metzmacher 
363*1249c01aSStefan Metzmacher 	/*
364*1249c01aSStefan Metzmacher 	 * The state for Memory registrations on the client
365*1249c01aSStefan Metzmacher 	 */
366*1249c01aSStefan Metzmacher 	struct {
367*1249c01aSStefan Metzmacher 		enum ib_mr_type type;
368*1249c01aSStefan Metzmacher 
369*1249c01aSStefan Metzmacher 		/*
370*1249c01aSStefan Metzmacher 		 * The list of free smbdirect_mr_io
371*1249c01aSStefan Metzmacher 		 * structures
372*1249c01aSStefan Metzmacher 		 */
373*1249c01aSStefan Metzmacher 		struct {
374*1249c01aSStefan Metzmacher 			struct list_head list;
375*1249c01aSStefan Metzmacher 			spinlock_t lock;
376*1249c01aSStefan Metzmacher 		} all;
377*1249c01aSStefan Metzmacher 
378*1249c01aSStefan Metzmacher 		/*
379*1249c01aSStefan Metzmacher 		 * The number of available MRs ready for memory registration
380*1249c01aSStefan Metzmacher 		 */
381*1249c01aSStefan Metzmacher 		struct {
382*1249c01aSStefan Metzmacher 			atomic_t count;
383*1249c01aSStefan Metzmacher 			wait_queue_head_t wait_queue;
384*1249c01aSStefan Metzmacher 		} ready;
385*1249c01aSStefan Metzmacher 
386*1249c01aSStefan Metzmacher 		/*
387*1249c01aSStefan Metzmacher 		 * The number of used MRs
388*1249c01aSStefan Metzmacher 		 */
389*1249c01aSStefan Metzmacher 		struct {
390*1249c01aSStefan Metzmacher 			atomic_t count;
391*1249c01aSStefan Metzmacher 		} used;
392*1249c01aSStefan Metzmacher 	} mr_io;
393*1249c01aSStefan Metzmacher 
394*1249c01aSStefan Metzmacher 	/*
395*1249c01aSStefan Metzmacher 	 * The state for RDMA read/write requests on the server
396*1249c01aSStefan Metzmacher 	 */
397*1249c01aSStefan Metzmacher 	struct {
398*1249c01aSStefan Metzmacher 		/*
399*1249c01aSStefan Metzmacher 		 * Memory hints for
400*1249c01aSStefan Metzmacher 		 * smbdirect_rw_io structs
401*1249c01aSStefan Metzmacher 		 */
402*1249c01aSStefan Metzmacher 		struct {
403*1249c01aSStefan Metzmacher 			gfp_t gfp_mask;
404*1249c01aSStefan Metzmacher 		} mem;
405*1249c01aSStefan Metzmacher 
406*1249c01aSStefan Metzmacher 		/*
407*1249c01aSStefan Metzmacher 		 * The credit state for the send side
408*1249c01aSStefan Metzmacher 		 */
409*1249c01aSStefan Metzmacher 		struct {
410*1249c01aSStefan Metzmacher 			/*
411*1249c01aSStefan Metzmacher 			 * The maximum number of rw credits
412*1249c01aSStefan Metzmacher 			 */
413*1249c01aSStefan Metzmacher 			size_t max;
414*1249c01aSStefan Metzmacher 			/*
415*1249c01aSStefan Metzmacher 			 * The number of pages per credit
416*1249c01aSStefan Metzmacher 			 */
417*1249c01aSStefan Metzmacher 			size_t num_pages;
418*1249c01aSStefan Metzmacher 			atomic_t count;
419*1249c01aSStefan Metzmacher 			wait_queue_head_t wait_queue;
420*1249c01aSStefan Metzmacher 		} credits;
421*1249c01aSStefan Metzmacher 	} rw_io;
422*1249c01aSStefan Metzmacher 
423*1249c01aSStefan Metzmacher 	/*
424*1249c01aSStefan Metzmacher 	 * For debug purposes
425*1249c01aSStefan Metzmacher 	 */
426*1249c01aSStefan Metzmacher 	struct {
427*1249c01aSStefan Metzmacher 		u64 get_receive_buffer;
428*1249c01aSStefan Metzmacher 		u64 put_receive_buffer;
429*1249c01aSStefan Metzmacher 		u64 enqueue_reassembly_queue;
430*1249c01aSStefan Metzmacher 		u64 dequeue_reassembly_queue;
431*1249c01aSStefan Metzmacher 		u64 send_empty;
432*1249c01aSStefan Metzmacher 	} statistics;
433*1249c01aSStefan Metzmacher 
434*1249c01aSStefan Metzmacher 	struct {
435*1249c01aSStefan Metzmacher 		void *private_ptr;
436*1249c01aSStefan Metzmacher 		bool (*needed)(struct smbdirect_socket *sc,
437*1249c01aSStefan Metzmacher 			       void *private_ptr,
438*1249c01aSStefan Metzmacher 			       unsigned int lvl,
439*1249c01aSStefan Metzmacher 			       unsigned int cls);
440*1249c01aSStefan Metzmacher 		void (*vaprintf)(struct smbdirect_socket *sc,
441*1249c01aSStefan Metzmacher 				 const char *func,
442*1249c01aSStefan Metzmacher 				 unsigned int line,
443*1249c01aSStefan Metzmacher 				 void *private_ptr,
444*1249c01aSStefan Metzmacher 				 unsigned int lvl,
445*1249c01aSStefan Metzmacher 				 unsigned int cls,
446*1249c01aSStefan Metzmacher 				 struct va_format *vaf);
447*1249c01aSStefan Metzmacher 	} logging;
448*1249c01aSStefan Metzmacher };
449*1249c01aSStefan Metzmacher 
450*1249c01aSStefan Metzmacher static void __smbdirect_socket_disabled_work(struct work_struct *work)
451*1249c01aSStefan Metzmacher {
452*1249c01aSStefan Metzmacher 	/*
453*1249c01aSStefan Metzmacher 	 * Should never be called as disable_[delayed_]work_sync() was used.
454*1249c01aSStefan Metzmacher 	 */
455*1249c01aSStefan Metzmacher 	WARN_ON_ONCE(1);
456*1249c01aSStefan Metzmacher }
457*1249c01aSStefan Metzmacher 
458*1249c01aSStefan Metzmacher static bool __smbdirect_log_needed(struct smbdirect_socket *sc,
459*1249c01aSStefan Metzmacher 				   void *private_ptr,
460*1249c01aSStefan Metzmacher 				   unsigned int lvl,
461*1249c01aSStefan Metzmacher 				   unsigned int cls)
462*1249c01aSStefan Metzmacher {
463*1249c01aSStefan Metzmacher 	/*
464*1249c01aSStefan Metzmacher 	 * Should never be called, the caller should
465*1249c01aSStefan Metzmacher 	 * set it's own functions.
466*1249c01aSStefan Metzmacher 	 */
467*1249c01aSStefan Metzmacher 	WARN_ON_ONCE(1);
468*1249c01aSStefan Metzmacher 	return false;
469*1249c01aSStefan Metzmacher }
470*1249c01aSStefan Metzmacher 
471*1249c01aSStefan Metzmacher static void __smbdirect_log_vaprintf(struct smbdirect_socket *sc,
472*1249c01aSStefan Metzmacher 				     const char *func,
473*1249c01aSStefan Metzmacher 				     unsigned int line,
474*1249c01aSStefan Metzmacher 				     void *private_ptr,
475*1249c01aSStefan Metzmacher 				     unsigned int lvl,
476*1249c01aSStefan Metzmacher 				     unsigned int cls,
477*1249c01aSStefan Metzmacher 				     struct va_format *vaf)
478*1249c01aSStefan Metzmacher {
479*1249c01aSStefan Metzmacher 	/*
480*1249c01aSStefan Metzmacher 	 * Should never be called, the caller should
481*1249c01aSStefan Metzmacher 	 * set it's own functions.
482*1249c01aSStefan Metzmacher 	 */
483*1249c01aSStefan Metzmacher 	WARN_ON_ONCE(1);
484*1249c01aSStefan Metzmacher }
485*1249c01aSStefan Metzmacher 
486*1249c01aSStefan Metzmacher __printf(6, 7)
487*1249c01aSStefan Metzmacher static void __smbdirect_log_printf(struct smbdirect_socket *sc,
488*1249c01aSStefan Metzmacher 				   const char *func,
489*1249c01aSStefan Metzmacher 				   unsigned int line,
490*1249c01aSStefan Metzmacher 				   unsigned int lvl,
491*1249c01aSStefan Metzmacher 				   unsigned int cls,
492*1249c01aSStefan Metzmacher 				   const char *fmt,
493*1249c01aSStefan Metzmacher 				   ...);
494*1249c01aSStefan Metzmacher __maybe_unused
495*1249c01aSStefan Metzmacher static void __smbdirect_log_printf(struct smbdirect_socket *sc,
496*1249c01aSStefan Metzmacher 				   const char *func,
497*1249c01aSStefan Metzmacher 				   unsigned int line,
498*1249c01aSStefan Metzmacher 				   unsigned int lvl,
499*1249c01aSStefan Metzmacher 				   unsigned int cls,
500*1249c01aSStefan Metzmacher 				   const char *fmt,
501*1249c01aSStefan Metzmacher 				   ...)
502*1249c01aSStefan Metzmacher {
503*1249c01aSStefan Metzmacher 	struct va_format vaf;
504*1249c01aSStefan Metzmacher 	va_list args;
505*1249c01aSStefan Metzmacher 
506*1249c01aSStefan Metzmacher 	va_start(args, fmt);
507*1249c01aSStefan Metzmacher 
508*1249c01aSStefan Metzmacher 	vaf.fmt = fmt;
509*1249c01aSStefan Metzmacher 	vaf.va = &args;
510*1249c01aSStefan Metzmacher 
511*1249c01aSStefan Metzmacher 	sc->logging.vaprintf(sc,
512*1249c01aSStefan Metzmacher 			     func,
513*1249c01aSStefan Metzmacher 			     line,
514*1249c01aSStefan Metzmacher 			     sc->logging.private_ptr,
515*1249c01aSStefan Metzmacher 			     lvl,
516*1249c01aSStefan Metzmacher 			     cls,
517*1249c01aSStefan Metzmacher 			     &vaf);
518*1249c01aSStefan Metzmacher 	va_end(args);
519*1249c01aSStefan Metzmacher }
520*1249c01aSStefan Metzmacher 
521*1249c01aSStefan Metzmacher #define ___smbdirect_log_generic(sc, func, line, lvl, cls, fmt, args...) do {	\
522*1249c01aSStefan Metzmacher 	if (sc->logging.needed(sc, sc->logging.private_ptr, lvl, cls)) {	\
523*1249c01aSStefan Metzmacher 		__smbdirect_log_printf(sc, func, line, lvl, cls, fmt, ##args);	\
524*1249c01aSStefan Metzmacher 	}									\
525*1249c01aSStefan Metzmacher } while (0)
526*1249c01aSStefan Metzmacher #define __smbdirect_log_generic(sc, lvl, cls, fmt, args...) \
527*1249c01aSStefan Metzmacher 	___smbdirect_log_generic(sc, __func__, __LINE__, lvl, cls, fmt, ##args)
528*1249c01aSStefan Metzmacher 
529*1249c01aSStefan Metzmacher #define smbdirect_log_outgoing(sc, lvl, fmt, args...) \
530*1249c01aSStefan Metzmacher 		__smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_OUTGOING, fmt, ##args)
531*1249c01aSStefan Metzmacher #define smbdirect_log_incoming(sc, lvl, fmt, args...) \
532*1249c01aSStefan Metzmacher 		__smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_INCOMING, fmt, ##args)
533*1249c01aSStefan Metzmacher #define smbdirect_log_read(sc, lvl, fmt, args...) \
534*1249c01aSStefan Metzmacher 		__smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_READ, fmt, ##args)
535*1249c01aSStefan Metzmacher #define smbdirect_log_write(sc, lvl, fmt, args...) \
536*1249c01aSStefan Metzmacher 		__smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_WRITE, fmt, ##args)
537*1249c01aSStefan Metzmacher #define smbdirect_log_rdma_send(sc, lvl, fmt, args...) \
538*1249c01aSStefan Metzmacher 		__smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_RDMA_SEND, fmt, ##args)
539*1249c01aSStefan Metzmacher #define smbdirect_log_rdma_recv(sc, lvl, fmt, args...) \
540*1249c01aSStefan Metzmacher 		__smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_RDMA_RECV, fmt, ##args)
541*1249c01aSStefan Metzmacher #define smbdirect_log_keep_alive(sc, lvl, fmt, args...) \
542*1249c01aSStefan Metzmacher 		__smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_KEEP_ALIVE, fmt, ##args)
543*1249c01aSStefan Metzmacher #define smbdirect_log_rdma_event(sc, lvl, fmt, args...) \
544*1249c01aSStefan Metzmacher 		__smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_RDMA_EVENT, fmt, ##args)
545*1249c01aSStefan Metzmacher #define smbdirect_log_rdma_mr(sc, lvl, fmt, args...) \
546*1249c01aSStefan Metzmacher 		__smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_RDMA_MR, fmt, ##args)
547*1249c01aSStefan Metzmacher #define smbdirect_log_rdma_rw(sc, lvl, fmt, args...) \
548*1249c01aSStefan Metzmacher 		__smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_RDMA_RW, fmt, ##args)
549*1249c01aSStefan Metzmacher #define smbdirect_log_negotiate(sc, lvl, fmt, args...) \
550*1249c01aSStefan Metzmacher 		__smbdirect_log_generic(sc, lvl, SMBDIRECT_LOG_NEGOTIATE, fmt, ##args)
551*1249c01aSStefan Metzmacher 
552*1249c01aSStefan Metzmacher static __always_inline void smbdirect_socket_init(struct smbdirect_socket *sc)
553*1249c01aSStefan Metzmacher {
554*1249c01aSStefan Metzmacher 	/*
555*1249c01aSStefan Metzmacher 	 * This also sets status = SMBDIRECT_SOCKET_CREATED
556*1249c01aSStefan Metzmacher 	 */
557*1249c01aSStefan Metzmacher 	BUILD_BUG_ON(SMBDIRECT_SOCKET_CREATED != 0);
558*1249c01aSStefan Metzmacher 	memset(sc, 0, sizeof(*sc));
559*1249c01aSStefan Metzmacher 
560*1249c01aSStefan Metzmacher 	init_waitqueue_head(&sc->status_wait);
561*1249c01aSStefan Metzmacher 
562*1249c01aSStefan Metzmacher 	sc->workqueues.accept = smbdirect_globals.workqueues.accept;
563*1249c01aSStefan Metzmacher 	sc->workqueues.connect = smbdirect_globals.workqueues.connect;
564*1249c01aSStefan Metzmacher 	sc->workqueues.idle = smbdirect_globals.workqueues.idle;
565*1249c01aSStefan Metzmacher 	sc->workqueues.refill = smbdirect_globals.workqueues.refill;
566*1249c01aSStefan Metzmacher 	sc->workqueues.immediate = smbdirect_globals.workqueues.immediate;
567*1249c01aSStefan Metzmacher 	sc->workqueues.cleanup = smbdirect_globals.workqueues.cleanup;
568*1249c01aSStefan Metzmacher 
569*1249c01aSStefan Metzmacher 	INIT_WORK(&sc->disconnect_work, __smbdirect_socket_disabled_work);
570*1249c01aSStefan Metzmacher 	disable_work_sync(&sc->disconnect_work);
571*1249c01aSStefan Metzmacher 
572*1249c01aSStefan Metzmacher 	kref_init(&sc->refs.disconnect);
573*1249c01aSStefan Metzmacher 	sc->refs.destroy = (struct kref) KREF_INIT(REFCOUNT_MAX);
574*1249c01aSStefan Metzmacher 
575*1249c01aSStefan Metzmacher 	sc->rdma.expected_event = RDMA_CM_EVENT_INTERNAL;
576*1249c01aSStefan Metzmacher 
577*1249c01aSStefan Metzmacher 	sc->ib.poll_ctx = IB_POLL_UNBOUND_WORKQUEUE;
578*1249c01aSStefan Metzmacher 
579*1249c01aSStefan Metzmacher 	spin_lock_init(&sc->connect.lock);
580*1249c01aSStefan Metzmacher 	INIT_WORK(&sc->connect.work, __smbdirect_socket_disabled_work);
581*1249c01aSStefan Metzmacher 	disable_work_sync(&sc->connect.work);
582*1249c01aSStefan Metzmacher 
583*1249c01aSStefan Metzmacher 	INIT_WORK(&sc->idle.immediate_work, __smbdirect_socket_disabled_work);
584*1249c01aSStefan Metzmacher 	disable_work_sync(&sc->idle.immediate_work);
585*1249c01aSStefan Metzmacher 	INIT_DELAYED_WORK(&sc->idle.timer_work, __smbdirect_socket_disabled_work);
586*1249c01aSStefan Metzmacher 	disable_delayed_work_sync(&sc->idle.timer_work);
587*1249c01aSStefan Metzmacher 
588*1249c01aSStefan Metzmacher 	spin_lock_init(&sc->listen.lock);
589*1249c01aSStefan Metzmacher 	INIT_LIST_HEAD(&sc->listen.pending);
590*1249c01aSStefan Metzmacher 	INIT_LIST_HEAD(&sc->listen.ready);
591*1249c01aSStefan Metzmacher 	sc->listen.backlog = -1; /* not a listener */
592*1249c01aSStefan Metzmacher 	init_waitqueue_head(&sc->listen.wait_queue);
593*1249c01aSStefan Metzmacher 
594*1249c01aSStefan Metzmacher 	INIT_LIST_HEAD(&sc->accept.list);
595*1249c01aSStefan Metzmacher 
596*1249c01aSStefan Metzmacher 	sc->send_io.mem.gfp_mask = GFP_KERNEL;
597*1249c01aSStefan Metzmacher 
598*1249c01aSStefan Metzmacher 	atomic_set(&sc->send_io.bcredits.count, 0);
599*1249c01aSStefan Metzmacher 	init_waitqueue_head(&sc->send_io.bcredits.wait_queue);
600*1249c01aSStefan Metzmacher 
601*1249c01aSStefan Metzmacher 	atomic_set(&sc->send_io.lcredits.count, 0);
602*1249c01aSStefan Metzmacher 	init_waitqueue_head(&sc->send_io.lcredits.wait_queue);
603*1249c01aSStefan Metzmacher 
604*1249c01aSStefan Metzmacher 	atomic_set(&sc->send_io.credits.count, 0);
605*1249c01aSStefan Metzmacher 	init_waitqueue_head(&sc->send_io.credits.wait_queue);
606*1249c01aSStefan Metzmacher 
607*1249c01aSStefan Metzmacher 	atomic_set(&sc->send_io.pending.count, 0);
608*1249c01aSStefan Metzmacher 	init_waitqueue_head(&sc->send_io.pending.zero_wait_queue);
609*1249c01aSStefan Metzmacher 
610*1249c01aSStefan Metzmacher 	sc->recv_io.mem.gfp_mask = GFP_KERNEL;
611*1249c01aSStefan Metzmacher 
612*1249c01aSStefan Metzmacher 	INIT_LIST_HEAD(&sc->recv_io.free.list);
613*1249c01aSStefan Metzmacher 	spin_lock_init(&sc->recv_io.free.lock);
614*1249c01aSStefan Metzmacher 
615*1249c01aSStefan Metzmacher 	atomic_set(&sc->recv_io.posted.count, 0);
616*1249c01aSStefan Metzmacher 	INIT_WORK(&sc->recv_io.posted.refill_work, __smbdirect_socket_disabled_work);
617*1249c01aSStefan Metzmacher 	disable_work_sync(&sc->recv_io.posted.refill_work);
618*1249c01aSStefan Metzmacher 
619*1249c01aSStefan Metzmacher 	atomic_set(&sc->recv_io.credits.available, 0);
620*1249c01aSStefan Metzmacher 	atomic_set(&sc->recv_io.credits.count, 0);
621*1249c01aSStefan Metzmacher 
622*1249c01aSStefan Metzmacher 	INIT_LIST_HEAD(&sc->recv_io.reassembly.list);
623*1249c01aSStefan Metzmacher 	spin_lock_init(&sc->recv_io.reassembly.lock);
624*1249c01aSStefan Metzmacher 	init_waitqueue_head(&sc->recv_io.reassembly.wait_queue);
625*1249c01aSStefan Metzmacher 
626*1249c01aSStefan Metzmacher 	sc->rw_io.mem.gfp_mask = GFP_KERNEL;
627*1249c01aSStefan Metzmacher 	atomic_set(&sc->rw_io.credits.count, 0);
628*1249c01aSStefan Metzmacher 	init_waitqueue_head(&sc->rw_io.credits.wait_queue);
629*1249c01aSStefan Metzmacher 
630*1249c01aSStefan Metzmacher 	spin_lock_init(&sc->mr_io.all.lock);
631*1249c01aSStefan Metzmacher 	INIT_LIST_HEAD(&sc->mr_io.all.list);
632*1249c01aSStefan Metzmacher 	atomic_set(&sc->mr_io.ready.count, 0);
633*1249c01aSStefan Metzmacher 	init_waitqueue_head(&sc->mr_io.ready.wait_queue);
634*1249c01aSStefan Metzmacher 	atomic_set(&sc->mr_io.used.count, 0);
635*1249c01aSStefan Metzmacher 
636*1249c01aSStefan Metzmacher 	sc->logging.private_ptr = NULL;
637*1249c01aSStefan Metzmacher 	sc->logging.needed = __smbdirect_log_needed;
638*1249c01aSStefan Metzmacher 	sc->logging.vaprintf = __smbdirect_log_vaprintf;
639*1249c01aSStefan Metzmacher }
640*1249c01aSStefan Metzmacher 
641*1249c01aSStefan Metzmacher #define __SMBDIRECT_CHECK_STATUS_FAILED(__sc, __expected_status, __error_cmd, __unexpected_cmd) ({ \
642*1249c01aSStefan Metzmacher 	bool __failed = false; \
643*1249c01aSStefan Metzmacher 	if (unlikely((__sc)->first_error)) { \
644*1249c01aSStefan Metzmacher 		__failed = true; \
645*1249c01aSStefan Metzmacher 		__error_cmd \
646*1249c01aSStefan Metzmacher 	} else if (unlikely((__sc)->status != (__expected_status))) { \
647*1249c01aSStefan Metzmacher 		__failed = true; \
648*1249c01aSStefan Metzmacher 		__unexpected_cmd \
649*1249c01aSStefan Metzmacher 	} \
650*1249c01aSStefan Metzmacher 	__failed; \
651*1249c01aSStefan Metzmacher })
652*1249c01aSStefan Metzmacher 
653*1249c01aSStefan Metzmacher #define __SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status, __unexpected_cmd) \
654*1249c01aSStefan Metzmacher 	__SMBDIRECT_CHECK_STATUS_FAILED(__sc, __expected_status, \
655*1249c01aSStefan Metzmacher 	{ \
656*1249c01aSStefan Metzmacher 		const struct sockaddr_storage *__src = NULL; \
657*1249c01aSStefan Metzmacher 		const struct sockaddr_storage *__dst = NULL; \
658*1249c01aSStefan Metzmacher 		if ((__sc)->rdma.cm_id) { \
659*1249c01aSStefan Metzmacher 			__src = &(__sc)->rdma.cm_id->route.addr.src_addr; \
660*1249c01aSStefan Metzmacher 			__dst = &(__sc)->rdma.cm_id->route.addr.dst_addr; \
661*1249c01aSStefan Metzmacher 		} \
662*1249c01aSStefan Metzmacher 		smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_INFO, \
663*1249c01aSStefan Metzmacher 			"expected[%s] != %s first_error=%1pe local=%pISpsfc remote=%pISpsfc\n", \
664*1249c01aSStefan Metzmacher 			smbdirect_socket_status_string(__expected_status), \
665*1249c01aSStefan Metzmacher 			smbdirect_socket_status_string((__sc)->status), \
666*1249c01aSStefan Metzmacher 			SMBDIRECT_DEBUG_ERR_PTR((__sc)->first_error), \
667*1249c01aSStefan Metzmacher 			__src, __dst); \
668*1249c01aSStefan Metzmacher 	}, \
669*1249c01aSStefan Metzmacher 	{ \
670*1249c01aSStefan Metzmacher 		const struct sockaddr_storage *__src = NULL; \
671*1249c01aSStefan Metzmacher 		const struct sockaddr_storage *__dst = NULL; \
672*1249c01aSStefan Metzmacher 		if ((__sc)->rdma.cm_id) { \
673*1249c01aSStefan Metzmacher 			__src = &(__sc)->rdma.cm_id->route.addr.src_addr; \
674*1249c01aSStefan Metzmacher 			__dst = &(__sc)->rdma.cm_id->route.addr.dst_addr; \
675*1249c01aSStefan Metzmacher 		} \
676*1249c01aSStefan Metzmacher 		smbdirect_log_rdma_event(sc, SMBDIRECT_LOG_ERR, \
677*1249c01aSStefan Metzmacher 			"expected[%s] != %s first_error=%1pe local=%pISpsfc remote=%pISpsfc\n", \
678*1249c01aSStefan Metzmacher 			smbdirect_socket_status_string(__expected_status), \
679*1249c01aSStefan Metzmacher 			smbdirect_socket_status_string((__sc)->status), \
680*1249c01aSStefan Metzmacher 			SMBDIRECT_DEBUG_ERR_PTR((__sc)->first_error), \
681*1249c01aSStefan Metzmacher 			__src, __dst); \
682*1249c01aSStefan Metzmacher 		WARN_ONCE(1, \
683*1249c01aSStefan Metzmacher 			"expected[%s] != %s first_error=%1pe local=%pISpsfc remote=%pISpsfc\n", \
684*1249c01aSStefan Metzmacher 			smbdirect_socket_status_string(__expected_status), \
685*1249c01aSStefan Metzmacher 			smbdirect_socket_status_string((__sc)->status), \
686*1249c01aSStefan Metzmacher 			SMBDIRECT_DEBUG_ERR_PTR((__sc)->first_error), \
687*1249c01aSStefan Metzmacher 			__src, __dst); \
688*1249c01aSStefan Metzmacher 		__unexpected_cmd \
689*1249c01aSStefan Metzmacher 	})
690*1249c01aSStefan Metzmacher 
691*1249c01aSStefan Metzmacher #define SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status) \
692*1249c01aSStefan Metzmacher 	__SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status, /* nothing */)
693*1249c01aSStefan Metzmacher 
694*1249c01aSStefan Metzmacher #ifndef __SMBDIRECT_SOCKET_DISCONNECT
695*1249c01aSStefan Metzmacher #define __SMBDIRECT_SOCKET_DISCONNECT(__sc) \
696*1249c01aSStefan Metzmacher 		smbdirect_socket_schedule_cleanup(__sc, -ECONNABORTED)
697*1249c01aSStefan Metzmacher #endif /* ! __SMBDIRECT_SOCKET_DISCONNECT */
698*1249c01aSStefan Metzmacher 
699*1249c01aSStefan Metzmacher #define SMBDIRECT_CHECK_STATUS_DISCONNECT(__sc, __expected_status) \
700*1249c01aSStefan Metzmacher 	__SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status, \
701*1249c01aSStefan Metzmacher 		__SMBDIRECT_SOCKET_DISCONNECT(__sc);)
702*1249c01aSStefan Metzmacher 
703*1249c01aSStefan Metzmacher struct smbdirect_send_io {
704*1249c01aSStefan Metzmacher 	struct smbdirect_socket *socket;
705*1249c01aSStefan Metzmacher 	struct ib_cqe cqe;
706*1249c01aSStefan Metzmacher 
707*1249c01aSStefan Metzmacher 	/*
708*1249c01aSStefan Metzmacher 	 * The SGE entries for this work request
709*1249c01aSStefan Metzmacher 	 *
710*1249c01aSStefan Metzmacher 	 * The first points to the packet header
711*1249c01aSStefan Metzmacher 	 */
712*1249c01aSStefan Metzmacher #define SMBDIRECT_SEND_IO_MAX_SGE 6
713*1249c01aSStefan Metzmacher 	size_t num_sge;
714*1249c01aSStefan Metzmacher 	struct ib_sge sge[SMBDIRECT_SEND_IO_MAX_SGE];
715*1249c01aSStefan Metzmacher 
716*1249c01aSStefan Metzmacher 	/*
717*1249c01aSStefan Metzmacher 	 * Link to the list of sibling smbdirect_send_io
718*1249c01aSStefan Metzmacher 	 * messages.
719*1249c01aSStefan Metzmacher 	 */
720*1249c01aSStefan Metzmacher 	struct list_head sibling_list;
721*1249c01aSStefan Metzmacher 	struct ib_send_wr wr;
722*1249c01aSStefan Metzmacher 
723*1249c01aSStefan Metzmacher 	/* SMBD packet header follows this structure */
724*1249c01aSStefan Metzmacher 	u8 packet[];
725*1249c01aSStefan Metzmacher };
726*1249c01aSStefan Metzmacher 
727*1249c01aSStefan Metzmacher struct smbdirect_send_batch {
728*1249c01aSStefan Metzmacher 	/*
729*1249c01aSStefan Metzmacher 	 * List of smbdirect_send_io messages
730*1249c01aSStefan Metzmacher 	 */
731*1249c01aSStefan Metzmacher 	struct list_head msg_list;
732*1249c01aSStefan Metzmacher 	/*
733*1249c01aSStefan Metzmacher 	 * Number of list entries
734*1249c01aSStefan Metzmacher 	 */
735*1249c01aSStefan Metzmacher 	size_t wr_cnt;
736*1249c01aSStefan Metzmacher 
737*1249c01aSStefan Metzmacher 	/*
738*1249c01aSStefan Metzmacher 	 * Possible remote key invalidation state
739*1249c01aSStefan Metzmacher 	 */
740*1249c01aSStefan Metzmacher 	bool need_invalidate_rkey;
741*1249c01aSStefan Metzmacher 	u32 remote_key;
742*1249c01aSStefan Metzmacher 
743*1249c01aSStefan Metzmacher 	int credit;
744*1249c01aSStefan Metzmacher };
745*1249c01aSStefan Metzmacher 
746*1249c01aSStefan Metzmacher struct smbdirect_recv_io {
747*1249c01aSStefan Metzmacher 	struct smbdirect_socket *socket;
748*1249c01aSStefan Metzmacher 	struct ib_cqe cqe;
749*1249c01aSStefan Metzmacher 
750*1249c01aSStefan Metzmacher 	/*
751*1249c01aSStefan Metzmacher 	 * For now we only use a single SGE
752*1249c01aSStefan Metzmacher 	 * as we have just one large buffer
753*1249c01aSStefan Metzmacher 	 * per posted recv.
754*1249c01aSStefan Metzmacher 	 */
755*1249c01aSStefan Metzmacher #define SMBDIRECT_RECV_IO_MAX_SGE 1
756*1249c01aSStefan Metzmacher 	struct ib_sge sge;
757*1249c01aSStefan Metzmacher 
758*1249c01aSStefan Metzmacher 	/* Link to free or reassembly list */
759*1249c01aSStefan Metzmacher 	struct list_head list;
760*1249c01aSStefan Metzmacher 
761*1249c01aSStefan Metzmacher 	/* Indicate if this is the 1st packet of a payload */
762*1249c01aSStefan Metzmacher 	bool first_segment;
763*1249c01aSStefan Metzmacher 
764*1249c01aSStefan Metzmacher 	/* SMBD packet header and payload follows this structure */
765*1249c01aSStefan Metzmacher 	u8 packet[];
766*1249c01aSStefan Metzmacher };
767*1249c01aSStefan Metzmacher 
768*1249c01aSStefan Metzmacher enum smbdirect_mr_state {
769*1249c01aSStefan Metzmacher 	SMBDIRECT_MR_READY,
770*1249c01aSStefan Metzmacher 	SMBDIRECT_MR_REGISTERED,
771*1249c01aSStefan Metzmacher 	SMBDIRECT_MR_INVALIDATED,
772*1249c01aSStefan Metzmacher 	SMBDIRECT_MR_ERROR,
773*1249c01aSStefan Metzmacher 	SMBDIRECT_MR_DISABLED
774*1249c01aSStefan Metzmacher };
775*1249c01aSStefan Metzmacher 
776*1249c01aSStefan Metzmacher struct smbdirect_mr_io {
777*1249c01aSStefan Metzmacher 	struct smbdirect_socket *socket;
778*1249c01aSStefan Metzmacher 	struct ib_cqe cqe;
779*1249c01aSStefan Metzmacher 
780*1249c01aSStefan Metzmacher 	/*
781*1249c01aSStefan Metzmacher 	 * We can have up to two references:
782*1249c01aSStefan Metzmacher 	 * 1. by the connection
783*1249c01aSStefan Metzmacher 	 * 2. by the registration
784*1249c01aSStefan Metzmacher 	 */
785*1249c01aSStefan Metzmacher 	struct kref kref;
786*1249c01aSStefan Metzmacher 	struct mutex mutex;
787*1249c01aSStefan Metzmacher 
788*1249c01aSStefan Metzmacher 	struct list_head list;
789*1249c01aSStefan Metzmacher 
790*1249c01aSStefan Metzmacher 	enum smbdirect_mr_state state;
791*1249c01aSStefan Metzmacher 	struct ib_mr *mr;
792*1249c01aSStefan Metzmacher 	struct sg_table sgt;
793*1249c01aSStefan Metzmacher 	enum dma_data_direction dir;
794*1249c01aSStefan Metzmacher 	union {
795*1249c01aSStefan Metzmacher 		struct ib_reg_wr wr;
796*1249c01aSStefan Metzmacher 		struct ib_send_wr inv_wr;
797*1249c01aSStefan Metzmacher 	};
798*1249c01aSStefan Metzmacher 
799*1249c01aSStefan Metzmacher 	bool need_invalidate;
800*1249c01aSStefan Metzmacher 	struct completion invalidate_done;
801*1249c01aSStefan Metzmacher };
802*1249c01aSStefan Metzmacher 
803*1249c01aSStefan Metzmacher struct smbdirect_rw_io {
804*1249c01aSStefan Metzmacher 	struct smbdirect_socket *socket;
805*1249c01aSStefan Metzmacher 	struct ib_cqe cqe;
806*1249c01aSStefan Metzmacher 
807*1249c01aSStefan Metzmacher 	struct list_head list;
808*1249c01aSStefan Metzmacher 
809*1249c01aSStefan Metzmacher 	int error;
810*1249c01aSStefan Metzmacher 	struct completion *completion;
811*1249c01aSStefan Metzmacher 
812*1249c01aSStefan Metzmacher 	struct rdma_rw_ctx rdma_ctx;
813*1249c01aSStefan Metzmacher 	struct sg_table sgt;
814*1249c01aSStefan Metzmacher 	struct scatterlist sg_list[];
815*1249c01aSStefan Metzmacher };
816*1249c01aSStefan Metzmacher 
817*1249c01aSStefan Metzmacher static inline size_t smbdirect_get_buf_page_count(const void *buf, size_t size)
818*1249c01aSStefan Metzmacher {
819*1249c01aSStefan Metzmacher 	return DIV_ROUND_UP((uintptr_t)buf + size, PAGE_SIZE) -
820*1249c01aSStefan Metzmacher 		(uintptr_t)buf / PAGE_SIZE;
821*1249c01aSStefan Metzmacher }
822*1249c01aSStefan Metzmacher 
823*1249c01aSStefan Metzmacher /*
824*1249c01aSStefan Metzmacher  * Maximum number of retries on data transfer operations
825*1249c01aSStefan Metzmacher  */
826*1249c01aSStefan Metzmacher #define SMBDIRECT_RDMA_CM_RETRY 6
827*1249c01aSStefan Metzmacher /*
828*1249c01aSStefan Metzmacher  * No need to retry on Receiver Not Ready since SMB_DIRECT manages credits
829*1249c01aSStefan Metzmacher  */
830*1249c01aSStefan Metzmacher #define SMBDIRECT_RDMA_CM_RNR_RETRY 0
831*1249c01aSStefan Metzmacher 
832*1249c01aSStefan Metzmacher #endif /* __FS_SMB_COMMON_SMBDIRECT_SMBDIRECT_SOCKET_H__ */
833