@@ -7,6 +7,8 @@ cdef class CompChannel(PyverbsCM):
cdef v.ibv_comp_channel *cc
cpdef close(self)
cdef object context
+ cdef add_ref(self, obj)
+ cdef object cqs
cdef class CQ(PyverbsCM):
cdef v.ibv_cq *cq
@@ -15,6 +17,7 @@ cdef class CQ(PyverbsCM):
cdef class CqInitAttrEx(PyverbsObject):
cdef v.ibv_cq_init_attr_ex attr
+ cdef object channel
cdef class CQEX(PyverbsCM):
cdef v.ibv_cq_ex *cq
@@ -1,5 +1,7 @@
# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB)
# Copyright (c) 2019, Mellanox Technologies. All rights reserved.
+import weakref
+
from pyverbs.base import PyverbsRDMAErrno
cimport pyverbs.libibverbs_enums as e
from pyverbs.device cimport Context
@@ -22,6 +24,7 @@ cdef class CompChannel(PyverbsCM):
raise PyverbsRDMAErrno('Failed to create a completion channel')
self.context = context
context.add_ref(self)
+ self.cqs = weakref.WeakSet()
self.logger.debug('Created a Completion Channel')
def __dealloc__(self):
@@ -29,6 +32,7 @@ cdef class CompChannel(PyverbsCM):
cpdef close(self):
self.logger.debug('Closing completion channel')
+ self.close_weakrefs([self.cqs])
if self.cc != NULL:
rc = v.ibv_destroy_comp_channel(self.cc)
if rc != 0:
@@ -50,6 +54,14 @@ cdef class CompChannel(PyverbsCM):
if cq != expected_cq.cq:
raise PyverbsRDMAErrno('Received event on an unexpected CQ')
+ cdef add_ref(self, obj):
+ if isinstance(obj, CQ) or isinstance(obj, CQEX):
+ self.cqs.add(obj)
+
+ @property
+ def channel(self):
+ return <object>self.cc
+
cdef class CQ(PyverbsCM):
"""
@@ -69,8 +81,14 @@ cdef class CQ(PyverbsCM):
context's num_comp_vectors
:return: The newly created CQ
"""
- self.cq = v.ibv_create_cq(context.context, cqe, <void*>cq_context,
- NULL, comp_vector)
+ if channel is not None:
+ self.cq = v.ibv_create_cq(context.context, cqe, <void*>cq_context,
+ <v.ibv_comp_channel*>channel.channel,
+ comp_vector)
+ channel.add_ref(self)
+ else:
+ self.cq = v.ibv_create_cq(context.context, cqe, <void*>cq_context,
+ NULL, comp_vector)
if self.cq == NULL:
raise PyverbsRDMAErrno('Failed to create a CQ')
self.context = context
@@ -115,6 +133,28 @@ cdef class CQ(PyverbsCM):
dlid_path_bits=wc.dlid_path_bits))
return npolled, wcs
+ def req_notify(self, solicited_only = False):
+ """
+ Request completion notification on the completion queue.
+ :param solicited_only: If non-zero, notifications will be created only
+ for incoming send / RDMA write WRs with
+ immediate data that have the solicited bit set in
+ their send flags.
+ :return: None
+ """
+ rc = v.ibv_req_notify_cq(self.cq, solicited_only)
+ if rc != 0:
+ raise PyverbsRDMAErrno('Request notify CQ returned {rc}'.
+ format(rc=rc))
+
+ def ack_events(self, num_events):
+ """
+ Get and acknowledge CQ events
+ :param num_events: Number of events to acknowledge
+ :return: None
+ """
+ v.ibv_ack_cq_events(self.cq, num_events)
+
@property
def _cq(self):
return <object>self.cq
@@ -150,6 +190,7 @@ cdef class CqInitAttrEx(PyverbsObject):
self.attr.wc_flags = wc_flags
self.attr.comp_mask = comp_mask
self.attr.flags = flags
+ self.channel = channel
@property
def cqe(self):
@@ -163,9 +204,13 @@ cdef class CqInitAttrEx(PyverbsObject):
def __set__(self, val):
self.attr.cq_context = <void*>val
- property channel:
- def __set__(self, val):
- self.attr.channel = <v.ibv_comp_channel*>val
+ @property
+ def comp_channel(self):
+ return self.channel
+ @comp_channel.setter
+ def comp_channel(self, val):
+ self.channel = val
+ self.attr.channel = <v.ibv_comp_channel*>val
@property
def comp_vector(self):
@@ -215,6 +260,8 @@ cdef class CQEX(PyverbsCM):
if init_attr is None:
init_attr = CqInitAttrEx()
self.cq = v.ibv_create_cq_ex(context.context, &init_attr.attr)
+ if init_attr.comp_channel:
+ init_attr.comp_channel.add_ref(self)
if self.cq == NULL:
raise PyverbsRDMAErrno('Failed to create extended CQ')
self.ibv_cq = v.ibv_cq_ex_to_cq(self.cq)
@@ -259,6 +259,8 @@ cdef extern from 'infiniband/verbs.h':
int ibv_destroy_comp_channel(ibv_comp_channel *channel)
int ibv_get_cq_event(ibv_comp_channel *channel, ibv_cq **cq,
void **cq_context)
+ int ibv_req_notify_cq(ibv_cq *cq, int solicited_only)
+ void ibv_ack_cq_events(ibv_cq *cq, int nevents)
ibv_cq *ibv_create_cq(ibv_context *context, int cqe, void *cq_context,
ibv_comp_channel *channel, int comp_vector)
int ibv_destroy_cq(ibv_cq *cq)
Add missing definitions to allow using a completion channel properly; some functions declarations were missing as well as a reference between a completion channel and its users. Change-Id: Ia9259f34d8d1a76b09ed2fe1a897031bb04c8073 Signed-off-by: Noa Osherovich <noaos@mellanox.com> --- pyverbs/cq.pxd | 3 +++ pyverbs/cq.pyx | 57 ++++++++++++++++++++++++++++++++++++++---- pyverbs/libibverbs.pxd | 2 ++ 3 files changed, 57 insertions(+), 5 deletions(-)