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
41
42#ifndef SVC_RDMA_H
43#define SVC_RDMA_H
44#include <linux/sunrpc/xdr.h>
45#include <linux/sunrpc/svcsock.h>
46#include <linux/sunrpc/rpc_rdma.h>
47#include <rdma/ib_verbs.h>
48#include <rdma/rdma_cm.h>
49#define SVCRDMA_DEBUG
50
51
52extern unsigned int svcrdma_ord;
53extern unsigned int svcrdma_max_requests;
54extern unsigned int svcrdma_max_req_size;
55
56extern atomic_t rdma_stat_recv;
57extern atomic_t rdma_stat_read;
58extern atomic_t rdma_stat_write;
59extern atomic_t rdma_stat_sq_starve;
60extern atomic_t rdma_stat_rq_starve;
61extern atomic_t rdma_stat_rq_poll;
62extern atomic_t rdma_stat_rq_prod;
63extern atomic_t rdma_stat_sq_poll;
64extern atomic_t rdma_stat_sq_prod;
65
66#define RPCRDMA_VERSION 1
67
68
69
70
71
72
73struct svc_rdma_op_ctxt {
74 struct svc_rdma_op_ctxt *read_hdr;
75 int hdr_count;
76 struct xdr_buf arg;
77 struct list_head dto_q;
78 enum ib_wr_opcode wr_op;
79 enum ib_wc_status wc_status;
80 u32 byte_len;
81 struct svcxprt_rdma *xprt;
82 unsigned long flags;
83 enum dma_data_direction direction;
84 int count;
85 struct ib_sge sge[RPCSVC_MAXPAGES];
86 struct page *pages[RPCSVC_MAXPAGES];
87};
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102struct svc_rdma_chunk_sge {
103 int start;
104 int count;
105};
106struct svc_rdma_req_map {
107 unsigned long count;
108 union {
109 struct kvec sge[RPCSVC_MAXPAGES];
110 struct svc_rdma_chunk_sge ch[RPCSVC_MAXPAGES];
111 };
112};
113
114#define RDMACTXT_F_LAST_CTXT 2
115
116struct svcxprt_rdma {
117 struct svc_xprt sc_xprt;
118 struct rdma_cm_id *sc_cm_id;
119 struct list_head sc_accept_q;
120 int sc_ord;
121 int sc_max_sge;
122
123 int sc_sq_depth;
124 atomic_t sc_sq_count;
125
126 int sc_max_requests;
127 int sc_max_req_size;
128
129 struct ib_pd *sc_pd;
130
131 atomic_t sc_dma_used;
132 atomic_t sc_ctxt_used;
133 struct list_head sc_rq_dto_q;
134 spinlock_t sc_rq_dto_lock;
135 struct ib_qp *sc_qp;
136 struct ib_cq *sc_rq_cq;
137 struct ib_cq *sc_sq_cq;
138 struct ib_mr *sc_phys_mr;
139
140 spinlock_t sc_lock;
141
142 wait_queue_head_t sc_send_wait;
143 unsigned long sc_flags;
144 struct list_head sc_dto_q;
145 struct list_head sc_read_complete_q;
146 struct work_struct sc_work;
147};
148
149#define RDMAXPRT_RQ_PENDING 1
150#define RDMAXPRT_SQ_PENDING 2
151#define RDMAXPRT_CONN_PENDING 3
152
153#define RPCRDMA_LISTEN_BACKLOG 10
154
155
156#define RPCRDMA_ORD (64/4)
157#define RPCRDMA_SQ_DEPTH_MULT 8
158#define RPCRDMA_MAX_THREADS 16
159#define RPCRDMA_MAX_REQUESTS 16
160#define RPCRDMA_MAX_REQ_SIZE 4096
161
162
163extern void svc_rdma_rcl_chunk_counts(struct rpcrdma_read_chunk *,
164 int *, int *);
165extern int svc_rdma_xdr_decode_req(struct rpcrdma_msg **, struct svc_rqst *);
166extern int svc_rdma_xdr_decode_deferred_req(struct svc_rqst *);
167extern int svc_rdma_xdr_encode_error(struct svcxprt_rdma *,
168 struct rpcrdma_msg *,
169 enum rpcrdma_errcode, u32 *);
170extern void svc_rdma_xdr_encode_write_list(struct rpcrdma_msg *, int);
171extern void svc_rdma_xdr_encode_reply_array(struct rpcrdma_write_array *, int);
172extern void svc_rdma_xdr_encode_array_chunk(struct rpcrdma_write_array *, int,
173 u32, u64, u32);
174extern void svc_rdma_xdr_encode_reply_header(struct svcxprt_rdma *,
175 struct rpcrdma_msg *,
176 struct rpcrdma_msg *,
177 enum rpcrdma_proc);
178extern int svc_rdma_xdr_get_reply_hdr_len(struct rpcrdma_msg *);
179
180
181extern int svc_rdma_recvfrom(struct svc_rqst *);
182
183
184extern int svc_rdma_sendto(struct svc_rqst *);
185
186
187extern int svc_rdma_send(struct svcxprt_rdma *, struct ib_send_wr *);
188extern void svc_rdma_send_error(struct svcxprt_rdma *, struct rpcrdma_msg *,
189 enum rpcrdma_errcode);
190struct page *svc_rdma_get_page(void);
191extern int svc_rdma_post_recv(struct svcxprt_rdma *);
192extern int svc_rdma_create_listen(struct svc_serv *, int, struct sockaddr *);
193extern struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *);
194extern void svc_rdma_put_context(struct svc_rdma_op_ctxt *, int);
195extern struct svc_rdma_req_map *svc_rdma_get_req_map(void);
196extern void svc_rdma_put_req_map(struct svc_rdma_req_map *);
197extern void svc_sq_reap(struct svcxprt_rdma *);
198extern void svc_rq_reap(struct svcxprt_rdma *);
199extern struct svc_xprt_class svc_rdma_class;
200extern void svc_rdma_prep_reply_hdr(struct svc_rqst *);
201
202
203extern int svc_rdma_init(void);
204extern void svc_rdma_cleanup(void);
205
206
207
208
209
210static inline struct rpcrdma_read_chunk *
211svc_rdma_get_read_chunk(struct rpcrdma_msg *rmsgp)
212{
213 struct rpcrdma_read_chunk *ch =
214 (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0];
215
216 if (ch->rc_discrim == 0)
217 return NULL;
218
219 return ch;
220}
221
222
223
224
225
226static inline struct rpcrdma_write_array *
227svc_rdma_get_write_array(struct rpcrdma_msg *rmsgp)
228{
229 if (rmsgp->rm_body.rm_chunks[0] != 0
230 || rmsgp->rm_body.rm_chunks[1] == 0)
231 return NULL;
232
233 return (struct rpcrdma_write_array *)&rmsgp->rm_body.rm_chunks[1];
234}
235
236
237
238
239
240static inline struct rpcrdma_write_array *
241svc_rdma_get_reply_array(struct rpcrdma_msg *rmsgp)
242{
243 struct rpcrdma_read_chunk *rch;
244 struct rpcrdma_write_array *wr_ary;
245 struct rpcrdma_write_array *rp_ary;
246
247
248
249 if (rmsgp->rm_body.rm_chunks[0] != 0 ||
250 rmsgp->rm_body.rm_chunks[1] != 0)
251 return NULL;
252
253 rch = svc_rdma_get_read_chunk(rmsgp);
254 if (rch) {
255 while (rch->rc_discrim)
256 rch++;
257
258
259
260
261 rp_ary = (struct rpcrdma_write_array *)&rch->rc_target;
262
263 goto found_it;
264 }
265
266 wr_ary = svc_rdma_get_write_array(rmsgp);
267 if (wr_ary) {
268 rp_ary = (struct rpcrdma_write_array *)
269 &wr_ary->
270 wc_array[wr_ary->wc_nchunks].wc_target.rs_length;
271
272 goto found_it;
273 }
274
275
276 rp_ary = (struct rpcrdma_write_array *)
277 &rmsgp->rm_body.rm_chunks[2];
278
279 found_it:
280 if (rp_ary->wc_discrim == 0)
281 return NULL;
282
283 return rp_ary;
284}
285#endif
286