[PATCH rdma-core 01/10] pyverbs: Introducing pyverbs and its context class

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 | 344 +++++++++++++++++++++++++++++++++++
 pyverbs/pyverbs_error.py     |  40 ++++
 10 files changed, 765 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..99d8b670
--- /dev/null
+++ b/pyverbs/libibverbs_enums.pxd
@@ -0,0 +1,344 @@
+# 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_atomic_cap:
+        IBV_ATOMIC_NONE
+        IBV_ATOMIC_HCA
+        IBV_ATOMIC_GLOB
+
+    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




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux