Skip to content

Commit 5772209

Browse files
committed
pyverbs: Add Completion Counters support
Expose the Completion Counters verbs API through pyverbs. Add CompCntr class with set, set_err, inc, inc_err, read and read_err methods. Add CompCntrInitAttr and CompCntrAttachAttr helper classes. Add attach_comp_cntr method to the QP class. Add EfaCompCntr and EfaCompCntrInitAttr for efadv extended creation with external memory options. Signed-off-by: Michael Margolin <mrgolin@amazon.com>
1 parent 6c4542e commit 5772209

11 files changed

Lines changed: 253 additions & 0 deletions

File tree

pyverbs/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ rdma_cython_module(pyverbs ""
2222
addr.pyx
2323
base.pyx
2424
cmid.pyx
25+
comp_cntr.pyx
2526
cq.pyx
2627
device.pyx
2728
${DMA_UTIL}

pyverbs/comp_cntr.pxd

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB)
2+
# Copyright Amazon.com, Inc. or its affiliates. All rights reserved.
3+
4+
#cython: language_level=3
5+
6+
from pyverbs.base cimport PyverbsObject, PyverbsCM
7+
from pyverbs.device cimport Context
8+
cimport pyverbs.libibverbs as v
9+
10+
cdef class CompCntrInitAttr(PyverbsObject):
11+
cdef v.ibv_comp_cntr_init_attr attr
12+
13+
cdef class QPAttachCompCntrAttr(PyverbsObject):
14+
cdef v.ibv_qp_attach_comp_cntr_attr attr
15+
16+
cdef class CompCntr(PyverbsCM):
17+
cdef v.ibv_comp_cntr *comp_cntr
18+
cdef Context ctx
19+
cpdef close(self)

pyverbs/comp_cntr.pyx

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB)
2+
# Copyright Amazon.com, Inc. or its affiliates. All rights reserved.
3+
4+
#cython: language_level=3
5+
6+
from pyverbs.base import PyverbsRDMAErrno, PyverbsRDMAError
7+
from pyverbs.device cimport Context
8+
cimport pyverbs.libibverbs as v
9+
10+
11+
cdef class CompCntrInitAttr(PyverbsObject):
12+
"""Represents ibv_comp_cntr_init_attr struct."""
13+
def __init__(self, comp_mask=0, type=0, flags=0):
14+
super().__init__()
15+
self.attr.comp_mask = comp_mask
16+
self.attr.type = type
17+
self.attr.flags = flags
18+
19+
@property
20+
def comp_mask(self):
21+
return self.attr.comp_mask
22+
23+
@property
24+
def type(self):
25+
return self.attr.type
26+
27+
@property
28+
def flags(self):
29+
return self.attr.flags
30+
31+
32+
cdef class QPAttachCompCntrAttr(PyverbsObject):
33+
"""Represents ibv_qp_attach_comp_cntr_attr struct."""
34+
def __init__(self, op_mask=0):
35+
super().__init__()
36+
self.attr.op_mask = op_mask
37+
38+
@property
39+
def op_mask(self):
40+
return self.attr.op_mask
41+
42+
43+
cdef class CompCntr(PyverbsCM):
44+
"""Represents a Completion Counter."""
45+
def __init__(self, Context ctx not None, CompCntrInitAttr attr not None):
46+
super().__init__()
47+
self.comp_cntr = v.ibv_create_comp_cntr(ctx.context, &attr.attr)
48+
if self.comp_cntr == NULL:
49+
raise PyverbsRDMAErrno('Failed to create comp_cntr')
50+
self.ctx = ctx
51+
52+
def close(self):
53+
if self.comp_cntr != NULL:
54+
rc = v.ibv_destroy_comp_cntr(self.comp_cntr)
55+
if rc:
56+
raise PyverbsRDMAError('Failed to destroy comp_cntr', rc)
57+
self.comp_cntr = NULL
58+
59+
@property
60+
def comp_count_max_value(self):
61+
return self.comp_cntr.comp_count_max_value
62+
63+
@property
64+
def err_count_max_value(self):
65+
return self.comp_cntr.err_count_max_value
66+
67+
def set(self, value):
68+
rc = v.ibv_set_comp_cntr(self.comp_cntr, value)
69+
if rc:
70+
raise PyverbsRDMAError('Failed to set comp_cntr', rc)
71+
72+
def set_err(self, value):
73+
rc = v.ibv_set_err_comp_cntr(self.comp_cntr, value)
74+
if rc:
75+
raise PyverbsRDMAError('Failed to set_err comp_cntr', rc)
76+
77+
def inc(self, amount):
78+
rc = v.ibv_inc_comp_cntr(self.comp_cntr, amount)
79+
if rc:
80+
raise PyverbsRDMAError('Failed to inc comp_cntr', rc)
81+
82+
def inc_err(self, amount):
83+
rc = v.ibv_inc_err_comp_cntr(self.comp_cntr, amount)
84+
if rc:
85+
raise PyverbsRDMAError('Failed to inc_err comp_cntr', rc)
86+
87+
def read(self):
88+
cdef unsigned long value = 0
89+
rc = v.ibv_read_comp_cntr(self.comp_cntr, &value)
90+
if rc:
91+
raise PyverbsRDMAError('Failed to read comp_cntr', rc)
92+
return value
93+
94+
def read_err(self):
95+
cdef unsigned long value = 0
96+
rc = v.ibv_read_err_comp_cntr(self.comp_cntr, &value)
97+
if rc:
98+
raise PyverbsRDMAError('Failed to read_err comp_cntr', rc)
99+
return value

pyverbs/device.pyx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,9 @@ cdef class DeviceAttrEx(PyverbsObject):
743743
@property
744744
def phys_port_cnt_ex(self):
745745
return self.dev_attr.phys_port_cnt_ex
746+
@property
747+
def max_comp_cntr(self):
748+
return self.dev_attr.max_comp_cntr
746749

747750

748751
cdef class AllocDmAttr(PyverbsObject):

pyverbs/libibverbs.pxd

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ cdef extern from 'infiniband/verbs.h':
149149
ibv_pci_atomic_caps pci_atomic_caps
150150
uint32_t xrc_odp_caps
151151
uint32_t phys_port_cnt_ex
152+
uint32_t max_comp_cntr
152153

153154
cdef struct ibv_mw:
154155
ibv_context *context
@@ -244,6 +245,17 @@ cdef extern from 'infiniband/verbs.h':
244245
cdef struct ibv_poll_cq_attr:
245246
unsigned int comp_mask
246247

248+
cdef struct ibv_comp_cntr:
249+
ibv_context *context
250+
unsigned int handle
251+
unsigned long comp_count_max_value
252+
unsigned long err_count_max_value
253+
254+
cdef struct ibv_comp_cntr_init_attr:
255+
unsigned int comp_mask
256+
unsigned int type
257+
unsigned int flags
258+
247259
cdef struct ibv_wc_tm_info:
248260
unsigned long tag
249261
unsigned int priv
@@ -503,6 +515,10 @@ cdef extern from 'infiniband/verbs.h':
503515
ibv_qp_type qp_type;
504516
unsigned int events_completed;
505517

518+
cdef struct ibv_qp_attach_comp_cntr_attr:
519+
unsigned int comp_mask
520+
unsigned int op_mask
521+
506522
cdef struct ibv_parent_domain_init_attr:
507523
ibv_pd *pd;
508524
uint32_t comp_mask;
@@ -741,6 +757,15 @@ cdef extern from 'infiniband/verbs.h':
741757
unsigned int ibv_wc_read_flow_tag(ibv_cq_ex *cq)
742758
void ibv_wc_read_tm_info(ibv_cq_ex *cq, ibv_wc_tm_info *tm_info)
743759
unsigned long ibv_wc_read_completion_wallclock_ns(ibv_cq_ex *cq)
760+
ibv_comp_cntr *ibv_create_comp_cntr(ibv_context *context,
761+
ibv_comp_cntr_init_attr *attr)
762+
int ibv_destroy_comp_cntr(ibv_comp_cntr *comp_cntr)
763+
int ibv_set_comp_cntr(ibv_comp_cntr *comp_cntr, unsigned long value)
764+
int ibv_set_err_comp_cntr(ibv_comp_cntr *comp_cntr, unsigned long value)
765+
int ibv_inc_comp_cntr(ibv_comp_cntr *comp_cntr, unsigned long amount)
766+
int ibv_inc_err_comp_cntr(ibv_comp_cntr *comp_cntr, unsigned long amount)
767+
int ibv_read_comp_cntr(ibv_comp_cntr *comp_cntr, unsigned long *value)
768+
int ibv_read_err_comp_cntr(ibv_comp_cntr *comp_cntr, unsigned long *value)
744769
ibv_ah *ibv_create_ah(ibv_pd *pd, ibv_ah_attr *attr)
745770
int ibv_init_ah_from_wc(ibv_context *context, uint8_t port_num,
746771
ibv_wc *wc, ibv_grh *grh, ibv_ah_attr *ah_attr)
@@ -754,6 +779,8 @@ cdef extern from 'infiniband/verbs.h':
754779
int ibv_query_qp(ibv_qp *qp, ibv_qp_attr *attr, int attr_mask,
755780
ibv_qp_init_attr *init_attr)
756781
int ibv_destroy_qp(ibv_qp *qp)
782+
int ibv_qp_attach_comp_cntr(ibv_qp *qp, ibv_comp_cntr *comp_cntr,
783+
ibv_qp_attach_comp_cntr_attr *attr)
757784
int ibv_post_recv(ibv_qp *qp, ibv_recv_wr *wr, ibv_recv_wr **bad_wr)
758785
int ibv_post_send(ibv_qp *qp, ibv_send_wr *wr, ibv_send_wr **bad_wr)
759786
int ibv_bind_mw(ibv_qp *qp, ibv_mw *mw, ibv_mw_bind *mw_bind)

pyverbs/libibverbs_enums.pxd

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,14 @@ cdef extern from '<infiniband/verbs.h>':
521521
IBV_REG_MR_MASK_FD_OFFSET
522522
IBV_REG_MR_MASK_DMAH
523523

524+
cpdef enum ibv_qp_attach_comp_cntr_op:
525+
IBV_QP_ATTACH_COMP_CNTR_OP_SEND
526+
IBV_QP_ATTACH_COMP_CNTR_OP_RECV
527+
IBV_QP_ATTACH_COMP_CNTR_OP_RDMA_READ
528+
IBV_QP_ATTACH_COMP_CNTR_OP_REMOTE_RDMA_READ
529+
IBV_QP_ATTACH_COMP_CNTR_OP_RDMA_WRITE
530+
IBV_QP_ATTACH_COMP_CNTR_OP_REMOTE_RDMA_WRITE
531+
524532

525533
cdef extern from "<infiniband/verbs_api.h>":
526534
cdef unsigned long long IBV_ADVISE_MR_ADVICE_PREFETCH

pyverbs/providers/efa/efa_enums.pxd

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ cdef extern from 'infiniband/efadv.h':
1111
EFADV_DEVICE_ATTR_CAPS_CQ_WITH_SGID
1212
EFADV_DEVICE_ATTR_CAPS_RDMA_WRITE
1313
EFADV_DEVICE_ATTR_CAPS_UNSOLICITED_WRITE_RECV
14+
EFADV_DEVICE_ATTR_CAPS_CQ_WITH_EXT_MEM_DMABUF
15+
EFADV_DEVICE_ATTR_CAPS_COMP_CNTR
1416

1517
cpdef enum:
1618
EFADV_QP_DRIVER_TYPE_SRD
@@ -36,3 +38,11 @@ cdef extern from 'infiniband/efadv.h':
3638

3739
cpdef enum:
3840
EFADV_SQ_DEPTH_ATTR_INLINE_WRITE
41+
42+
cpdef enum:
43+
EFADV_MEMORY_LOCATION_VA
44+
EFADV_MEMORY_LOCATION_DMABUF
45+
46+
cpdef enum:
47+
EFADV_COMP_CNTR_INIT_WITH_COMP_EXTERNAL_MEM
48+
EFADV_COMP_CNTR_INIT_WITH_ERR_EXTERNAL_MEM

pyverbs/providers/efa/efadv.pxd

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ cimport pyverbs.providers.efa.libefa as dv
77

88
from pyverbs.addr cimport AH
99
from pyverbs.base cimport PyverbsObject
10+
from pyverbs.comp_cntr cimport CompCntr
1011
from pyverbs.cq cimport CQEX
1112
from pyverbs.device cimport Context
1213
from pyverbs.qp cimport QP, QPEx
@@ -48,6 +49,14 @@ cdef class EfaDVCQInitAttr(PyverbsObject):
4849
cdef dv.efadv_cq_init_attr cq_init_attr
4950

5051

52+
cdef class EfaCompCntrInitAttr(PyverbsObject):
53+
cdef dv.efadv_comp_cntr_init_attr attr
54+
55+
56+
cdef class EfaCompCntr(CompCntr):
57+
pass
58+
59+
5160
cdef class EfaDVMRAttr(PyverbsObject):
5261
cdef dv.efadv_mr_attr mr_attr
5362

pyverbs/providers/efa/efadv.pyx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ cimport pyverbs.providers.efa.libefa as dv
66

77
from pyverbs.addr cimport GID
88
from pyverbs.base import PyverbsRDMAErrno, PyverbsRDMAError
9+
from pyverbs.comp_cntr cimport CompCntr, CompCntrInitAttr
910
from pyverbs.cq cimport CQEX, CqInitAttrEx
1011
from pyverbs.libibverbs_enums import ibv_qp_attr_mask
1112
cimport pyverbs.libibverbs as v
1213
from pyverbs.pd cimport PD
1314
from pyverbs.qp cimport QP, QPEx, QPInitAttr, QPInitAttrEx
1415
from pyverbs.mr cimport MR
16+
from libc.string cimport memset
17+
from libc.stdint cimport uintptr_t, uint8_t
1518

1619

1720
def dev_cap_to_str(flags):
@@ -293,6 +296,50 @@ cdef class EfaCQ(CQEX):
293296
return dv.efadv_wc_is_unsolicited(self.dv_cq)
294297

295298

299+
cdef class EfaCompCntrInitAttr(PyverbsObject):
300+
"""Represents efadv_comp_cntr_init_attr struct."""
301+
302+
def __init__(self):
303+
super().__init__()
304+
memset(&self.attr, 0, sizeof(self.attr))
305+
306+
@property
307+
def flags(self):
308+
return self.attr.flags
309+
310+
@flags.setter
311+
def flags(self, val):
312+
self.attr.flags = val
313+
314+
def set_comp_ext_mem_va(self, uintptr_t ptr):
315+
self.attr.flags |= dve.EFADV_COMP_CNTR_INIT_WITH_COMP_EXTERNAL_MEM
316+
self.attr.comp_cntr_ext_mem.type = dve.EFADV_MEMORY_LOCATION_VA
317+
self.attr.comp_cntr_ext_mem.ptr = <uint8_t *>ptr
318+
319+
def set_err_ext_mem_va(self, uintptr_t ptr):
320+
self.attr.flags |= dve.EFADV_COMP_CNTR_INIT_WITH_ERR_EXTERNAL_MEM
321+
self.attr.err_cntr_ext_mem.type = dve.EFADV_MEMORY_LOCATION_VA
322+
self.attr.err_cntr_ext_mem.ptr = <uint8_t *>ptr
323+
324+
325+
cdef class EfaCompCntr(CompCntr):
326+
"""
327+
Initializes an EFA Completion Counter with EFA-specific options.
328+
:param ctx: Context object
329+
:param attr: CompCntrInitAttr object
330+
:param efa_attr: EfaCompCntrInitAttr object
331+
:return: An initialized EfaCompCntr
332+
"""
333+
def __init__(self, Context ctx not None, CompCntrInitAttr attr not None,
334+
EfaCompCntrInitAttr efa_attr=None):
335+
if efa_attr is None:
336+
efa_attr = EfaCompCntrInitAttr()
337+
self.comp_cntr = dv.efadv_create_comp_cntr(ctx.context, &attr.attr, &efa_attr.attr, sizeof(efa_attr.attr))
338+
if self.comp_cntr == NULL:
339+
raise PyverbsRDMAErrno('Failed to create EFA comp_cntr')
340+
self.ctx = ctx
341+
342+
296343
cdef class EfaDVMRAttr(PyverbsObject):
297344
"""
298345
Represents efadv_mr_attr struct, which exposes efa-specific MR attributes,

pyverbs/providers/efa/libefa.pxd

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,20 @@ cdef extern from 'infiniband/efadv.h':
8686
uint32_t inlen)
8787
int efadv_get_max_rq_depth(v.ibv_context *ibvctx, efadv_rq_depth_attr *attr,
8888
uint32_t inlen);
89+
90+
cdef struct efadv_memory_location:
91+
uint8_t *ptr
92+
uint8_t type
93+
uint8_t reserved[7]
94+
95+
cdef struct efadv_comp_cntr_init_attr:
96+
uint64_t comp_mask
97+
uint32_t flags
98+
uint32_t reserved
99+
efadv_memory_location comp_cntr_ext_mem
100+
efadv_memory_location err_cntr_ext_mem
101+
102+
v.ibv_comp_cntr *efadv_create_comp_cntr(v.ibv_context *ibvctx,
103+
v.ibv_comp_cntr_init_attr *attr,
104+
efadv_comp_cntr_init_attr *efa_attr,
105+
uint32_t inlen)

0 commit comments

Comments
 (0)