1use crate::*;
2
3use std::mem;
4use std::ptr;
5
6pub type ibv_advise_mr_advice = ib_uverbs_advise_mr_advice::Type;
9
10#[inline]
12pub unsafe fn ibv_wr_atomic_cmp_swp(
13 qp: *mut ibv_qp_ex,
14 rkey: u32,
15 remote_addr: u64,
16 compare: u64,
17 swap: u64,
18) {
19 (*qp).wr_atomic_cmp_swp.unwrap()(qp, rkey, remote_addr, compare, swap);
20}
21
22#[inline]
23pub unsafe fn ibv_wr_atomic_fetch_add(qp: *mut ibv_qp_ex, rkey: u32, remote_addr: u64, add: u64) {
24 (*qp).wr_atomic_fetch_add.unwrap()(qp, rkey, remote_addr, add);
25}
26
27#[inline]
28pub unsafe fn ibv_wr_bind_mw(
29 qp: *mut ibv_qp_ex,
30 mw: *mut ibv_mw,
31 rkey: u32,
32 bind_info: *const ibv_mw_bind_info,
33) {
34 (*qp).wr_bind_mw.unwrap()(qp, mw, rkey, bind_info);
35}
36
37#[inline]
38pub unsafe fn ibv_wr_local_inv(qp: *mut ibv_qp_ex, invalidate_rkey: u32) {
39 (*qp).wr_local_inv.unwrap()(qp, invalidate_rkey);
40}
41
42#[inline]
43pub unsafe fn ibv_wr_rdma_read(qp: *mut ibv_qp_ex, rkey: u32, remote_addr: u64) {
44 (*qp).wr_rdma_read.unwrap()(qp, rkey, remote_addr);
45}
46
47#[inline]
48pub unsafe fn ibv_wr_rdma_write(qp: *mut ibv_qp_ex, rkey: u32, remote_addr: u64) {
49 (*qp).wr_rdma_write.unwrap()(qp, rkey, remote_addr);
50}
51
52#[inline]
53pub unsafe fn ibv_wr_rdma_write_imm(
54 qp: *mut ibv_qp_ex,
55 rkey: u32,
56 remote_addr: u64,
57 imm_data: __be32,
58) {
59 (*qp).wr_rdma_write_imm.unwrap()(qp, rkey, remote_addr, imm_data);
60}
61
62#[inline]
63pub unsafe fn ibv_wr_send(qp: *mut ibv_qp_ex) {
64 (*qp).wr_send.unwrap()(qp);
65}
66
67#[inline]
68pub unsafe fn ibv_wr_send_imm(qp: *mut ibv_qp_ex, imm_data: __be32) {
69 (*qp).wr_send_imm.unwrap()(qp, imm_data);
70}
71
72#[inline]
73pub unsafe fn ibv_wr_send_inv(qp: *mut ibv_qp_ex, invalidate_rkey: u32) {
74 (*qp).wr_send_inv.unwrap()(qp, invalidate_rkey);
75}
76
77#[inline]
78pub unsafe fn ibv_wr_send_tso(qp: *mut ibv_qp_ex, hdr: *mut c_void, hdr_sz: u16, mss: u16) {
79 (*qp).wr_send_tso.unwrap()(qp, hdr, hdr_sz, mss);
80}
81
82#[inline]
83pub unsafe fn ibv_wr_set_ud_addr(
84 qp: *mut ibv_qp_ex,
85 ah: *mut ibv_ah,
86 remote_qpn: u32,
87 remote_qkey: u32,
88) {
89 (*qp).wr_set_ud_addr.unwrap()(qp, ah, remote_qpn, remote_qkey);
90}
91
92#[inline]
93pub unsafe fn ibv_wr_set_xrc_srqn(qp: *mut ibv_qp_ex, remote_srqn: u32) {
94 (*qp).wr_set_xrc_srqn.unwrap()(qp, remote_srqn);
95}
96
97#[inline]
98pub unsafe fn ibv_wr_set_inline_data(qp: *mut ibv_qp_ex, addr: *mut c_void, length: usize) {
99 (*qp).wr_set_inline_data.unwrap()(qp, addr, length);
100}
101
102#[inline]
103pub unsafe fn ibv_wr_set_inline_data_list(
104 qp: *mut ibv_qp_ex,
105 num_buf: usize,
106 buf_list: *const ibv_data_buf,
107) {
108 (*qp).wr_set_inline_data_list.unwrap()(qp, num_buf, buf_list);
109}
110
111#[inline]
112pub unsafe fn ibv_wr_set_sge(qp: *mut ibv_qp_ex, lkey: u32, addr: u64, length: u32) {
113 (*qp).wr_set_sge.unwrap()(qp, lkey, addr, length);
114}
115
116#[inline]
117pub unsafe fn ibv_wr_set_sge_list(qp: *mut ibv_qp_ex, num_sge: usize, sg_list: *const ibv_sge) {
118 (*qp).wr_set_sge_list.unwrap()(qp, num_sge, sg_list);
119}
120
121#[inline]
122pub unsafe fn ibv_wr_start(qp: *mut ibv_qp_ex) {
123 (*qp).wr_start.unwrap()(qp);
124}
125
126#[inline]
127pub unsafe fn ibv_wr_complete(qp: *mut ibv_qp_ex) -> c_int {
128 (*qp).wr_complete.unwrap()(qp)
129}
130
131#[inline]
132pub unsafe fn ibv_wr_abort(qp: *mut ibv_qp_ex) {
133 (*qp).wr_abort.unwrap()(qp)
134}
135
136#[inline]
138pub unsafe fn ibv_cq_ex_to_cq(cq: *mut ibv_cq_ex) -> *mut ibv_cq {
139 cq as *mut ibv_cq_ex as *mut ibv_cq
140}
141
142#[inline]
143pub unsafe fn ibv_start_poll(cq: *mut ibv_cq_ex, attr: *mut ibv_poll_cq_attr) -> c_int {
144 (*cq).start_poll.unwrap()(cq, attr)
145}
146
147#[inline]
148pub unsafe fn ibv_next_poll(cq: *mut ibv_cq_ex) -> c_int {
149 (*cq).next_poll.unwrap()(cq)
150}
151
152#[inline]
153pub unsafe fn ibv_end_poll(cq: *mut ibv_cq_ex) {
154 (*cq).end_poll.unwrap()(cq)
155}
156
157#[inline]
158pub unsafe fn ibv_wc_read_opcode(cq: *mut ibv_cq_ex) -> ibv_wc_opcode::Type {
159 (*cq).read_opcode.unwrap()(cq)
160}
161
162#[inline]
163pub unsafe fn ibv_wc_read_vendor_err(cq: *mut ibv_cq_ex) -> u32 {
164 (*cq).read_vendor_err.unwrap()(cq)
165}
166
167#[inline]
168pub unsafe fn ibv_wc_read_byte_len(cq: *mut ibv_cq_ex) -> u32 {
169 (*cq).read_byte_len.unwrap()(cq)
170}
171
172#[inline]
173pub unsafe fn ibv_wc_read_imm_data(cq: *mut ibv_cq_ex) -> __be32 {
174 (*cq).read_imm_data.unwrap()(cq)
175}
176
177#[inline]
178pub unsafe fn ibv_wc_read_invalidated_rkey(cq: *mut ibv_cq_ex) -> u32 {
179 (*cq).read_imm_data.unwrap()(cq)
185}
186
187#[inline]
188pub unsafe fn ibv_wc_read_qp_num(cq: *mut ibv_cq_ex) -> u32 {
189 (*cq).read_qp_num.unwrap()(cq)
190}
191
192#[inline]
193pub unsafe fn ibv_wc_read_src_qp(cq: *mut ibv_cq_ex) -> u32 {
194 (*cq).read_src_qp.unwrap()(cq)
195}
196
197#[inline]
198pub unsafe fn ibv_wc_read_wc_flags(cq: *mut ibv_cq_ex) -> c_uint {
199 (*cq).read_wc_flags.unwrap()(cq)
200}
201
202#[inline]
203pub unsafe fn ibv_wc_read_slid(cq: *mut ibv_cq_ex) -> u32 {
204 (*cq).read_slid.unwrap()(cq)
205}
206
207#[inline]
208pub unsafe fn ibv_wc_read_sl(cq: *mut ibv_cq_ex) -> u8 {
209 (*cq).read_sl.unwrap()(cq)
210}
211
212#[inline]
213pub unsafe fn ibv_wc_read_dlid_path_bits(cq: *mut ibv_cq_ex) -> u8 {
214 (*cq).read_dlid_path_bits.unwrap()(cq)
215}
216
217#[inline]
218pub unsafe fn ibv_wc_read_completion_ts(cq: *mut ibv_cq_ex) -> u64 {
219 (*cq).read_completion_ts.unwrap()(cq)
220}
221
222#[inline]
223pub unsafe fn ibv_wc_read_completion_wallclock_ns(cq: *mut ibv_cq_ex) -> u64 {
224 (*cq).read_completion_wallclock_ns.unwrap()(cq)
225}
226
227#[inline]
228pub unsafe fn ibv_wc_read_cvlan(cq: *mut ibv_cq_ex) -> u16 {
229 (*cq).read_cvlan.unwrap()(cq)
230}
231
232#[inline]
233pub unsafe fn ibv_wc_read_flow_tag(cq: *mut ibv_cq_ex) -> u32 {
234 (*cq).read_flow_tag.unwrap()(cq)
235}
236
237#[inline]
238pub unsafe fn ibv_wc_read_tm_info(cq: *mut ibv_cq_ex, tm_info: *mut ibv_wc_tm_info) {
239 (*cq).read_tm_info.unwrap()(cq, tm_info)
240}
241
242#[inline]
244pub unsafe fn ibv_post_wq_recv(
245 wq: *mut ibv_wq,
246 recv_wr: *mut ibv_recv_wr,
247 bad_recv_wr: *mut *mut ibv_recv_wr,
248) -> c_int {
249 (*wq).post_recv.unwrap()(wq, recv_wr, bad_recv_wr)
250}
251
252macro_rules! container_of {
254 ($ptr:expr, $container:path, $field:ident) => {{
255 ($ptr as *const _ as *const u8).sub(memoffset::offset_of!($container, $field))
256 as *const $container
257 }};
258}
259
260#[inline]
262unsafe fn verbs_get_ctx(ctx: *const ibv_context) -> Option<*mut verbs_context> {
263 if (*ctx).abi_compat as usize != u32::MAX as usize {
264 None
265 } else {
266 let vcp = container_of!(ctx, verbs_context, context) as *mut _;
267 Some(vcp)
268 }
269}
270
271macro_rules! verbs_get_ctx_op {
272 ($vcr:expr, $field:ident) => {
273 if let Some(vc) = verbs_get_ctx($vcr) {
274 if (*vc).sz < mem::size_of_val(&*vc) - memoffset::offset_of!(verbs_context, $field) {
275 None
276 } else {
277 if (*vc).$field.is_some() {
278 Some(vc)
279 } else {
280 None
281 }
282 }
283 } else {
284 None
285 }
286 };
287}
288
289pub unsafe fn __ibv_get_device_list(num_devices: *mut c_int) -> *mut *mut ibv_device {
318 ibv_get_device_list(num_devices)
321}
322
323#[inline]
328pub unsafe fn ___ibv_query_port(
329 context: *mut ibv_context,
330 port_num: u8,
331 port_attr: *mut ibv_port_attr,
332) -> c_int {
333 let vcr = verbs_get_ctx_op!(context, query_port);
334
335 if let Some(vctx) = vcr {
336 (*vctx).query_port.unwrap()(context, port_num, port_attr, mem::size_of_val(&*port_attr))
337 } else {
338 let compat_attr = port_attr as *mut _ as *mut _compat_ibv_port_attr;
340 ibv_query_port(context, port_num, compat_attr)
341 }
342}
343
344#[inline]
346pub unsafe fn ibv_create_flow(qp: *mut ibv_qp, flow: *mut ibv_flow_attr) -> Option<*mut ibv_flow> {
347 let vcr = verbs_get_ctx_op!((*qp).context, ibv_create_flow);
348
349 if let Some(vctx) = vcr {
350 Some((*vctx).ibv_create_flow.unwrap()(qp, flow))
351 } else {
352 *libc::__errno_location() = libc::EOPNOTSUPP;
353 None
354 }
355}
356
357#[inline]
358pub unsafe fn ibv_destroy_flow(flow_id: *mut ibv_flow) -> c_int {
359 let vcr = verbs_get_ctx_op!((*flow_id).context, ibv_destroy_flow);
360
361 if let Some(vctx) = vcr {
362 (*vctx).ibv_destroy_flow.unwrap()(flow_id)
363 } else {
364 libc::EOPNOTSUPP
365 }
366}
367
368#[inline]
369pub unsafe fn ibv_create_flow_action_esp(
370 ctx: *mut ibv_context,
371 esp: *mut ibv_flow_action_esp_attr,
372) -> Option<*mut ibv_flow_action> {
373 let vcr = verbs_get_ctx_op!(ctx, create_flow_action_esp);
374
375 if let Some(vctx) = vcr {
376 Some((*vctx).create_flow_action_esp.unwrap()(ctx, esp))
377 } else {
378 *libc::__errno_location() = libc::EOPNOTSUPP;
379 None
380 }
381}
382
383#[inline]
384pub unsafe fn ibv_modify_flow_action_esp(
385 action: *mut ibv_flow_action,
386 esp: *mut ibv_flow_action_esp_attr,
387) -> c_int {
388 let vcr = verbs_get_ctx_op!((*action).context, modify_flow_action_esp);
389
390 if let Some(vctx) = vcr {
391 (*vctx).modify_flow_action_esp.unwrap()(action, esp)
392 } else {
393 libc::EOPNOTSUPP
394 }
395}
396
397#[inline]
398pub unsafe fn ibv_destroy_flow_action(action: *mut ibv_flow_action) -> c_int {
399 let vcr = verbs_get_ctx_op!((*action).context, destroy_flow_action);
400
401 if let Some(vctx) = vcr {
402 (*vctx).destroy_flow_action.unwrap()(action)
403 } else {
404 libc::EOPNOTSUPP
405 }
406}
407
408#[inline]
410pub unsafe fn ibv_open_xrcd(
411 context: *mut ibv_context,
412 xrcd_init_attr: *mut ibv_xrcd_init_attr,
413) -> Option<*mut ibv_xrcd> {
414 let vcr = verbs_get_ctx_op!(context, open_xrcd);
415
416 if let Some(vctx) = vcr {
417 Some((*vctx).open_xrcd.unwrap()(context, xrcd_init_attr))
418 } else {
419 *libc::__errno_location() = libc::EOPNOTSUPP;
420 None
421 }
422}
423
424#[inline]
425pub unsafe fn ibv_close_xrcd(xrcd: *mut ibv_xrcd) -> c_int {
426 let vctx = verbs_get_ctx((*xrcd).context);
427
428 (*vctx.unwrap()).close_xrcd.unwrap()(xrcd)
429}
430
431#[inline]
433pub unsafe fn __ibv_reg_mr(
434 pd: *mut ibv_pd,
435 addr: *mut c_void,
436 length: usize,
437 access: c_uint,
438 is_access_const: c_int,
439) -> *mut ibv_mr {
440 if is_access_const != 0
441 && (ib_uverbs_access_flags(access)
442 & ib_uverbs_access_flags::IB_UVERBS_ACCESS_OPTIONAL_RANGE)
443 == ib_uverbs_access_flags(0)
444 {
445 ibv_reg_mr(pd, addr, length, access as c_int)
446 } else {
447 ibv_reg_mr_iova2(pd, addr, length, addr as u64, access)
448 }
449}
450#[inline]
458pub unsafe fn __ibv_reg_mr_iova(
459 pd: *mut ibv_pd,
460 addr: *mut c_void,
461 length: usize,
462 iova: u64,
463 access: c_uint,
464 is_access_const: c_int,
465) -> *mut ibv_mr {
466 if is_access_const != 0
467 && (ib_uverbs_access_flags(access)
468 & ib_uverbs_access_flags::IB_UVERBS_ACCESS_OPTIONAL_RANGE)
469 == ib_uverbs_access_flags(0)
470 {
471 ibv_reg_mr_iova(pd, addr, length, iova, access as c_int)
472 } else {
473 ibv_reg_mr_iova2(pd, addr, length, iova, access)
474 }
475}
476#[inline]
484pub unsafe fn ibv_alloc_mw(pd: *mut ibv_pd, type_: ibv_mw_type::Type) -> Option<*mut ibv_mw> {
485 if (*(*pd).context).ops.alloc_mw.is_some() {
486 Some((*(*pd).context).ops.alloc_mw.unwrap()(pd, type_))
487 } else {
488 *libc::__errno_location() = libc::EOPNOTSUPP;
489 None
490 }
491}
492
493#[inline]
494pub unsafe fn ibv_dealloc_mw(mw: *mut ibv_mw) -> c_int {
495 (*(*mw).context).ops.dealloc_mw.unwrap()(mw)
496}
497
498#[inline]
500pub unsafe fn ibv_inc_rkey(rkey: u32) -> u32 {
501 let mask: u32 = 0x000000ff;
502 let newtag = ((rkey + 1) & mask) as u8;
503
504 (rkey & !mask) | (newtag as u32)
505}
506
507#[inline]
508pub unsafe fn ibv_bind_mw(qp: *mut ibv_qp, mw: *mut ibv_mw, mw_bind: *mut ibv_mw_bind) -> c_int {
509 if (*mw).type_ != ibv_mw_type::IBV_MW_TYPE_1 {
510 libc::EINVAL
511 } else {
512 (*(*mw).context).ops.bind_mw.unwrap()(qp, mw, mw_bind)
513 }
514}
515
516#[inline]
517pub unsafe fn ibv_advise_mr(
518 pd: *mut ibv_pd,
519 advice: ibv_advise_mr_advice,
520 flags: u32,
521 sg_list: *mut ibv_sge,
522 num_sge: u32,
523) -> c_int {
524 let vcr = verbs_get_ctx_op!((*pd).context, advise_mr);
525
526 if let Some(vctx) = vcr {
527 (*vctx).advise_mr.unwrap()(pd, advice, flags, sg_list, num_sge)
528 } else {
529 libc::EOPNOTSUPP
530 }
531}
532
533#[inline]
535pub unsafe fn ibv_alloc_dm(
536 context: *mut ibv_context,
537 attr: *mut ibv_alloc_dm_attr,
538) -> Option<*mut ibv_dm> {
539 let vcr = verbs_get_ctx_op!(context, alloc_dm);
540
541 if let Some(vctx) = vcr {
542 Some((*vctx).alloc_dm.unwrap()(context, attr))
543 } else {
544 *libc::__errno_location() = libc::EOPNOTSUPP;
545 None
546 }
547}
548
549#[inline]
550pub unsafe fn ibv_free_dm(dm: *mut ibv_dm) -> c_int {
551 let vcr = verbs_get_ctx_op!((*dm).context, free_dm);
552
553 if let Some(vctx) = vcr {
554 (*vctx).free_dm.unwrap()(dm)
555 } else {
556 libc::EOPNOTSUPP
557 }
558}
559
560#[inline]
561pub unsafe fn ibv_memcpy_to_dm(
562 dm: *mut ibv_dm,
563 dm_offset: u64,
564 host_addr: *const c_void,
565 length: usize,
566) -> c_int {
567 (*dm).memcpy_to_dm.unwrap()(dm, dm_offset, host_addr, length)
568}
569
570#[inline]
571pub unsafe fn ibv_memcpy_from_dm(
572 host_addr: *mut c_void,
573 dm: *mut ibv_dm,
574 dm_offset: u64,
575 length: usize,
576) -> c_int {
577 (*dm).memcpy_from_dm.unwrap()(host_addr, dm, dm_offset, length)
578}
579
580#[inline]
581pub unsafe fn ibv_alloc_null_mr(pd: *mut ibv_pd) -> Option<*mut ibv_mr> {
582 let vcr = verbs_get_ctx_op!((*pd).context, alloc_null_mr);
583
584 if let Some(vctx) = vcr {
585 Some((*vctx).alloc_null_mr.unwrap()(pd))
586 } else {
587 *libc::__errno_location() = libc::EOPNOTSUPP;
588 None
589 }
590}
591
592#[inline]
593pub unsafe fn ibv_reg_dm_mr(
594 pd: *mut ibv_pd,
595 dm: *mut ibv_dm,
596 dm_offset: u64,
597 length: usize,
598 access: u32,
599) -> Option<*mut ibv_mr> {
600 let vcr = verbs_get_ctx_op!((*pd).context, reg_dm_mr);
601
602 if let Some(vctx) = vcr {
603 Some((*vctx).reg_dm_mr.unwrap()(
604 pd, dm, dm_offset, length, access,
605 ))
606 } else {
607 *libc::__errno_location() = libc::EOPNOTSUPP;
608 None
609 }
610}
611
612#[inline]
614pub unsafe fn ibv_create_cq_ex(
615 context: *mut ibv_context,
616 cq_attr: *mut ibv_cq_init_attr_ex,
617) -> Option<*mut ibv_cq_ex> {
618 let vcr = verbs_get_ctx_op!(context, create_cq_ex);
619
620 if let Some(vctx) = vcr {
621 Some((*vctx).create_cq_ex.unwrap()(context, cq_attr))
622 } else {
623 *libc::__errno_location() = libc::EOPNOTSUPP;
624 None
625 }
626}
627
628#[inline]
630pub unsafe fn ibv_poll_cq(cq: *mut ibv_cq, num_entries: i32, wc: *mut ibv_wc) -> c_int {
631 (*(*cq).context).ops.poll_cq.unwrap()(cq, num_entries, wc)
632}
633
634#[inline]
635pub unsafe fn ibv_req_notify_cq(cq: *mut ibv_cq, solicited_only: i32) -> c_int {
636 (*(*cq).context).ops.req_notify_cq.unwrap()(cq, solicited_only)
637}
638
639#[inline]
640pub unsafe fn ibv_modify_cq(cq: *mut ibv_cq, attr: *mut ibv_modify_cq_attr) -> c_int {
641 let vcr = verbs_get_ctx_op!((*cq).context, modify_cq);
642
643 if let Some(vctx) = vcr {
644 (*vctx).modify_cq.unwrap()(cq, attr)
645 } else {
646 libc::EOPNOTSUPP
647 }
648}
649
650#[inline]
652pub unsafe fn ibv_create_srq_ex(
653 context: *mut ibv_context,
654 srq_init_attr_ex: *mut ibv_srq_init_attr_ex,
655) -> Option<*mut ibv_srq> {
656 let mask = ibv_srq_init_attr_mask((*srq_init_attr_ex).comp_mask);
657 let mask_inv = ibv_srq_init_attr_mask(!(*srq_init_attr_ex).comp_mask);
658 let zero = ibv_srq_init_attr_mask(0);
659
660 let cond = (mask_inv
662 | (ibv_srq_init_attr_mask::IBV_SRQ_INIT_ATTR_PD
663 & ibv_srq_init_attr_mask::IBV_SRQ_INIT_ATTR_TYPE))
664 != zero
665 && (mask & ibv_srq_init_attr_mask::IBV_SRQ_INIT_ATTR_PD) != zero
666 && ((mask & ibv_srq_init_attr_mask::IBV_SRQ_INIT_ATTR_TYPE) != zero
667 || ((*srq_init_attr_ex).srq_type == ibv_srq_type::IBV_SRQT_BASIC));
668 if cond {
669 Some(ibv_create_srq(
670 (*srq_init_attr_ex).pd,
671 srq_init_attr_ex as *mut ibv_srq_init_attr,
672 ))
673 } else {
674 let vcr = verbs_get_ctx_op!(context, create_srq_ex);
675
676 if let Some(vctx) = vcr {
677 Some((*vctx).create_srq_ex.unwrap()(context, srq_init_attr_ex))
678 } else {
679 *libc::__errno_location() = libc::EOPNOTSUPP;
680 None
681 }
682 }
683}
684
685#[inline]
686pub unsafe fn ibv_get_srq_num(srq: *mut ibv_srq, srq_num: *mut u32) -> c_int {
687 let vcr = verbs_get_ctx_op!((*srq).context, get_srq_num);
688
689 if let Some(vctx) = vcr {
690 (*vctx).get_srq_num.unwrap()(srq, srq_num)
691 } else {
692 libc::EOPNOTSUPP
693 }
694}
695
696#[inline]
697pub unsafe fn ibv_post_srq_recv(
698 srq: *mut ibv_srq,
699 recv_wr: *mut ibv_recv_wr,
700 bad_recv_wr: *mut *mut ibv_recv_wr,
701) -> c_int {
702 (*(*srq).context).ops.post_srq_recv.unwrap()(srq, recv_wr, bad_recv_wr)
703}
704
705#[inline]
706pub unsafe fn ibv_post_srq_ops(
707 srq: *mut ibv_srq,
708 op: *mut ibv_ops_wr,
709 bad_op: *mut *mut ibv_ops_wr,
710) -> c_int {
711 let vcr = verbs_get_ctx_op!((*srq).context, post_srq_ops);
712
713 if let Some(vctx) = vcr {
714 (*vctx).post_srq_ops.unwrap()(srq, op, bad_op)
715 } else {
716 *bad_op = op;
717 libc::EOPNOTSUPP
718 }
719}
720
721#[inline]
723pub unsafe fn ibv_create_qp_ex(
724 context: *mut ibv_context,
725 qp_init_attr_ex: *mut ibv_qp_init_attr_ex,
726) -> Option<*mut ibv_qp> {
727 let mask = ibv_qp_init_attr_mask((*qp_init_attr_ex).comp_mask);
728
729 if mask == ibv_qp_init_attr_mask::IBV_QP_INIT_ATTR_PD {
730 Some(ibv_create_qp(
731 (*qp_init_attr_ex).pd,
732 qp_init_attr_ex as *mut ibv_qp_init_attr,
733 ))
734 } else {
735 let vcr = verbs_get_ctx_op!(context, create_qp_ex);
736
737 if let Some(vctx) = vcr {
738 Some((*vctx).create_qp_ex.unwrap()(context, qp_init_attr_ex))
739 } else {
740 *libc::__errno_location() = libc::EOPNOTSUPP;
741 None
742 }
743 }
744}
745
746#[inline]
748pub unsafe fn ibv_alloc_td(
749 context: *mut ibv_context,
750 init_attr: *mut ibv_td_init_attr,
751) -> Option<*mut ibv_td> {
752 let vcr = verbs_get_ctx_op!(context, alloc_td);
753
754 if let Some(vctx) = vcr {
755 Some((*vctx).alloc_td.unwrap()(context, init_attr))
756 } else {
757 *libc::__errno_location() = libc::EOPNOTSUPP;
758 None
759 }
760}
761
762#[inline]
763pub unsafe fn ibv_dealloc_td(td: *mut ibv_td) -> c_int {
764 let vcr = verbs_get_ctx_op!((*td).context, dealloc_td);
765
766 if let Some(vctx) = vcr {
767 (*vctx).dealloc_td.unwrap()(td)
768 } else {
769 libc::EOPNOTSUPP
770 }
771}
772
773#[inline]
775pub unsafe fn ibv_alloc_parent_domain(
776 context: *mut ibv_context,
777 attr: *mut ibv_parent_domain_init_attr,
778) -> Option<*mut ibv_pd> {
779 let vcr = verbs_get_ctx_op!(context, alloc_parent_domain);
780
781 if let Some(vctx) = vcr {
782 Some((*vctx).alloc_parent_domain.unwrap()(context, attr))
783 } else {
784 *libc::__errno_location() = libc::EOPNOTSUPP;
785 None
786 }
787}
788
789#[inline]
791pub unsafe fn ibv_query_rt_values_ex(
792 context: *mut ibv_context,
793 values: *mut ibv_values_ex,
794) -> c_int {
795 let vcr = verbs_get_ctx_op!(context, query_rt_values);
796
797 if let Some(vctx) = vcr {
798 (*vctx).query_rt_values.unwrap()(context, values)
799 } else {
800 libc::EOPNOTSUPP
801 }
802}
803
804#[inline]
805pub unsafe fn ibv_query_device_ex(
806 context: *mut ibv_context,
807 input: *const ibv_query_device_ex_input,
808 attr: *mut ibv_device_attr_ex,
809) -> c_int {
810 let vcr = verbs_get_ctx_op!(context, query_device_ex);
811
812 if let Some(vctx) = vcr {
813 let ret = (*vctx).query_device_ex.unwrap()(context, input, attr, mem::size_of_val(&*attr));
814 if ret != libc::EOPNOTSUPP {
815 return ret;
816 }
817 }
818
819 ibv_query_device(context, &mut (*attr).orig_attr)
821}
822
823#[inline]
825pub unsafe fn ibv_open_qp(
826 context: *mut ibv_context,
827 qp_open_attr: *mut ibv_qp_open_attr,
828) -> Option<*mut ibv_qp> {
829 let vcr = verbs_get_ctx_op!(context, open_qp);
830
831 if let Some(vctx) = vcr {
832 Some((*vctx).open_qp.unwrap()(context, qp_open_attr))
833 } else {
834 *libc::__errno_location() = libc::EOPNOTSUPP;
835 None
836 }
837}
838
839#[inline]
840pub unsafe fn ibv_modify_qp_rate_limit(
841 qp: *mut ibv_qp,
842 attr: *mut ibv_qp_rate_limit_attr,
843) -> c_int {
844 let vcr = verbs_get_ctx_op!((*qp).context, modify_qp_rate_limit);
845
846 if let Some(vctx) = vcr {
847 (*vctx).modify_qp_rate_limit.unwrap()(qp, attr)
848 } else {
849 libc::EOPNOTSUPP
850 }
851}
852
853#[inline]
855pub unsafe fn ibv_create_wq(
856 context: *mut ibv_context,
857 wq_init_attr: *mut ibv_wq_init_attr,
858) -> Option<*mut ibv_wq> {
859 let vcr = verbs_get_ctx_op!(context, create_wq);
860
861 if let Some(vctx) = vcr {
862 let wq = (*vctx).create_wq.unwrap()(context, wq_init_attr);
863 if wq != (ptr::null::<ibv_wq>() as *mut _) {
864 (*wq).events_completed = 0;
865 libc::pthread_mutex_init(
866 &mut (*wq).mutex,
867 ptr::null::<libc::pthread_mutexattr_t>() as *mut _,
868 );
869 libc::pthread_cond_init(
870 &mut (*wq).cond,
871 ptr::null::<libc::pthread_condattr_t>() as *mut _,
872 );
873 }
874 Some(wq)
875 } else {
876 *libc::__errno_location() = libc::EOPNOTSUPP;
877 None
878 }
879}
880
881#[inline]
882pub unsafe fn ibv_modify_wq(wq: *mut ibv_wq, wq_attr: *mut ibv_wq_attr) -> c_int {
883 let vcr = verbs_get_ctx_op!((*wq).context, modify_wq);
884
885 if let Some(vctx) = vcr {
886 (*vctx).modify_wq.unwrap()(wq, wq_attr)
887 } else {
888 libc::EOPNOTSUPP
889 }
890}
891
892#[inline]
893pub unsafe fn ibv_destroy_wq(wq: *mut ibv_wq) -> c_int {
894 let vcr = verbs_get_ctx_op!((*wq).context, destroy_wq);
895
896 if let Some(vctx) = vcr {
897 (*vctx).destroy_wq.unwrap()(wq)
898 } else {
899 libc::EOPNOTSUPP
900 }
901}
902
903#[inline]
905pub unsafe fn ibv_create_rwq_ind_table(
906 context: *mut ibv_context,
907 init_attr: *mut ibv_rwq_ind_table_init_attr,
908) -> Option<*mut ibv_rwq_ind_table> {
909 let vcr = verbs_get_ctx_op!(context, create_rwq_ind_table);
910
911 if let Some(vctx) = vcr {
912 Some((*vctx).create_rwq_ind_table.unwrap()(context, init_attr))
913 } else {
914 *libc::__errno_location() = libc::EOPNOTSUPP;
915 None
916 }
917}
918
919#[inline]
920pub unsafe fn ibv_destroy_rwq_ind_table(rwq_ind_table: *mut ibv_rwq_ind_table) -> c_int {
921 let vcr = verbs_get_ctx_op!((*rwq_ind_table).context, destroy_rwq_ind_table);
922
923 if let Some(vctx) = vcr {
924 (*vctx).destroy_rwq_ind_table.unwrap()(rwq_ind_table)
925 } else {
926 libc::EOPNOTSUPP
927 }
928}
929
930#[inline]
933pub unsafe fn ibv_post_send(
934 qp: *mut ibv_qp,
935 wr: *mut ibv_send_wr,
936 bad_wr: *mut *mut ibv_send_wr,
937) -> c_int {
938 (*(*qp).context).ops.post_send.unwrap()(qp, wr, bad_wr)
939}
940
941#[inline]
942pub unsafe fn ibv_post_recv(
943 qp: *mut ibv_qp,
944 wr: *mut ibv_recv_wr,
945 bad_wr: *mut *mut ibv_recv_wr,
946) -> c_int {
947 (*(*qp).context).ops.post_recv.unwrap()(qp, wr, bad_wr)
948}
949
950#[inline]
951pub unsafe fn ibv_is_qpt_supported(caps: u32, qpt: ibv_qp_type::Type) -> c_int {
952 !!(caps & (1 << qpt)) as c_int
953}
954
955#[inline]
957pub unsafe fn ibv_create_counters(
958 context: *mut ibv_context,
959 init_attr: *mut ibv_counters_init_attr,
960) -> Option<*mut ibv_counters> {
961 let vcr = verbs_get_ctx_op!(context, create_counters);
962
963 if let Some(vctx) = vcr {
964 Some((*vctx).create_counters.unwrap()(context, init_attr))
965 } else {
966 *libc::__errno_location() = libc::EOPNOTSUPP;
967 None
968 }
969}
970
971#[inline]
972pub unsafe fn ibv_destroy_counters(counters: *mut ibv_counters) -> c_int {
973 let vcr = verbs_get_ctx_op!((*counters).context, destroy_counters);
974
975 if let Some(vctx) = vcr {
976 (*vctx).destroy_counters.unwrap()(counters)
977 } else {
978 libc::EOPNOTSUPP
979 }
980}
981
982#[inline]
983pub unsafe fn ibv_attach_counters_point_flow(
984 counters: *mut ibv_counters,
985 attr: *mut ibv_counter_attach_attr,
986 flow: *mut ibv_flow,
987) -> c_int {
988 let vcr = verbs_get_ctx_op!((*counters).context, attach_counters_point_flow);
989
990 if let Some(vctx) = vcr {
991 (*vctx).attach_counters_point_flow.unwrap()(counters, attr, flow)
992 } else {
993 libc::EOPNOTSUPP
994 }
995}
996
997#[inline]
998pub unsafe fn ibv_read_counters(
999 counters: *mut ibv_counters,
1000 counters_value: *mut u64,
1001 ncounters: u32,
1002 flags: u32,
1003) -> c_int {
1004 let vcr = verbs_get_ctx_op!((*counters).context, read_counters);
1005
1006 if let Some(vctx) = vcr {
1007 (*vctx).read_counters.unwrap()(counters, counters_value, ncounters, flags)
1008 } else {
1009 libc::EOPNOTSUPP
1010 }
1011}
1012
1013pub const RDMA_IB_IP_PS_MASK: u64 = 0xFFFFFFFFFFFF0000;
1016pub const RDMA_IB_IP_PORT_MASK: u64 = 0x000000000000FFFF;
1017pub const RDMA_IB_IP_PS_TCP: u64 = 0x0000000001060000;
1018pub const RDMA_IB_IP_PS_UDP: u64 = 0x0000000001110000;
1019pub const RDMA_IB_PS_IB: u64 = 0x00000000013F0000;
1020
1021pub const RDMA_UDP_QKEY: u32 = 0x01234567;
1022
1023pub const RAI_PASSIVE: u32 = 0x00000001;
1024pub const RAI_NUMERICHOST: u32 = 0x00000002;
1025pub const RAI_NOROUTE: u32 = 0x00000004;
1026pub const RAI_FAMILY: u32 = 0x00000008;
1027
1028#[inline]
1029pub unsafe fn rdma_get_local_addr(id: &rdma_cm_id) -> &libc::sockaddr {
1030 &id.route.addr.src_addr_union.src_addr
1031}
1032
1033#[inline]
1034pub unsafe fn rdma_get_peer_addr(id: &rdma_cm_id) -> &libc::sockaddr {
1035 &id.route.addr.dst_addr_union.dst_addr
1036}
1037
1038#[inline]
1041pub unsafe fn rdma_seterrno(ret: c_int) -> c_int {
1042 if ret != 0 {
1043 *libc::__errno_location() = ret;
1044 -1
1045 } else {
1046 ret
1047 }
1048}
1049
1050#[inline]
1051pub unsafe fn rdma_reg_msgs(id: *mut rdma_cm_id, addr: *mut c_void, length: usize) -> *mut ibv_mr {
1052 ibv_reg_mr(
1053 (*id).pd,
1054 addr,
1055 length,
1056 ibv_access_flags::IBV_ACCESS_LOCAL_WRITE.0 as c_int,
1057 )
1058}
1059
1060#[inline]
1061pub unsafe fn rdma_reg_read(id: *mut rdma_cm_id, addr: *mut c_void, length: usize) -> *mut ibv_mr {
1062 ibv_reg_mr(
1063 (*id).pd,
1064 addr,
1065 length,
1066 (ibv_access_flags::IBV_ACCESS_LOCAL_WRITE | ibv_access_flags::IBV_ACCESS_REMOTE_READ).0
1067 as c_int,
1068 )
1069}
1070
1071#[inline]
1072pub unsafe fn rdma_reg_write(id: *mut rdma_cm_id, addr: *mut c_void, length: usize) -> *mut ibv_mr {
1073 ibv_reg_mr(
1074 (*id).pd,
1075 addr,
1076 length,
1077 (ibv_access_flags::IBV_ACCESS_LOCAL_WRITE | ibv_access_flags::IBV_ACCESS_REMOTE_WRITE).0
1078 as c_int,
1079 )
1080}
1081
1082#[inline]
1083pub unsafe fn rdma_dereg_mr(mr: *mut ibv_mr) -> c_int {
1084 rdma_seterrno(ibv_dereg_mr(mr))
1085}
1086
1087#[inline]
1088pub unsafe fn rdma_post_recvv(
1089 id: *mut rdma_cm_id,
1090 context: *mut c_void,
1091 sgl: *mut ibv_sge,
1092 nsge: c_int,
1093) -> c_int {
1094 let mut wr = ibv_recv_wr {
1095 wr_id: context as u64,
1096 next: ptr::null::<ibv_recv_wr>() as *mut _,
1097 sg_list: sgl,
1098 num_sge: nsge,
1099 };
1100 let mut bad = ptr::null::<ibv_recv_wr>() as *mut _;
1101
1102 if (*id).srq as usize != 0 {
1103 rdma_seterrno(ibv_post_srq_recv((*id).srq, &mut wr, &mut bad))
1104 } else {
1105 rdma_seterrno(ibv_post_recv((*id).qp, &mut wr, &mut bad))
1106 }
1107}
1108
1109#[inline]
1110pub unsafe fn rdma_post_sendv(
1111 id: *mut rdma_cm_id,
1112 context: *mut c_void,
1113 sgl: *mut ibv_sge,
1114 nsge: c_int,
1115 flags: c_int,
1116) -> c_int {
1117 let mut wr = std::mem::zeroed::<ibv_send_wr>();
1118 wr.wr_id = context as u64;
1119 wr.next = ptr::null::<ibv_send_wr>() as *mut _;
1120 wr.sg_list = sgl;
1121 wr.num_sge = nsge;
1122 wr.opcode = ibv_wr_opcode::IBV_WR_SEND;
1123 wr.send_flags = flags as c_uint;
1124 let mut bad = ptr::null::<ibv_send_wr>() as *mut _;
1125
1126 rdma_seterrno(ibv_post_send((*id).qp, &mut wr, &mut bad))
1127}
1128
1129#[inline]
1130pub unsafe fn rdma_post_readv(
1131 id: *mut rdma_cm_id,
1132 context: *mut c_void,
1133 sgl: *mut ibv_sge,
1134 nsge: c_int,
1135 flags: c_int,
1136 remote_addr: u64,
1137 rkey: u32,
1138) -> c_int {
1139 let mut wr = std::mem::zeroed::<ibv_send_wr>();
1140 wr.wr_id = context as u64;
1141 wr.next = ptr::null::<ibv_send_wr>() as *mut _;
1142 wr.sg_list = sgl;
1143 wr.num_sge = nsge;
1144 wr.opcode = ibv_wr_opcode::IBV_WR_RDMA_READ;
1145 wr.send_flags = flags as c_uint;
1146 wr.wr = wr_t {
1147 rdma: rdma_t { remote_addr, rkey },
1148 };
1149 let mut bad = ptr::null::<ibv_send_wr>() as *mut _;
1150
1151 rdma_seterrno(ibv_post_send((*id).qp, &mut wr, &mut bad))
1152}
1153
1154#[inline]
1155pub unsafe fn rdma_post_writev(
1156 id: *mut rdma_cm_id,
1157 context: *mut c_void,
1158 sgl: *mut ibv_sge,
1159 nsge: c_int,
1160 flags: c_int,
1161 remote_addr: u64,
1162 rkey: u32,
1163) -> c_int {
1164 let mut wr = std::mem::zeroed::<ibv_send_wr>();
1165 wr.wr_id = context as u64;
1166 wr.next = ptr::null::<ibv_send_wr>() as *mut _;
1167 wr.sg_list = sgl;
1168 wr.num_sge = nsge;
1169 wr.opcode = ibv_wr_opcode::IBV_WR_RDMA_WRITE;
1170 wr.send_flags = flags as c_uint;
1171 wr.wr = wr_t {
1172 rdma: rdma_t { remote_addr, rkey },
1173 };
1174 let mut bad = ptr::null::<ibv_send_wr>() as *mut _;
1175
1176 rdma_seterrno(ibv_post_send((*id).qp, &mut wr, &mut bad))
1177}
1178
1179#[inline]
1180pub unsafe fn rdma_post_recv(
1181 id: *mut rdma_cm_id,
1182 context: *mut c_void,
1183 addr: *mut c_void,
1184 length: usize,
1185 mr: *mut ibv_mr,
1186) -> c_int {
1187 assert!(
1188 addr >= (*mr).addr && (addr as usize + length <= (*mr).addr as usize + (*mr).length),
1189 "invalid addr={} and length={}",
1190 addr as usize,
1191 length,
1192 );
1193 let mut sge = ibv_sge {
1194 addr: addr as u64,
1195 length: length as u32,
1196 lkey: (*mr).lkey,
1197 };
1198 let nsge = 1;
1199 rdma_post_recvv(id, context, &mut sge, nsge)
1200}
1201
1202#[inline]
1203pub unsafe fn rdma_post_send(
1204 id: *mut rdma_cm_id,
1205 context: *mut c_void,
1206 addr: *mut c_void,
1207 length: usize,
1208 mr: *mut ibv_mr,
1209 flags: c_int,
1210) -> c_int {
1211 let mut sge = ibv_sge {
1212 addr: addr as u64,
1213 length: length as u32,
1214 lkey: if !mr.is_null() { (*mr).lkey } else { 0 },
1215 };
1216 let nsge = 1;
1217 rdma_post_sendv(id, context, &mut sge, nsge, flags)
1218}
1219
1220#[inline]
1221pub unsafe fn rdma_post_read(
1222 id: *mut rdma_cm_id,
1223 context: *mut c_void,
1224 addr: *mut c_void,
1225 length: usize,
1226 mr: *mut ibv_mr,
1227 flags: c_int,
1228 remote_addr: u64,
1229 rkey: u32,
1230) -> c_int {
1231 let mut sge = ibv_sge {
1232 addr: addr as u64,
1233 length: length as u32,
1234 lkey: (*mr).lkey,
1235 };
1236 let nsge = 1;
1237 rdma_post_readv(id, context, &mut sge, nsge, flags, remote_addr, rkey)
1238}
1239
1240#[inline]
1241pub unsafe fn rdma_post_write(
1242 id: *mut rdma_cm_id,
1243 context: *mut c_void,
1244 addr: *mut c_void,
1245 length: usize,
1246 mr: *mut ibv_mr,
1247 flags: c_int,
1248 remote_addr: u64,
1249 rkey: u32,
1250) -> c_int {
1251 let mut sge = ibv_sge {
1252 addr: addr as u64,
1253 length: length as u32,
1254 lkey: if !mr.is_null() { (*mr).lkey } else { 0 },
1255 };
1256 let nsge = 1;
1257 rdma_post_writev(id, context, &mut sge, nsge, flags, remote_addr, rkey)
1258}
1259
1260#[inline]
1261pub unsafe fn rdma_post_ud_send(
1262 id: *mut rdma_cm_id,
1263 context: *mut c_void,
1264 addr: *mut c_void,
1265 length: usize,
1266 mr: *mut ibv_mr,
1267 flags: c_int,
1268 ah: *mut ibv_ah,
1269 remote_qpn: u32,
1270) -> c_int {
1271 let mut sge = ibv_sge {
1272 addr: addr as u64,
1273 length: length as u32,
1274 lkey: if !mr.is_null() { (*mr).lkey } else { 0 },
1275 };
1276
1277 let mut wr = std::mem::zeroed::<ibv_send_wr>();
1278 wr.wr_id = context as u64;
1279 wr.next = ptr::null::<ibv_send_wr>() as *mut _;
1280 wr.sg_list = &mut sge;
1281 wr.num_sge = 1;
1282 wr.opcode = ibv_wr_opcode::IBV_WR_SEND;
1283 wr.send_flags = flags as c_uint;
1284 wr.wr = wr_t {
1285 ud: ud_t {
1286 ah,
1287 remote_qpn,
1288 remote_qkey: RDMA_UDP_QKEY,
1289 },
1290 };
1291 let mut bad = ptr::null::<ibv_send_wr>() as *mut _;
1292
1293 rdma_seterrno(ibv_post_send((*id).qp, &mut wr, &mut bad))
1294}
1295
1296#[inline]
1297pub unsafe fn rdma_get_send_comp(id: *mut rdma_cm_id, wc: *mut ibv_wc) -> c_int {
1298 let mut ret: c_int;
1299 let mut cq = ptr::null::<ibv_cq>() as *mut _;
1300 let mut context = ptr::null::<c_void>() as *mut _;
1301 let nevents = 1;
1302 let num_entries = 1;
1303 let solicited_only = 0;
1304
1305 loop {
1306 ret = ibv_poll_cq((*id).send_cq, num_entries, wc);
1307 if ret != 0 {
1308 break;
1309 }
1310 ret = ibv_req_notify_cq((*id).send_cq, solicited_only);
1311 if ret != 0 {
1312 return rdma_seterrno(ret);
1313 }
1314 ret = ibv_poll_cq((*id).send_cq, num_entries, wc);
1315 if ret != 0 {
1316 break;
1317 }
1318 ret = ibv_get_cq_event((*id).send_cq_channel, &mut cq, &mut context);
1319 if ret != 0 {
1320 return ret;
1321 }
1322
1323 assert!(cq == (*id).send_cq && context as *mut rdma_cm_id == id);
1324 ibv_ack_cq_events((*id).send_cq, nevents);
1325 }
1326 if ret < 0 {
1327 rdma_seterrno(ret)
1328 } else {
1329 ret
1330 }
1331}
1332
1333#[inline]
1334pub unsafe fn rdma_get_recv_comp(id: *mut rdma_cm_id, wc: *mut ibv_wc) -> c_int {
1335 let mut ret: c_int;
1336 let mut cq = ptr::null::<ibv_cq>() as *mut _;
1337 let mut context = ptr::null::<c_void>() as *mut _;
1338 let nevents = 1;
1339 let num_entries = 1;
1340 let solicited_only = 0;
1341 loop {
1342 ret = ibv_poll_cq((*id).recv_cq, num_entries, wc);
1343 if ret != 0 {
1344 break;
1345 }
1346 ret = ibv_req_notify_cq((*id).recv_cq, solicited_only);
1347 if ret != 0 {
1348 return rdma_seterrno(ret);
1349 }
1350 ret = ibv_poll_cq((*id).recv_cq, num_entries, wc);
1351 if ret != 0 {
1352 break;
1353 }
1354 ret = ibv_get_cq_event((*id).recv_cq_channel, &mut cq, &mut context);
1355 if ret != 0 {
1356 return ret;
1357 }
1358
1359 assert!(cq == (*id).recv_cq && context as *mut rdma_cm_id == id);
1360 ibv_ack_cq_events((*id).recv_cq, nevents);
1361 }
1362 if ret < 0 {
1363 rdma_seterrno(ret)
1364 } else {
1365 ret
1366 }
1367}