1 /*
2 * Copyright (c) 2013-2014 Intel Corporation. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33 #ifndef FI_EQ_H
34 #define FI_EQ_H
35
36 #include <poll.h>
37
38 #ifndef _WIN32
39 #include <pthread.h>
40 #endif /* _WIN32 */
41
42 #include <rdma/fabric.h>
43 #include <rdma/fi_errno.h>
44
45
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49
50
51
52 /*
53 * Wait Set
54 * Allows associating multiple EQs and counters with a single wait object.
55 */
56
57 /* Use fi_control GETWAIT to get underlying wait object(s) */
58 enum fi_wait_obj {
59 FI_WAIT_NONE,
60 FI_WAIT_UNSPEC,
61 FI_WAIT_SET,
62 FI_WAIT_FD,
63 FI_WAIT_MUTEX_COND, /* pthread mutex & cond */
64 FI_WAIT_YIELD,
65 FI_WAIT_POLLFD,
66 };
67
68 struct fi_wait_attr {
69 enum fi_wait_obj wait_obj;
70 uint64_t flags;
71 };
72
73 struct fi_ops_wait {
74 size_t size;
75 int (*wait)(struct fid_wait *waitset, int timeout);
76 };
77
78 struct fid_wait {
79 struct fid fid;
80 struct fi_ops_wait *ops;
81 };
82
83 #ifndef _WIN32
84 struct fi_mutex_cond {
85 pthread_mutex_t *mutex;
86 pthread_cond_t *cond;
87 };
88 #endif /* _WIN32 */
89
90 struct fi_wait_pollfd {
91 uint64_t change_index;
92 size_t nfds;
93 struct pollfd *fd;
94 };
95
96 /*
97 * Poll Set
98 * Allows polling multiple event queues and counters for progress
99 */
100
101 struct fi_poll_attr {
102 uint64_t flags;
103 };
104
105 struct fi_ops_poll {
106 size_t size;
107 int (*poll)(struct fid_poll *pollset, void **context, int count);
108 int (*poll_add)(struct fid_poll *pollset, struct fid *event_fid,
109 uint64_t flags);
110 int (*poll_del)(struct fid_poll *pollset, struct fid *event_fid,
111 uint64_t flags);
112 };
113
114 struct fid_poll {
115 struct fid fid;
116 struct fi_ops_poll *ops;
117 };
118
119 /*
120 * EQ = Event Queue
121 * Used to report various control (not data transfer) events and operations.
122 */
123
124 struct fi_eq_attr {
125 size_t size;
126 uint64_t flags;
127 enum fi_wait_obj wait_obj;
128 int signaling_vector;
129 struct fid_wait *wait_set;
130 };
131
132 /* Standard EQ events */
133 enum {
134 FI_NOTIFY,
135 FI_CONNREQ,
136 FI_CONNECTED,
137 FI_SHUTDOWN,
138 FI_MR_COMPLETE,
139 FI_AV_COMPLETE,
140 FI_JOIN_COMPLETE,
141 };
142
143 struct fi_eq_entry {
144 fid_t fid;
145 void *context;
146 uint64_t data;
147 };
148
149 struct fi_eq_err_entry {
150 fid_t fid;
151 void *context;
152 uint64_t data;
153 int err;
154 int prov_errno;
155 /* err_data is available until the next time the EQ is read */
156 void *err_data;
157 size_t err_data_size;
158 };
159
160 struct fi_eq_cm_entry {
161 fid_t fid;
162 /* user must call fi_freeinfo to release info */
163 struct fi_info *info;
164 /* connection data placed here, up to space provided */
165 uint8_t data[];
166 };
167
168 struct fi_ops_eq {
169 size_t size;
170 ssize_t (*read)(struct fid_eq *eq, uint32_t *event,
171 void *buf, size_t len, uint64_t flags);
172 ssize_t (*readerr)(struct fid_eq *eq, struct fi_eq_err_entry *buf,
173 uint64_t flags);
174 ssize_t (*write)(struct fid_eq *eq, uint32_t event,
175 const void *buf, size_t len, uint64_t flags);
176 ssize_t (*sread)(struct fid_eq *eq, uint32_t *event,
177 void *buf, size_t len, int timeout, uint64_t flags);
178 const char * (*strerror)(struct fid_eq *eq, int prov_errno,
179 const void *err_data, char *buf, size_t len);
180 };
181
182 struct fid_eq {
183 struct fid fid;
184 struct fi_ops_eq *ops;
185 };
186
187
188 /*
189 * CQ = Complete Queue
190 * Used to report the completion of data transfer operations.
191 */
192
193 enum fi_cq_format {
194 FI_CQ_FORMAT_UNSPEC,
195 FI_CQ_FORMAT_CONTEXT,
196 FI_CQ_FORMAT_MSG,
197 FI_CQ_FORMAT_DATA,
198 FI_CQ_FORMAT_TAGGED,
199 };
200
201 struct fi_cq_entry {
202 void *op_context;
203 };
204
205 struct fi_cq_msg_entry {
206 void *op_context;
207 uint64_t flags;
208 size_t len;
209 };
210
211 struct fi_cq_data_entry {
212 void *op_context;
213 uint64_t flags;
214 size_t len;
215 void *buf;
216 /* data depends on operation and/or flags - e.g. remote EQ data */
217 uint64_t data;
218 };
219
220 struct fi_cq_tagged_entry {
221 void *op_context;
222 uint64_t flags;
223 size_t len;
224 void *buf;
225 uint64_t data;
226 uint64_t tag;
227 };
228
229 struct fi_cq_err_entry {
230 void *op_context;
231 uint64_t flags;
232 size_t len;
233 void *buf;
234 uint64_t data;
235 uint64_t tag;
236 size_t olen;
237 int err;
238 int prov_errno;
239 /* err_data is available until the next time the CQ is read */
240 void *err_data;
241 size_t err_data_size;
242 };
243
244 enum fi_cq_wait_cond {
245 FI_CQ_COND_NONE,
246 FI_CQ_COND_THRESHOLD /* size_t threshold */
247 };
248
249 struct fi_cq_attr {
250 size_t size;
251 uint64_t flags;
252 enum fi_cq_format format;
253 enum fi_wait_obj wait_obj;
254 int signaling_vector;
255 enum fi_cq_wait_cond wait_cond;
256 struct fid_wait *wait_set;
257 };
258
259 struct fi_ops_cq {
260 size_t size;
261 ssize_t (*read)(struct fid_cq *cq, void *buf, size_t count);
262 ssize_t (*readfrom)(struct fid_cq *cq, void *buf, size_t count,
263 fi_addr_t *src_addr);
264 ssize_t (*readerr)(struct fid_cq *cq, struct fi_cq_err_entry *buf,
265 uint64_t flags);
266 ssize_t (*sread)(struct fid_cq *cq, void *buf, size_t count,
267 const void *cond, int timeout);
268 ssize_t (*sreadfrom)(struct fid_cq *cq, void *buf, size_t count,
269 fi_addr_t *src_addr, const void *cond, int timeout);
270 int (*signal)(struct fid_cq *cq);
271 const char * (*strerror)(struct fid_cq *cq, int prov_errno,
272 const void *err_data, char *buf, size_t len);
273 };
274
275 struct fid_cq {
276 struct fid fid;
277 struct fi_ops_cq *ops;
278 };
279
280
281 /*
282 * CNTR = Counter
283 * Used to report the number of completed of asynchronous operations.
284 */
285
286 enum fi_cntr_events {
287 FI_CNTR_EVENTS_COMP
288 };
289
290 struct fi_cntr_attr {
291 enum fi_cntr_events events;
292 enum fi_wait_obj wait_obj;
293 struct fid_wait *wait_set;
294 uint64_t flags;
295 };
296
297 struct fi_ops_cntr {
298 size_t size;
299 uint64_t (*read)(struct fid_cntr *cntr);
300 uint64_t (*readerr)(struct fid_cntr *cntr);
301 int (*add)(struct fid_cntr *cntr, uint64_t value);
302 int (*set)(struct fid_cntr *cntr, uint64_t value);
303 int (*wait)(struct fid_cntr *cntr, uint64_t threshold, int timeout);
304 int (*adderr)(struct fid_cntr *cntr, uint64_t value);
305 int (*seterr)(struct fid_cntr *cntr, uint64_t value);
306 };
307
308 struct fid_cntr {
309 struct fid fid;
310 struct fi_ops_cntr *ops;
311 };
312
313
314 #ifdef FABRIC_DIRECT
315 #include <rdma/fi_direct_eq.h>
316 #endif /* FABRIC_DIRECT */
317
318 #ifndef FABRIC_DIRECT_EQ
319
320 static inline int
fi_trywait(struct fid_fabric * fabric,struct fid ** fids,int count)321 fi_trywait(struct fid_fabric *fabric, struct fid **fids, int count)
322 {
323 return fabric->ops->trywait(fabric, fids, count);
324 }
325
326 static inline int
fi_wait(struct fid_wait * waitset,int timeout)327 fi_wait(struct fid_wait *waitset, int timeout)
328 {
329 return waitset->ops->wait(waitset, timeout);
330 }
331
332 static inline int
fi_poll(struct fid_poll * pollset,void ** context,int count)333 fi_poll(struct fid_poll *pollset, void **context, int count)
334 {
335 return pollset->ops->poll(pollset, context, count);
336 }
337
338 static inline int
fi_poll_add(struct fid_poll * pollset,struct fid * event_fid,uint64_t flags)339 fi_poll_add(struct fid_poll *pollset, struct fid *event_fid, uint64_t flags)
340 {
341 return pollset->ops->poll_add(pollset, event_fid, flags);
342 }
343
344 static inline int
fi_poll_del(struct fid_poll * pollset,struct fid * event_fid,uint64_t flags)345 fi_poll_del(struct fid_poll *pollset, struct fid *event_fid, uint64_t flags)
346 {
347 return pollset->ops->poll_del(pollset, event_fid, flags);
348 }
349
350 static inline int
fi_eq_open(struct fid_fabric * fabric,struct fi_eq_attr * attr,struct fid_eq ** eq,void * context)351 fi_eq_open(struct fid_fabric *fabric, struct fi_eq_attr *attr,
352 struct fid_eq **eq, void *context)
353 {
354 return fabric->ops->eq_open(fabric, attr, eq, context);
355 }
356
357 static inline ssize_t
fi_eq_read(struct fid_eq * eq,uint32_t * event,void * buf,size_t len,uint64_t flags)358 fi_eq_read(struct fid_eq *eq, uint32_t *event, void *buf,
359 size_t len, uint64_t flags)
360 {
361 return eq->ops->read(eq, event, buf, len, flags);
362 }
363
364 static inline ssize_t
fi_eq_readerr(struct fid_eq * eq,struct fi_eq_err_entry * buf,uint64_t flags)365 fi_eq_readerr(struct fid_eq *eq, struct fi_eq_err_entry *buf, uint64_t flags)
366 {
367 return eq->ops->readerr(eq, buf, flags);
368 }
369
370 static inline ssize_t
fi_eq_write(struct fid_eq * eq,uint32_t event,const void * buf,size_t len,uint64_t flags)371 fi_eq_write(struct fid_eq *eq, uint32_t event, const void *buf,
372 size_t len, uint64_t flags)
373 {
374 return eq->ops->write(eq, event, buf, len, flags);
375 }
376
377 static inline ssize_t
fi_eq_sread(struct fid_eq * eq,uint32_t * event,void * buf,size_t len,int timeout,uint64_t flags)378 fi_eq_sread(struct fid_eq *eq, uint32_t *event, void *buf, size_t len,
379 int timeout, uint64_t flags)
380 {
381 return eq->ops->sread(eq, event, buf, len, timeout, flags);
382 }
383
384 static inline const char *
fi_eq_strerror(struct fid_eq * eq,int prov_errno,const void * err_data,char * buf,size_t len)385 fi_eq_strerror(struct fid_eq *eq, int prov_errno, const void *err_data,
386 char *buf, size_t len)
387 {
388 return eq->ops->strerror(eq, prov_errno, err_data, buf, len);
389 }
390
391
fi_cq_read(struct fid_cq * cq,void * buf,size_t count)392 static inline ssize_t fi_cq_read(struct fid_cq *cq, void *buf, size_t count)
393 {
394 return cq->ops->read(cq, buf, count);
395 }
396
397 static inline ssize_t
fi_cq_readfrom(struct fid_cq * cq,void * buf,size_t count,fi_addr_t * src_addr)398 fi_cq_readfrom(struct fid_cq *cq, void *buf, size_t count, fi_addr_t *src_addr)
399 {
400 return cq->ops->readfrom(cq, buf, count, src_addr);
401 }
402
403 static inline ssize_t
fi_cq_readerr(struct fid_cq * cq,struct fi_cq_err_entry * buf,uint64_t flags)404 fi_cq_readerr(struct fid_cq *cq, struct fi_cq_err_entry *buf, uint64_t flags)
405 {
406 return cq->ops->readerr(cq, buf, flags);
407 }
408
409 static inline ssize_t
fi_cq_sread(struct fid_cq * cq,void * buf,size_t count,const void * cond,int timeout)410 fi_cq_sread(struct fid_cq *cq, void *buf, size_t count, const void *cond, int timeout)
411 {
412 return cq->ops->sread(cq, buf, count, cond, timeout);
413 }
414
415 static inline ssize_t
fi_cq_sreadfrom(struct fid_cq * cq,void * buf,size_t count,fi_addr_t * src_addr,const void * cond,int timeout)416 fi_cq_sreadfrom(struct fid_cq *cq, void *buf, size_t count,
417 fi_addr_t *src_addr, const void *cond, int timeout)
418 {
419 return cq->ops->sreadfrom(cq, buf, count, src_addr, cond, timeout);
420 }
421
fi_cq_signal(struct fid_cq * cq)422 static inline int fi_cq_signal(struct fid_cq *cq)
423 {
424 return cq->ops->signal(cq);
425 }
426
427 static inline const char *
fi_cq_strerror(struct fid_cq * cq,int prov_errno,const void * err_data,char * buf,size_t len)428 fi_cq_strerror(struct fid_cq *cq, int prov_errno, const void *err_data,
429 char *buf, size_t len)
430 {
431 return cq->ops->strerror(cq, prov_errno, err_data, buf, len);
432 }
433
434
fi_cntr_read(struct fid_cntr * cntr)435 static inline uint64_t fi_cntr_read(struct fid_cntr *cntr)
436 {
437 return cntr->ops->read(cntr);
438 }
439
fi_cntr_readerr(struct fid_cntr * cntr)440 static inline uint64_t fi_cntr_readerr(struct fid_cntr *cntr)
441 {
442 return cntr->ops->readerr(cntr);
443 }
444
fi_cntr_add(struct fid_cntr * cntr,uint64_t value)445 static inline int fi_cntr_add(struct fid_cntr *cntr, uint64_t value)
446 {
447 return cntr->ops->add(cntr, value);
448 }
449
fi_cntr_adderr(struct fid_cntr * cntr,uint64_t value)450 static inline int fi_cntr_adderr(struct fid_cntr *cntr, uint64_t value)
451 {
452 return FI_CHECK_OP(cntr->ops, struct fi_ops_cntr, adderr) ?
453 cntr->ops->adderr(cntr, value) : -FI_ENOSYS;
454 }
455
fi_cntr_set(struct fid_cntr * cntr,uint64_t value)456 static inline int fi_cntr_set(struct fid_cntr *cntr, uint64_t value)
457 {
458 return cntr->ops->set(cntr, value);
459 }
460
fi_cntr_seterr(struct fid_cntr * cntr,uint64_t value)461 static inline int fi_cntr_seterr(struct fid_cntr *cntr, uint64_t value)
462 {
463 return FI_CHECK_OP(cntr->ops, struct fi_ops_cntr, seterr) ?
464 cntr->ops->seterr(cntr, value) : -FI_ENOSYS;
465 }
466
467 static inline int
fi_cntr_wait(struct fid_cntr * cntr,uint64_t threshold,int timeout)468 fi_cntr_wait(struct fid_cntr *cntr, uint64_t threshold, int timeout)
469 {
470 return cntr->ops->wait(cntr, threshold, timeout);
471 }
472
473 #endif
474
475 #ifdef __cplusplus
476 }
477 #endif
478
479 #endif /* FI_EQ_H */
480