1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40#ifndef _LINUX_SUNRPC_XPRT_RDMA_H
41#define _LINUX_SUNRPC_XPRT_RDMA_H
42
43#include <linux/wait.h>
44#include <linux/spinlock.h>
45#include <linux/atomic.h>
46
47#include <rdma/rdma_cm.h>
48#include <rdma/ib_verbs.h>
49
50#include <linux/sunrpc/clnt.h>
51#include <linux/sunrpc/rpc_rdma.h>
52#include <linux/sunrpc/xprtrdma.h>
53
54#define RDMA_RESOLVE_TIMEOUT (5000)
55#define RDMA_CONNECT_RETRY_MAX (2)
56
57
58
59
60struct rpcrdma_ia {
61 struct rdma_cm_id *ri_id;
62 struct ib_pd *ri_pd;
63 struct ib_mr *ri_bind_mem;
64 u32 ri_dma_lkey;
65 int ri_have_dma_lkey;
66 struct completion ri_done;
67 int ri_async_rc;
68 enum rpcrdma_memreg ri_memreg_strategy;
69};
70
71
72
73
74
75struct rpcrdma_ep {
76 atomic_t rep_cqcount;
77 int rep_cqinit;
78 int rep_connected;
79 struct rpcrdma_ia *rep_ia;
80 struct ib_cq *rep_cq;
81 struct ib_qp_init_attr rep_attr;
82 wait_queue_head_t rep_connect_wait;
83 struct ib_sge rep_pad;
84 struct ib_mr *rep_pad_mr;
85 void (*rep_func)(struct rpcrdma_ep *);
86 struct rpc_xprt *rep_xprt;
87 struct rdma_conn_param rep_remote_cma;
88 struct sockaddr_storage rep_remote_addr;
89};
90
91#define INIT_CQCOUNT(ep) atomic_set(&(ep)->rep_cqcount, (ep)->rep_cqinit)
92#define DECR_CQCOUNT(ep) atomic_sub_return(1, &(ep)->rep_cqcount)
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112#define RPCRDMA_MAX_DATA_SEGS (64)
113#define RPCRDMA_MAX_SEGS (RPCRDMA_MAX_DATA_SEGS + 2)
114#define MAX_RPCRDMAHDR (\
115 \
116 sizeof(struct rpcrdma_msg) + (2 * sizeof(u32)) + \
117 (sizeof(struct rpcrdma_read_chunk) * RPCRDMA_MAX_SEGS) + sizeof(u32))
118
119struct rpcrdma_buffer;
120
121struct rpcrdma_rep {
122 unsigned int rr_len;
123 struct rpcrdma_buffer *rr_buffer;
124 struct rpc_xprt *rr_xprt;
125 void (*rr_func)(struct rpcrdma_rep *);
126 struct list_head rr_list;
127 wait_queue_head_t rr_unbind;
128 struct ib_sge rr_iov;
129 struct ib_mr *rr_handle;
130 char rr_base[MAX_RPCRDMAHDR];
131};
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157struct rpcrdma_mr_seg {
158 union {
159 struct ib_mr *rl_mr;
160 struct rpcrdma_mw {
161 union {
162 struct ib_mw *mw;
163 struct ib_fmr *fmr;
164 struct {
165 struct ib_fast_reg_page_list *fr_pgl;
166 struct ib_mr *fr_mr;
167 enum { FRMR_IS_INVALID, FRMR_IS_VALID } state;
168 } frmr;
169 } r;
170 struct list_head mw_list;
171 } *rl_mw;
172 } mr_chunk;
173 u64 mr_base;
174 u32 mr_rkey;
175 u32 mr_len;
176 int mr_nsegs;
177 enum dma_data_direction mr_dir;
178 dma_addr_t mr_dma;
179 size_t mr_dmalen;
180 struct page *mr_page;
181 char *mr_offset;
182};
183
184struct rpcrdma_req {
185 size_t rl_size;
186 unsigned int rl_niovs;
187 unsigned int rl_nchunks;
188 unsigned int rl_connect_cookie;
189 struct rpcrdma_buffer *rl_buffer;
190 struct rpcrdma_rep *rl_reply;
191 struct rpcrdma_mr_seg rl_segments[RPCRDMA_MAX_SEGS];
192 struct ib_sge rl_send_iov[4];
193 struct ib_sge rl_iov;
194 struct ib_mr *rl_handle;
195 char rl_base[MAX_RPCRDMAHDR];
196 __u32 rl_xdr_buf[0];
197};
198#define rpcr_to_rdmar(r) \
199 container_of((r)->rq_buffer, struct rpcrdma_req, rl_xdr_buf[0])
200
201
202
203
204
205
206
207struct rpcrdma_buffer {
208 spinlock_t rb_lock;
209 atomic_t rb_credits;
210 unsigned long rb_cwndscale;
211 int rb_max_requests;
212 struct list_head rb_mws;
213 int rb_send_index;
214 struct rpcrdma_req **rb_send_bufs;
215 int rb_recv_index;
216 struct rpcrdma_rep **rb_recv_bufs;
217 char *rb_pool;
218};
219#define rdmab_to_ia(b) (&container_of((b), struct rpcrdma_xprt, rx_buf)->rx_ia)
220
221
222
223
224
225
226
227struct rpcrdma_create_data_internal {
228 struct sockaddr_storage addr;
229 unsigned int max_requests;
230 unsigned int rsize;
231 unsigned int wsize;
232 unsigned int inline_rsize;
233 unsigned int inline_wsize;
234 unsigned int padding;
235};
236
237#define RPCRDMA_INLINE_READ_THRESHOLD(rq) \
238 (rpcx_to_rdmad(rq->rq_task->tk_xprt).inline_rsize)
239
240#define RPCRDMA_INLINE_WRITE_THRESHOLD(rq)\
241 (rpcx_to_rdmad(rq->rq_task->tk_xprt).inline_wsize)
242
243#define RPCRDMA_INLINE_PAD_VALUE(rq)\
244 rpcx_to_rdmad(rq->rq_task->tk_xprt).padding
245
246
247
248
249struct rpcrdma_stats {
250 unsigned long read_chunk_count;
251 unsigned long write_chunk_count;
252 unsigned long reply_chunk_count;
253
254 unsigned long long total_rdma_request;
255 unsigned long long total_rdma_reply;
256
257 unsigned long long pullup_copy_count;
258 unsigned long long fixup_copy_count;
259 unsigned long hardway_register_count;
260 unsigned long failed_marshal_count;
261 unsigned long bad_reply_count;
262};
263
264
265
266
267
268
269
270
271
272
273
274struct rpcrdma_xprt {
275 struct rpc_xprt xprt;
276 struct rpcrdma_ia rx_ia;
277 struct rpcrdma_ep rx_ep;
278 struct rpcrdma_buffer rx_buf;
279 struct rpcrdma_create_data_internal rx_data;
280 struct delayed_work rdma_connect;
281 struct rpcrdma_stats rx_stats;
282};
283
284#define rpcx_to_rdmax(x) container_of(x, struct rpcrdma_xprt, xprt)
285#define rpcx_to_rdmad(x) (rpcx_to_rdmax(x)->rx_data)
286
287
288
289
290extern int xprt_rdma_pad_optimize;
291
292
293
294
295int rpcrdma_ia_open(struct rpcrdma_xprt *, struct sockaddr *, int);
296void rpcrdma_ia_close(struct rpcrdma_ia *);
297
298
299
300
301int rpcrdma_ep_create(struct rpcrdma_ep *, struct rpcrdma_ia *,
302 struct rpcrdma_create_data_internal *);
303int rpcrdma_ep_destroy(struct rpcrdma_ep *, struct rpcrdma_ia *);
304int rpcrdma_ep_connect(struct rpcrdma_ep *, struct rpcrdma_ia *);
305int rpcrdma_ep_disconnect(struct rpcrdma_ep *, struct rpcrdma_ia *);
306
307int rpcrdma_ep_post(struct rpcrdma_ia *, struct rpcrdma_ep *,
308 struct rpcrdma_req *);
309int rpcrdma_ep_post_recv(struct rpcrdma_ia *, struct rpcrdma_ep *,
310 struct rpcrdma_rep *);
311
312
313
314
315int rpcrdma_buffer_create(struct rpcrdma_buffer *, struct rpcrdma_ep *,
316 struct rpcrdma_ia *,
317 struct rpcrdma_create_data_internal *);
318void rpcrdma_buffer_destroy(struct rpcrdma_buffer *);
319
320struct rpcrdma_req *rpcrdma_buffer_get(struct rpcrdma_buffer *);
321void rpcrdma_buffer_put(struct rpcrdma_req *);
322void rpcrdma_recv_buffer_get(struct rpcrdma_req *);
323void rpcrdma_recv_buffer_put(struct rpcrdma_rep *);
324
325int rpcrdma_register_internal(struct rpcrdma_ia *, void *, int,
326 struct ib_mr **, struct ib_sge *);
327int rpcrdma_deregister_internal(struct rpcrdma_ia *,
328 struct ib_mr *, struct ib_sge *);
329
330int rpcrdma_register_external(struct rpcrdma_mr_seg *,
331 int, int, struct rpcrdma_xprt *);
332int rpcrdma_deregister_external(struct rpcrdma_mr_seg *,
333 struct rpcrdma_xprt *, void *);
334
335
336
337
338void rpcrdma_conn_func(struct rpcrdma_ep *);
339void rpcrdma_reply_handler(struct rpcrdma_rep *);
340
341
342
343
344int rpcrdma_marshal_req(struct rpc_rqst *);
345
346
347extern struct kmem_cache *svc_rdma_map_cachep;
348
349extern struct kmem_cache *svc_rdma_ctxt_cachep;
350
351extern struct workqueue_struct *svc_rdma_wq;
352
353#endif
354