From: Noa Osherovich <noaos@xxxxxxxxxxxx> Pyverbs is a cython package that provides Python API over IB verbs. By that it allows both fast development of tests and an easy introduction to RDMA for new users. Pyverbs' development flow follows the IB verbs model. This means that users are supposed to get ibv_context with context class, which will provide all standard functions, e.g. query_device. For more information, see examples section of pyverbs. Enums need to be added as both a pxd file (for internal cython usage) and pyx file (for Python users). To avoid code duplication, the pyx file is a symbolic link to the pxd file. Signed-off-by: Noa Osherovich <noaos@xxxxxxxxxxxx> Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx> --- pyverbs/__init__.pxd | 0 pyverbs/__init__.py | 0 pyverbs/base.pxd | 5 + pyverbs/base.pyx | 24 +++ pyverbs/device.pxd | 15 ++ pyverbs/device.pyx | 273 ++++++++++++++++++++++++++++ pyverbs/enums.pyx | 1 + pyverbs/libibverbs.pxd | 63 +++++++ pyverbs/libibverbs_enums.pxd | 339 +++++++++++++++++++++++++++++++++++ pyverbs/pyverbs_error.py | 40 +++++ 10 files changed, 760 insertions(+) create mode 100644 pyverbs/__init__.pxd create mode 100644 pyverbs/__init__.py create mode 100644 pyverbs/base.pxd create mode 100644 pyverbs/base.pyx create mode 100644 pyverbs/device.pxd create mode 100644 pyverbs/device.pyx create mode 120000 pyverbs/enums.pyx create mode 100644 pyverbs/libibverbs.pxd create mode 100644 pyverbs/libibverbs_enums.pxd create mode 100644 pyverbs/pyverbs_error.py diff --git a/pyverbs/__init__.pxd b/pyverbs/__init__.pxd new file mode 100644 index 00000000..e69de29b diff --git a/pyverbs/__init__.py b/pyverbs/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pyverbs/base.pxd b/pyverbs/base.pxd new file mode 100644 index 00000000..fa5e0dad --- /dev/null +++ b/pyverbs/base.pxd @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) +# Copyright (c) 2018, Mellanox Technologies. All rights reserved. + +cdef class PyverbsObject(object): + cdef object logger diff --git a/pyverbs/base.pyx b/pyverbs/base.pyx new file mode 100644 index 00000000..6bcebd09 --- /dev/null +++ b/pyverbs/base.pyx @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) +# Copyright (c) 2018, Mellanox Technologies. All rights reserved. + +import logging +from pyverbs.pyverbs_error import PyverbsRDMAError + + +cdef extern from 'errno.h': + int errno + +cpdef PyverbsRDMAErrno(str msg): + return PyverbsRDMAError(msg, errno) + +LOG_LEVEL=logging.INFO +LOG_FORMAT='[%(levelname)s] %(asctime)s %(filename)s:%(lineno)s: %(message)s' +logging.basicConfig(format=LOG_FORMAT, level=LOG_LEVEL, datefmt='%d %b %Y %H:%M:%S') + +cdef class PyverbsObject(object): + + def __cinit__(self): + self.logger = logging.getLogger(self.__class__.__name__) + + def set_log_level(self, val): + self.logger.setLevel(val) diff --git a/pyverbs/device.pxd b/pyverbs/device.pxd new file mode 100644 index 00000000..53da093b --- /dev/null +++ b/pyverbs/device.pxd @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) +# Copyright (c) 2018, Mellanox Technologies. All rights reserved. See COPYING file + +from .base cimport PyverbsObject +cimport pyverbs.libibverbs as v + + +cdef class Context(PyverbsObject): + cdef v.ibv_context *context + cdef object name + cdef _close(self) + +cdef class DeviceAttr(PyverbsObject): + cdef v.ibv_device_attr dev_attr + diff --git a/pyverbs/device.pyx b/pyverbs/device.pyx new file mode 100644 index 00000000..64fbd9e7 --- /dev/null +++ b/pyverbs/device.pyx @@ -0,0 +1,273 @@ +# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) +# Copyright (c) 2018, Mellanox Technologies. All rights reserved. See COPYING file + +""" +Device module introduces the Context and DeviceAttr class. +It allows user to open an IB device (using Context(name=<name>) and query it, +which returns a DeviceAttr object. +""" +from .pyverbs_error import PyverbsRDMAError +from .pyverbs_error import PyverbsUserError +from pyverbs.base import PyverbsRDMAErrno +cimport pyverbs.libibverbs as v + +cdef extern from 'errno.h': + int errno + + +cdef class Context(PyverbsObject): + """ + Context class represents the C ibv_context. It currently allows only + querying the underlying device. + """ + def __cinit__(self, **kwargs): + """ + Initializes a Context object. The function searches the IB devices list + for a device with the name provided by the user. If such a device is + found, it is opened. + :param kwargs: Currently supports 'name' argument only, the IB device's + name. + :return: None + """ + cdef int count + cdef v.ibv_device **dev_list + dev_name = kwargs.get('name') + + if dev_name is not None: + self.name = dev_name + else: + raise PyverbsUserError('Device name must be provided') + + dev_list = v.ibv_get_device_list(&count) + if dev_list == NULL: + raise PyverbsRDMAError('Failed to get devices list') + try: + for i in range(count): + if dev_list[i].name.decode() == self.name: + self.context = v.ibv_open_device(dev_list[i]) + if self.context == NULL: + raise PyverbsRDMAErrno('Failed to open device {dev}'. + format(dev=self.name)) + self.logger.debug('Context: opened device {dev}'. + format(dev=self.name)) + break + else: + raise PyverbsRDMAError('Failed to find device {dev}'. + format(dev=self.name)) + finally: + v.ibv_free_device_list(dev_list) + + def __dealloc__(self): + """ + Closes the inner IB device. + :return: None + """ + self._close() + + def close(self): + """ + Closes the inner IB device. + :return: None + """ + self._close() + + cdef _close(self): + self.logger.debug('Closing Context') + if self.context != NULL: + rc = v.ibv_close_device(self.context) + if rc != 0: + raise PyverbsRDMAErrno('Failed to close device {dev}'. + format(dev=self.device.name), errno) + self.context = NULL + + def query_device(self): + """ + Queries the device's attributes. + :return: A DeviceAttr object which holds the device's attributes as + reported by the hardware. + """ + dev_attr = DeviceAttr() + rc = v.ibv_query_device(self.context, &dev_attr.dev_attr) + if rc != 0: + raise PyverbsRDMAErrno('Failed to query device {name}'. + format(name=self.name), errno) + return dev_attr + + +cdef class DeviceAttr(PyverbsObject): + """ + DeviceAttr represents ibv_device_attr C class. It exposes the same + properties (read only) and also provides an __str__() function for + readability. + """ + property fw_version: + def __get__(self): + return self.dev_attr.fw_ver.decode() + property node_guid: + def __get__(self): + return self.dev_attr.node_guid + property sys_image_guid: + def __get__(self): + return self.dev_attr.sys_image_guid + property max_mr_size: + def __get__(self): + return self.dev_attr.max_mr_size + property page_size_cap: + def __get__(self): + return self.dev_attr.page_size_cap + property vendor_id: + def __get__(self): + return self.dev_attr.vendor_id + property vendor_part_id: + def __get__(self): + return self.dev_attr.vendor_part_id + property hw_ver: + def __get__(self): + return self.dev_attr.hw_ver + property max_qp: + def __get__(self): + return self.dev_attr.max_qp + property max_qp_wr: + def __get__(self): + return self.dev_attr.max_qp_wr + property device_cap_flags: + def __get__(self): + return self.dev_attr.device_cap_flags + property max_sge: + def __get__(self): + return self.dev_attr.max_sge + property max_sge_rd: + def __get__(self): + return self.dev_attr.max_sge_rd + property max_cq: + def __get__(self): + return self.dev_attr.max_cq + property max_cqe: + def __get__(self): + return self.dev_attr.max_cqe + property max_mr: + def __get__(self): + return self.dev_attr.max_mr + property max_pd: + def __get__(self): + return self.dev_attr.max_pd + property max_qp_rd_atom: + def __get__(self): + return self.dev_attr.max_qp_rd_atom + property max_ee_rd_atom: + def __get__(self): + return self.dev_attr.max_ee_rd_atom + property max_res_rd_atom: + def __get__(self): + return self.dev_attr.max_res_rd_atom + property max_qp_init_rd_atom: + def __get__(self): + return self.dev_attr.max_qp_init_rd_atom + property max_ee_init_rd_atom: + def __get__(self): + return self.dev_attr.max_ee_init_rd_atom + property atomic_caps: + def __get__(self): + return self.dev_attr.atomic_cap + property max_ee: + def __get__(self): + return self.dev_attr.max_ee + property max_rdd: + def __get__(self): + return self.dev_attr.max_rdd + property max_mw: + def __get__(self): + return self.dev_attr.max_mw + property max_raw_ipv6_qps: + def __get__(self): + return self.dev_attr.max_raw_ipv6_qp + property max_raw_ethy_qp: + def __get__(self): + return self.dev_attr.max_raw_ethy_qp + property max_mcast_grp: + def __get__(self): + return self.dev_attr.max_mcast_grp + property max_mcast_qp_attach: + def __get__(self): + return self.dev_attr.max_mcast_qp_attach + property max_ah: + def __get__(self): + return self.dev_attr.max_ah + property max_fmr: + def __get__(self): + return self.dev_attr.max_fmr + property max_map_per_fmr: + def __get__(self): + return self.dev_attr.max_map_per_fmr + property max_srq: + def __get__(self): + return self.dev_attr.max_srq + property max_srq_wr: + def __get__(self): + return self.dev_attr.max_srq_wr + property max_srq_sge: + def __get__(self): + return self.dev_attr.max_srq_sge + property max_pkeys: + def __get__(self): + return self.dev_attr.max_pkeys + property local_ca_ack_delay: + def __get__(self): + return self.dev_attr.local_ca_ack_delay + property phys_port_cnt: + def __get__(self): + return self.dev_attr.phys_port_cnt + + def __str__(self): + print_format = '{:<22}: {:<20}\n' + return print_format.format('FW version', self.fw_version) +\ + print_format.format('Node guid', guid_format(self.node_guid)) +\ + print_format.format('Sys image GUID', guid_format(self.sys_image_guid)) +\ + print_format.format('Max MR size', hex(self.max_mr_size).replace('L', '')) +\ + print_format.format('Page size cap', hex(self.page_size_cap).replace('L', '')) +\ + print_format.format('Vendor ID', hex(self.vendor_id)) +\ + print_format.format('Vender part ID', self.vendor_part_id) +\ + print_format.format('HW version', self.hw_ver) +\ + print_format.format('Max QP', self.max_qp) +\ + print_format.format('Max QP WR', self.max_qp_wr) +\ + print_format.format('Device cap flags', self.device_cap_flags) +\ + print_format.format('Max SGE', self.max_sge) +\ + print_format.format('Max SGE RD', self.max_sge_rd) +\ + print_format.format('MAX CQ', self.max_cq) +\ + print_format.format('Max CQE', self.max_cqe) +\ + print_format.format('Max MR', self.max_mr) +\ + print_format.format('Max PD', self.max_pd) +\ + print_format.format('Max QP RD atom', self.max_qp_rd_atom) +\ + print_format.format('Max EE RD atom', self.max_ee_rd_atom) +\ + print_format.format('Max res RD atom', self.max_res_rd_atom) +\ + print_format.format('Max QP init RD atom', self.max_qp_init_rd_atom) +\ + print_format.format('Max EE init RD atom', self.max_ee_init_rd_atom) +\ + print_format.format('Atomic caps', self.atomic_caps) +\ + print_format.format('Max EE', self.max_ee) +\ + print_format.format('Max RDD', self.max_rdd) +\ + print_format.format('Max MW', self.max_mw) +\ + print_format.format('Max raw IPv6 QPs', self.max_raw_ipv6_qps) +\ + print_format.format('Max raw ethy QP', self.max_raw_ethy_qp) +\ + print_format.format('Max mcast group', self.max_mcast_grp) +\ + print_format.format('Max mcast QP attach', self.max_mcast_qp_attach) +\ + print_format.format('Max AH', self.max_ah) +\ + print_format.format('Max FMR', self.max_fmr) +\ + print_format.format('Max map per FMR', self.max_map_per_fmr) +\ + print_format.format('Max SRQ', self.max_srq) +\ + print_format.format('Max SRQ WR', self.max_srq_wr) +\ + print_format.format('Max SRQ SGE', self.max_srq_sge) +\ + print_format.format('Max PKeys', self.max_pkeys) +\ + print_format.format('local CA ack delay', self.local_ca_ack_delay) +\ + print_format.format('Phys port count', self.phys_port_cnt) + +def guid_format(num): + """ + Get GUID representation of the given number, including change of endianness. + :param num: Number to change to GUID format. + :return: GUID-formatted string. + """ + num = be64toh(num) + hex_str = "%016x" % (num) + hex_array = [hex_str[i:i+2] for i in range(0, len(hex_str), 2)] + hex_array = [''.join(x) for x in zip(hex_array[0::2], hex_array[1::2])] + return ':'.join(hex_array) diff --git a/pyverbs/enums.pyx b/pyverbs/enums.pyx new file mode 120000 index 00000000..cbf66071 --- /dev/null +++ b/pyverbs/enums.pyx @@ -0,0 +1 @@ +libibverbs_enums.pxd \ No newline at end of file diff --git a/pyverbs/libibverbs.pxd b/pyverbs/libibverbs.pxd new file mode 100644 index 00000000..c5cd14d3 --- /dev/null +++ b/pyverbs/libibverbs.pxd @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) +# Copyright (c) 2018, Mellanox Technologies. All rights reserved. See COPYING file + +include 'libibverbs_enums.pxd' +from libc.stdint cimport uint8_t, uint64_t + +cdef extern from 'infiniband/verbs.h': + + cdef struct ibv_device: + char *name + int node_type + int transport_type + + cdef struct ibv_context: + ibv_device *device + + cdef struct ibv_device_attr: + char *fw_ver + unsigned long node_guid; + unsigned long sys_image_guid; + unsigned long max_mr_size; + unsigned long page_size_cap; + unsigned int vendor_id; + unsigned int vendor_part_id; + unsigned int hw_ver; + unsigned int max_qp + unsigned int max_qp_wr + unsigned int device_cap_flags + unsigned int max_sge + unsigned int max_sge_rd + unsigned int max_cq + unsigned int max_cqe + unsigned int max_mr + unsigned int max_pd + unsigned int max_qp_rd_atom + unsigned int max_ee_rd_atom + unsigned int max_res_rd_atom + unsigned int max_qp_init_rd_atom + unsigned int max_ee_init_rd_atom + ibv_atomic_cap atomic_cap + unsigned int max_ee; + unsigned int max_rdd; + unsigned int max_mw; + unsigned int max_raw_ipv6_qp; + unsigned int max_raw_ethy_qp; + unsigned int max_mcast_grp; + unsigned int max_mcast_qp_attach; + unsigned int max_total_mcast_qp_attach; + unsigned int max_ah; + unsigned int max_fmr; + unsigned int max_map_per_fmr; + unsigned int max_srq; + unsigned int max_srq_wr; + unsigned int max_srq_sge; + unsigned int max_pkeys; + unsigned int local_ca_ack_delay; + unsigned int phys_port_cnt; + + ibv_device **ibv_get_device_list(int *n) + void ibv_free_device_list(ibv_device **list); + ibv_context *ibv_open_device(ibv_device *device); + int ibv_close_device(ibv_context *context) + int ibv_query_device(ibv_context *context, ibv_device_attr *device_attr) diff --git a/pyverbs/libibverbs_enums.pxd b/pyverbs/libibverbs_enums.pxd new file mode 100644 index 00000000..d6e81199 --- /dev/null +++ b/pyverbs/libibverbs_enums.pxd @@ -0,0 +1,339 @@ +# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) +# Copyright (c) 2018, Mellanox Technologies. All rights reserved. + +cdef extern from '<infiniband/verbs.h>': + + cpdef enum ibv_atomic_cap: + IBV_ATOMIC_NONE + IBV_ATOMIC_HCA + IBV_ATOMIC_GLOB + + cpdef enum ibv_port_state: + IBV_PORT_NOP = 0 + IBV_PORT_DOWN = 1 + IBV_PORT_INIT = 2 + IBV_PORT_ARMED = 3 + IBV_PORT_ACTIVE = 4 + IBV_PORT_ACTIVE_DEFER = 5 + + cpdef enum ibv_port_cap_flags: + IBV_PORT_SM = 1 << 1 + IBV_PORT_NOTICE_SUP = 1 << 2 + IBV_PORT_TRAP_SUP = 1 << 3 + IBV_PORT_OPT_IPD_SUP = 1 << 4 + IBV_PORT_AUTO_MIGR_SUP = 1 << 5 + IBV_PORT_SL_MAP_SUP = 1 << 6 + IBV_PORT_MKEY_NVRAM = 1 << 7 + IBV_PORT_PKEY_NVRAM = 1 << 8 + IBV_PORT_LED_INFO_SUP = 1 << 9 + IBV_PORT_SYS_IMAGE_GUID_SUP = 1 << 11 + IBV_PORT_PKEY_SW_EXT_PORT_TRAP_SUP = 1 << 12 + IBV_PORT_EXTENDED_SPEEDS_SUP = 1 << 14 + IBV_PORT_CM_SUP = 1 << 16 + IBV_PORT_SNMP_TUNNEL_SUP = 1 << 17 + IBV_PORT_REINIT_SUP = 1 << 18 + IBV_PORT_DEVICE_MGMT_SUP = 1 << 19 + IBV_PORT_VENDOR_CLASS_SUP = 1 << 20 + IBV_PORT_DR_NOTICE_SUP = 1 << 21 + IBV_PORT_CAP_MASK_NOTICE_SUP = 1 << 22 + IBV_PORT_BOOT_MGMT_SUP = 1 << 23 + IBV_PORT_LINK_LATENCY_SUP = 1 << 24 + IBV_PORT_CLIENT_REG_SUP = 1 << 25 + IBV_PORT_IP_BASED_GIDS = 1 << 26 + + cpdef enum ibv_mtu: + IBV_MTU_256 = 1 + IBV_MTU_512 = 2 + IBV_MTU_1024 = 3 + IBV_MTU_2048 = 4 + IBV_MTU_4096 = 5 + + cpdef enum ibv_event_type: + IBV_EVENT_CQ_ERR + IBV_EVENT_QP_FATAL + IBV_EVENT_QP_REQ_ERR + IBV_EVENT_QP_ACCESS_ERR + IBV_EVENT_COMM_EST + IBV_EVENT_SQ_DRAINED + IBV_EVENT_PATH_MIG + IBV_EVENT_PATH_MIG_ERR + IBV_EVENT_DEVICE_FATAL + IBV_EVENT_PORT_ACTIVE + IBV_EVENT_PORT_ERR + IBV_EVENT_LID_CHANGE + IBV_EVENT_PKEY_CHANGE + IBV_EVENT_SM_CHANGE + IBV_EVENT_SRQ_ERR + IBV_EVENT_SRQ_LIMIT_REACHED + IBV_EVENT_QP_LAST_WQE_REACHED + IBV_EVENT_CLIENT_REREGISTER + IBV_EVENT_GID_CHANGE + IBV_EVENT_WQ_FATAL + + cpdef enum ibv_access_flags: + IBV_ACCESS_LOCAL_WRITE = 1 + IBV_ACCESS_REMOTE_WRITE = (1 << 1) + IBV_ACCESS_REMOTE_READ = (1 << 2) + IBV_ACCESS_REMOTE_ATOMIC = (1 << 3) + IBV_ACCESS_MW_BIND = (1 << 4) + IBV_ACCESS_ZERO_BASED = (1 << 5) + IBV_ACCESS_ON_DEMAND = (1 << 6) + + cpdef enum ibv_wr_opcode: + IBV_WR_RDMA_WRITE + IBV_WR_RDMA_WRITE_WITH_IMM + IBV_WR_SEND + IBV_WR_SEND_WITH_IMM + IBV_WR_RDMA_READ + IBV_WR_ATOMIC_CMP_AND_SWP + IBV_WR_ATOMIC_FETCH_AND_ADD + IBV_WR_LOCAL_INV + IBV_WR_BIND_MW + IBV_WR_SEND_WITH_INV + IBV_WR_TSO + + cpdef enum ibv_send_flags: + IBV_SEND_FENCE = 1 << 0 + IBV_SEND_SIGNALED = 1 << 1 + IBV_SEND_SOLICITED = 1 << 2 + IBV_SEND_INLINE = 1 << 3 + IBV_SEND_IP_CSUM = 1 << 4 + + cpdef enum ibv_qp_type: + IBV_QPT_RC = 2 + IBV_QPT_UC = 3 + IBV_QPT_UD = 4 + IBV_QPT_RAW_PACKET = 8 + IBV_QPT_XRC_SEND = 9 + IBV_QPT_XRC_RECV = 10 + IBV_QPT_DRIVER = 0xff + + cpdef enum ibv_qp_state: + IBV_QPS_RESET + IBV_QPS_INIT + IBV_QPS_RTR + IBV_QPS_RTS + IBV_QPS_SQD + IBV_QPS_SQE + IBV_QPS_ERR + IBV_QPS_UNKNOWN + + cpdef enum ibv_mw_type: + IBV_MW_TYPE_1 = 1 + IBV_MW_TYPE_2 = 2 + + cpdef enum ibv_wc_status: + IBV_WC_SUCCESS + IBV_WC_LOC_LEN_ERR + IBV_WC_LOC_QP_OP_ERR + IBV_WC_LOC_EEC_OP_ERR + IBV_WC_LOC_PROT_ERR + IBV_WC_WR_FLUSH_ERR + IBV_WC_MW_BIND_ERR + IBV_WC_BAD_RESP_ERR + IBV_WC_LOC_ACCESS_ERR + IBV_WC_REM_INV_REQ_ERR + IBV_WC_REM_ACCESS_ERR + IBV_WC_REM_OP_ERR + IBV_WC_RETRY_EXC_ERR + IBV_WC_RNR_RETRY_EXC_ERR + IBV_WC_LOC_RDD_VIOL_ERR + IBV_WC_REM_INV_RD_REQ_ERR + IBV_WC_REM_ABORT_ERR + IBV_WC_INV_EECN_ERR + IBV_WC_INV_EEC_STATE_ERR + IBV_WC_FATAL_ERR + IBV_WC_RESP_TIMEOUT_ERR + IBV_WC_GENERAL_ERR + + cpdef enum ibv_wc_opcode: + IBV_WC_SEND + IBV_WC_RDMA_WRITE + IBV_WC_RDMA_READ + IBV_WC_COMP_SWAP + IBV_WC_FETCH_ADD + IBV_WC_BIND_MW + IBV_WC_LOCAL_INV + IBV_WC_TSO + IBV_WC_RECV = 1 << 7 + IBV_WC_RECV_RDMA_WITH_IMM + + cpdef enum ibv_create_cq_wc_flags: + IBV_WC_EX_WITH_BYTE_LEN = 1 << 0 + IBV_WC_EX_WITH_IMM = 1 << 1 + IBV_WC_EX_WITH_QP_NUM = 1 << 2 + IBV_WC_EX_WITH_SRC_QP = 1 << 3 + IBV_WC_EX_WITH_SLID = 1 << 4 + IBV_WC_EX_WITH_SL = 1 << 5 + IBV_WC_EX_WITH_DLID_PATH_BITS = 1 << 6 + IBV_WC_EX_WITH_COMPLETION_TIMESTAMP = 1 << 7 + IBV_WC_EX_WITH_CVLAN = 1 << 8 + IBV_WC_EX_WITH_FLOW_TAG = 1 << 9 + IBV_WC_EX_WITH_TM_INFO = 1 << 10 + + cpdef enum ibv_wc_flags: + IBV_WC_GRH = 1 << 0 + IBV_WC_WITH_IMM = 1 << 1 + IBV_WC_IP_CSUM_OK = 1 << 2 + IBV_WC_WITH_INV = 1 << 3 + IBV_WC_TM_SYNC_REQ = 1 << 4 + IBV_WC_TM_MATCH = 1 << 5 + IBV_WC_TM_DATA_VALID = 1 << 6 + + cpdef enum ibv_tm_cap_flags: + IBV_TM_CAP_RC = 1 << 0, + + cpdef enum ibv_srq_attr_mask: + IBV_SRQ_MAX_WR = 1 << 0, + IBV_SRQ_LIMIT = 1 << 1 + + cpdef enum ibv_srq_type: + IBV_SRQT_BASIC + IBV_SRQT_XRC + IBV_SRQT_TM + + cpdef enum ibv_srq_init_attr_mask: + IBV_SRQ_INIT_ATTR_TYPE = 1 << 0 + IBV_SRQ_INIT_ATTR_PD = 1 << 1 + IBV_SRQ_INIT_ATTR_XRCD = 1 << 2 + IBV_SRQ_INIT_ATTR_CQ = 1 << 3 + IBV_SRQ_INIT_ATTR_TM = 1 << 4 + IBV_SRQ_INIT_ATTR_RESERVED = 1 << 5 + + cpdef enum ibv_mig_state: + IBV_MIG_MIGRATED + IBV_MIG_REARM + IBV_MIG_ARMED + + cpdef enum ibv_qp_init_attr_mask: + IBV_QP_INIT_ATTR_PD = 1 << 0 + IBV_QP_INIT_ATTR_XRCD = 1 << 1 + IBV_QP_INIT_ATTR_CREATE_FLAGS = 1 << 2 + IBV_QP_INIT_ATTR_MAX_TSO_HEADER = 1 << 3 + IBV_QP_INIT_ATTR_IND_TABLE = 1 << 4 + IBV_QP_INIT_ATTR_RX_HASH = 1 << 5 + IBV_QP_INIT_ATTR_RESERVED = 1 << 6 + + cpdef enum ibv_qp_create_flags: + IBV_QP_CREATE_BLOCK_SELF_MCAST_LB = 1 << 1 + IBV_QP_CREATE_SCATTER_FCS = 1 << 8 + IBV_QP_CREATE_CVLAN_STRIPPING = 1 << 9 + IBV_QP_CREATE_SOURCE_QPN = 1 << 10 + IBV_QP_CREATE_PCI_WRITE_END_PADDING = 1 << 11 + + cpdef enum ibv_qp_attr_mask: + IBV_QP_STATE = 1 << 0 + IBV_QP_CUR_STATE = 1 << 1 + IBV_QP_EN_SQD_ASYNC_NOTIFY = 1 << 2 + IBV_QP_ACCESS_FLAGS = 1 << 3 + IBV_QP_PKEY_INDEX = 1 << 4 + IBV_QP_PORT = 1 << 5 + IBV_QP_QKEY = 1 << 6 + IBV_QP_AV = 1 << 7 + IBV_QP_PATH_MTU = 1 << 8 + IBV_QP_TIMEOUT = 1 << 9 + IBV_QP_RETRY_CNT = 1 << 10 + IBV_QP_RNR_RETRY = 1 << 11 + IBV_QP_RQ_PSN = 1 << 12 + IBV_QP_MAX_QP_RD_ATOMIC = 1 << 13 + IBV_QP_ALT_PATH = 1 << 14 + IBV_QP_MIN_RNR_TIMER = 1 << 15 + IBV_QP_SQ_PSN = 1 << 16 + IBV_QP_MAX_DEST_RD_ATOMIC = 1 << 17 + IBV_QP_PATH_MIG_STATE = 1 << 18 + IBV_QP_CAP = 1 << 19 + IBV_QP_DEST_QPN = 1 << 20 + IBV_QP_RATE_LIMIT = 1 << 25 + + cpdef enum ibv_wq_type: + IBV_WQT_RQ + + cpdef enum ibv_wq_init_attr_mask: + IBV_WQ_INIT_ATTR_FLAGS = 1 << 0 + IBV_WQ_INIT_ATTR_RESERVED = 1 << 1 + + cpdef enum ibv_wq_flags: + IBV_WQ_FLAGS_CVLAN_STRIPPING = 1 << 0 + IBV_WQ_FLAGS_SCATTER_FCS = 1 << 1 + IBV_WQ_FLAGS_DELAY_DROP = 1 << 2 + IBV_WQ_FLAGS_PCI_WRITE_END_PADDING = 1 << 3 + IBV_WQ_FLAGS_RESERVED = 1 << 4 + + cpdef enum ibv_wq_state: + IBV_WQS_RESET + IBV_WQS_RDY + IBV_WQS_ERR + IBV_WQS_UNKNOWN + + cpdef enum ibv_wq_attr_mask: + IBV_WQ_ATTR_STATE = 1 << 0 + IBV_WQ_ATTR_CURR_STATE = 1 << 1 + IBV_WQ_ATTR_FLAGS = 1 << 2 + IBV_WQ_ATTR_RESERVED = 1 << 3 + + cpdef enum ibv_rx_hash_function_flags: + IBV_RX_HASH_FUNC_TOEPLITZ = 1 << 0 + + cpdef enum ibv_rx_hash_fields: + IBV_RX_HASH_SRC_IPV4 = 1 << 0 + IBV_RX_HASH_DST_IPV4 = 1 << 1 + IBV_RX_HASH_SRC_IPV6 = 1 << 2 + IBV_RX_HASH_DST_IPV6 = 1 << 3 + IBV_RX_HASH_SRC_PORT_TCP = 1 << 4 + IBV_RX_HASH_DST_PORT_TCP = 1 << 5 + IBV_RX_HASH_SRC_PORT_UDP = 1 << 6 + IBV_RX_HASH_DST_PORT_UDP = 1 << 7 + + cpdef enum ibv_ops_wr_opcode: + IBV_WR_TAG_ADD + IBV_WR_TAG_DEL + IBV_WR_TAG_SYNC + + cpdef enum ibv_ops_flags: + IBV_OPS_SIGNALED = 1 << 0 + IBV_OPS_TM_SYNC = 1 << 1 + + cpdef enum ibv_flow_flags: + IBV_FLOW_ATTR_FLAGS_ALLOW_LOOP_BACK = 1 << 0 + IBV_FLOW_ATTR_FLAGS_DONT_TRAP = 1 << 1 + IBV_FLOW_ATTR_FLAGS_EGRESS = 1 << 2 + + cpdef enum ibv_flow_attr_type: + IBV_FLOW_ATTR_NORMAL = 0x0 + IBV_FLOW_ATTR_ALL_DEFAULT = 0x1 + IBV_FLOW_ATTR_MC_DEFAULT = 0x2 + IBV_FLOW_ATTR_SNIFFER = 0x3 + + cpdef enum ibv_flow_spec_type: + IBV_FLOW_SPEC_ETH = 0x20 + IBV_FLOW_SPEC_IPV4 = 0x30 + IBV_FLOW_SPEC_IPV6 = 0x31 + IBV_FLOW_SPEC_IPV4_EXT = 0x32 + IBV_FLOW_SPEC_ESP = 0x34 + IBV_FLOW_SPEC_TCP = 0x40 + IBV_FLOW_SPEC_UDP = 0x41 + IBV_FLOW_SPEC_VXLAN_TUNNEL = 0x50 + IBV_FLOW_SPEC_GRE = 0x51 + IBV_FLOW_SPEC_MPLS = 0x60 + IBV_FLOW_SPEC_INNER = 0x100 + IBV_FLOW_SPEC_ACTION_TAG = 0x1000 + IBV_FLOW_SPEC_ACTION_DROP = 0x1001 + IBV_FLOW_SPEC_ACTION_HANDLE = 0x1002 + IBV_FLOW_SPEC_ACTION_COUNT = 0x1003 + + cpdef enum: + IBV_QPF_GRH_REQUIRED + + cpdef enum ibv_counter_description: + IBV_COUNTER_PACKETS + IBV_COUNTER_BYTES + + cpdef enum ibv_read_counters_flags: + IBV_READ_COUNTERS_ATTR_PREFER_CACHED = 1 << 0 + +cdef extern from "<infiniband/tm_types.h>": + cpdef enum ibv_tmh_op: + IBV_TMH_NO_TAG = 0 + IBV_TMH_RNDV = 1 + IBV_TMH_FIN = 2 + IBV_TMH_EAGER = 3 diff --git a/pyverbs/pyverbs_error.py b/pyverbs/pyverbs_error.py new file mode 100644 index 00000000..a82086f4 --- /dev/null +++ b/pyverbs/pyverbs_error.py @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) +# Copyright (c) 2018, Mellanox Technologies. All rights reserved. +import os + + +class PyverbsError(Exception): + """ + Base exception class for Pyverbs. Inherited by PyverbsRDMAError (for errors + returned by rdma-core) and PyverbsUserError (for user-related errors + found by Pyverbs, e.g. non-existing device name). + """ + def __init__(self, msg, error_code = -1): + """ + Initializes a PyverbsError instance + :param msg: The exception's message + :param error_code: errno value + """ + if error_code != -1: + msg = '{msg}. Errno: {err}, {err_str}'.\ + format(msg=msg, err=error_code, err_str=os.strerror(error_code)) + super(PyverbsError, self).__init__(msg) + +class PyverbsRDMAError(PyverbsError): + """ + This exception is raised when an rdma-core function returns an error. + """ + pass + +class PyverbsUserError(PyverbsError): + """ + This exception is raised when Pyverbs encounters an error resulting from + user's action or input. + """ + def __init__(self, msg): + """ + Initializes a PyverbsUserError instance + :param msg: The exception's message + """ + super(PyverbsUserError, self).__init__(msg) + -- 2.19.1