From patchwork Sun Feb 24 13:06:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Noa Osherovich X-Patchwork-Id: 10827961 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 66B8F1575 for ; Sun, 24 Feb 2019 13:09:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 54ABB29DAD for ; Sun, 24 Feb 2019 13:09:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4905B2AA01; Sun, 24 Feb 2019 13:09:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 603DA2A98F for ; Sun, 24 Feb 2019 13:09:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728298AbfBXNJA (ORCPT ); Sun, 24 Feb 2019 08:09:00 -0500 Received: from mail-il-dmz.mellanox.com ([193.47.165.129]:50551 "EHLO mellanox.co.il" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728296AbfBXNJA (ORCPT ); Sun, 24 Feb 2019 08:09:00 -0500 Received: from Internal Mail-Server by MTLPINE1 (envelope-from noaos@mellanox.com) with ESMTPS (AES256-SHA encrypted); 24 Feb 2019 15:06:49 +0200 Received: from reg-l-vrt-059-009.mtl.labs.mlnx (reg-l-vrt-059-009.mtl.labs.mlnx [10.135.59.9]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x1OD6mfh026210; Sun, 24 Feb 2019 15:06:49 +0200 From: Noa Osherovich To: leonro@mellanox.com, jgg@mellanox.com, dledford@redhat.com Cc: linux-rdma@vger.kernel.org, Noa Osherovich Subject: [PATCH rdma-core 13/19] pyverbs: Add query_port method Date: Sun, 24 Feb 2019 15:06:32 +0200 Message-Id: <20190224130638.31848-14-noaos@mellanox.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190224130638.31848-1-noaos@mellanox.com> References: <20190224130638.31848-1-noaos@mellanox.com> Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Context class can now query its ports. A PortAttr object with a user-friendly print function is returned to the user. Signed-off-by: Noa Osherovich --- pyverbs/device.pxd | 3 + pyverbs/device.pyx | 196 +++++++++++++++++++++++++++++++++++ pyverbs/libibverbs.pxd | 26 +++++ pyverbs/libibverbs_enums.pxd | 14 +++ 4 files changed, 239 insertions(+) diff --git a/pyverbs/device.pxd b/pyverbs/device.pxd index c9e346539e58..a7089972985b 100644 --- a/pyverbs/device.pxd +++ b/pyverbs/device.pxd @@ -47,3 +47,6 @@ cdef class DM(PyverbsCM): cdef object dm_mrs cdef object context cdef add_ref(self, obj) + +cdef class PortAttr(PyverbsObject): + cdef v.ibv_port_attr attr diff --git a/pyverbs/device.pyx b/pyverbs/device.pyx index 7bfcda8bc177..757eebf67c48 100644 --- a/pyverbs/device.pyx +++ b/pyverbs/device.pyx @@ -11,6 +11,7 @@ import weakref from .pyverbs_error import PyverbsRDMAError, PyverbsError from .pyverbs_error import PyverbsUserError from pyverbs.base import PyverbsRDMAErrno +cimport pyverbs.libibverbs_enums as e cimport pyverbs.libibverbs as v from pyverbs.addr cimport GID from pyverbs.mr import DMMR @@ -165,6 +166,18 @@ cdef class Context(PyverbsCM): format(idx=index, port=port_num)) return gid + def query_port(self, unsigned int port_num): + """ + Query port of the device and returns its attributes. + :param port_num: Port number to query + :return: PortAttr object on success + """ + port_attrs = PortAttr() + rc = v.ibv_query_port(self.context, port_num, &port_attrs.attr) + if rc != 0: + raise PyverbsRDMAErrno('Failed to query port {p}'.format(p=port_num)) + return port_attrs + cdef add_ref(self, obj): if isinstance(obj, PD): self.pds.add(obj) @@ -585,6 +598,99 @@ cdef class DM(PyverbsCM): return res +cdef class PortAttr(PyverbsObject): + @property + def state(self): + return self.attr.state + @property + def max_mtu(self): + return self.attr.max_mtu + @property + def active_mtu(self): + return self.attr.active_mtu + @property + def gid_tbl_len(self): + return self.attr.gid_tbl_len + @property + def port_cap_flags(self): + return self.attr.port_cap_flags + @property + def max_msg_sz(self): + return self.attr.max_msg_sz + @property + def bad_pkey_cntr(self): + return self.attr.bad_pkey_cntr + @property + def qkey_viol_cntr(self): + return self.attr.qkey_viol_cntr + @property + def pkey_tbl_len(self): + return self.attr.pkey_tbl_len + @property + def lid(self): + return self.attr.lid + @property + def sm_lid(self): + return self.attr.sm_lid + @property + def lmc(self): + return self.attr.lmc + @property + def max_vl_num(self): + return self.attr.max_vl_num + @property + def sm_sl(self): + return self.attr.sm_sl + @property + def subnet_timeout(self): + return self.attr.subnet_timeout + @property + def init_type_reply(self): + return self.attr.init_type_reply + @property + def active_width(self): + return self.attr.active_width + @property + def active_speed(self): + return self.attr.active_speed + @property + def phys_state(self): + return self.attr.phys_state + @property + def link_layer(self): + return self.attr.link_layer + @property + def flags(self): + return self.attr.flags + @property + def port_cap_flags2(self): + return self.attr.port_cap_flags2 + + def __str__(self): + print_format = '{:<24}: {:<20}\n' + return print_format.format('Port state', port_state_to_str(self.attr.state)) +\ + print_format.format('Max MTU', translate_mtu(self.attr.max_mtu)) +\ + print_format.format('Active MTU', translate_mtu(self.attr.active_mtu)) +\ + print_format.format('SM lid', self.attr.sm_lid) +\ + print_format.format('Port lid', self.attr.lid) +\ + print_format.format('lmc', hex(self.attr.lmc)) +\ + print_format.format('Link layer', translate_link_layer(self.attr.link_layer)) +\ + print_format.format('Max message size', hex(self.attr.max_msg_sz)) +\ + print_format.format('Port cap flags', translate_port_cap_flags(self.attr.port_cap_flags)) +\ + print_format.format('Port cap flags 2', translate_port_cap_flags2(self.attr.port_cap_flags2)) +\ + print_format.format('max VL num', self.attr.max_vl_num) +\ + print_format.format('Bad Pkey counter', self.attr.bad_pkey_cntr) +\ + print_format.format('Qkey violations counter', self.attr.qkey_viol_cntr) +\ + print_format.format('GID table len', self.attr.gid_tbl_len) +\ + print_format.format('Pkey table len', self.attr.pkey_tbl_len) +\ + print_format.format('SM sl', self.attr.sm_sl) +\ + print_format.format('Subnet timeout', self.attr.subnet_timeout) +\ + print_format.format('Init type reply', self.attr.init_type_reply) +\ + print_format.format('Active width', width_to_str(self.attr.active_width)) +\ + print_format.format('Active speed', speed_to_str(self.attr.active_speed)) +\ + print_format.format('Phys state', phys_state_to_str(self.attr.phys_state)) +\ + print_format.format('Flags', self.attr.flags) + def guid_format(num): """ Get GUID representation of the given number, including change of endianness. @@ -608,6 +714,96 @@ def translate_node_type(node_type): def guid_to_hex(node_guid): return hex(node_guid).replace('L', '').replace('0x', '') +def port_state_to_str(port_state): + l = {0: 'NOP', 1: 'Down', 2: 'Init', 3: 'Armed',4: 'Active', + 5: 'Active defer'} + try: + return '{s} ({n})'.format(s=l[port_state], n=port_state) + except: + return 'Invalid state' + +def translate_mtu(mtu): + l = {1: 256, 2: 512, 3: 1024, 4: 2048, 5: 4096} + try: + return '{s} ({n})'.format(s=l[mtu], n=mtu) + except: + return 'Invalid MTU' + +def translate_link_layer(ll): + l = {0: 'Unspecified', 1:'InfiniBand', 2:'Ethernet'} + try: + return l[ll] + except: + return 'Invalid link layer {ll}'.format(ll=ll) + +def translate_port_cap_flags(flags): + l = {e.IBV_PORT_SM: 'IBV_PORT_SM', + e.IBV_PORT_NOTICE_SUP: 'IBV_PORT_NOTICE_SUP', + e.IBV_PORT_TRAP_SUP: 'IBV_PORT_TRAP_SUP', + e.IBV_PORT_OPT_IPD_SUP: 'IBV_PORT_OPT_IPD_SUP', + e.IBV_PORT_AUTO_MIGR_SUP: 'IBV_PORT_AUTO_MIGR_SUP', + e.IBV_PORT_SL_MAP_SUP: 'IBV_PORT_SL_MAP_SUP', + e.IBV_PORT_MKEY_NVRAM: 'IBV_PORT_MKEY_NVRAM', + e.IBV_PORT_PKEY_NVRAM: 'IBV_PORT_PKEY_NVRAM', + e.IBV_PORT_LED_INFO_SUP: 'IBV_PORT_LED_INFO_SUP', + e.IBV_PORT_SYS_IMAGE_GUID_SUP: 'IBV_PORT_SYS_IMAGE_GUID_SUP', + e.IBV_PORT_PKEY_SW_EXT_PORT_TRAP_SUP: 'IBV_PORT_PKEY_SW_EXT_PORT_TRAP_SUP', + e.IBV_PORT_EXTENDED_SPEEDS_SUP: 'IBV_PORT_EXTENDED_SPEEDS_SUP', + e.IBV_PORT_CAP_MASK2_SUP: 'IBV_PORT_CAP_MASK2_SUP', + e.IBV_PORT_CM_SUP: 'IBV_PORT_CM_SUP', + e.IBV_PORT_SNMP_TUNNEL_SUP: 'IBV_PORT_SNMP_TUNNEL_SUP', + e.IBV_PORT_REINIT_SUP: 'IBV_PORT_REINIT_SUP', + e.IBV_PORT_DEVICE_MGMT_SUP: 'IBV_PORT_DEVICE_MGMT_SUP', + e.IBV_PORT_VENDOR_CLASS_SUP: 'IBV_PORT_VENDOR_CLASS_SUP', + e.IBV_PORT_DR_NOTICE_SUP: 'IBV_PORT_DR_NOTICE_SUP', + e.IBV_PORT_CAP_MASK_NOTICE_SUP: 'IBV_PORT_CAP_MASK_NOTICE_SUP', + e.IBV_PORT_BOOT_MGMT_SUP: 'IBV_PORT_BOOT_MGMT_SUP', + e.IBV_PORT_LINK_LATENCY_SUP: 'IBV_PORT_LINK_LATENCY_SUP', + e.IBV_PORT_CLIENT_REG_SUP: 'IBV_PORT_CLIENT_REG_SUP', + e.IBV_PORT_IP_BASED_GIDS: 'IBV_PORT_IP_BASED_GIDS'} + return str_from_flags(flags, l) + +def translate_port_cap_flags2(flags): + l = {e.IBV_PORT_SET_NODE_DESC_SUP: 'IBV_PORT_SET_NODE_DESC_SUP', + e.IBV_PORT_INFO_EXT_SUP: 'IBV_PORT_INFO_EXT_SUP', + e.IBV_PORT_VIRT_SUP: 'IBV_PORT_VIRT_SUP', + e.IBV_PORT_SWITCH_PORT_STATE_TABLE_SUP: 'IBV_PORT_SWITCH_PORT_STATE_TABLE_SUP', + e.IBV_PORT_LINK_WIDTH_2X_SUP: 'IBV_PORT_LINK_WIDTH_2X_SUP', + e.IBV_PORT_LINK_SPEED_HDR_SUP: 'IBV_PORT_LINK_SPEED_HDR_SUP'} + return str_from_flags(flags, l) + +def str_from_flags(flags, dictionary): + str_flags = "" + for bit in dictionary: + if flags & bit: + str_flags += dictionary[bit] + str_flags += ' ' + return str_flags + +def phys_state_to_str(phys): + l = {1: 'Sleep', 2: 'Polling', 3: 'Disabled', + 4: 'Port configuration training', 5: 'Link up', + 6: 'Link error recovery', 7: 'Phy test'} + try: + return '{s} ({n})'.format(s=l[phys], n=phys) + except: + return 'Invalid physical state' + +def width_to_str(width): + l = {1: '1X', 2: '4X', 4: '8X', 16: '2X'} + try: + return '{s} ({n})'.format(s=l[width], n=width) + except: + return 'Invalid width' + +def speed_to_str(speed): + l = {1: '2.5 Gbps', 2: '5.0 Gbps', 4: '5.0 Gbps', 8: '10.0 Gbps', + 16: '14.0 Gbps', 32: '25.0 Gbps', 64: '50.0 Gbps'} + try: + return '{s} ({n})'.format(s=l[speed], n=speed) + except: + return 'Invalid speed' + def get_device_list(): """ :return: list of IB_devices on current node diff --git a/pyverbs/libibverbs.pxd b/pyverbs/libibverbs.pxd index 5dd3ba013e5e..c6b564c4d487 100644 --- a/pyverbs/libibverbs.pxd +++ b/pyverbs/libibverbs.pxd @@ -148,6 +148,30 @@ cdef extern from 'infiniband/verbs.h': ibv_context *context unsigned int comp_mask + cdef struct ibv_port_attr: + ibv_port_state state + ibv_mtu max_mtu + ibv_mtu active_mtu + int gid_tbl_len + unsigned int port_cap_flags + unsigned int max_msg_sz + unsigned int bad_pkey_cntr + unsigned int qkey_viol_cntr + unsigned short pkey_tbl_len + unsigned short lid + unsigned short sm_lid + unsigned char lmc + unsigned char max_vl_num + unsigned char sm_sl + unsigned char subnet_timeout + unsigned char init_type_reply + unsigned char active_width + unsigned char active_speed + unsigned char phys_state + unsigned char link_layer + unsigned char flags + unsigned short port_cap_flags2 + ibv_device **ibv_get_device_list(int *n) void ibv_free_device_list(ibv_device **list) ibv_context *ibv_open_device(ibv_device *device) @@ -173,3 +197,5 @@ cdef extern from 'infiniband/verbs.h': size_t length) int ibv_memcpy_from_dm(void *host_addr, ibv_dm *dm, unsigned long dm_offset, size_t length) + int ibv_query_port(ibv_context *context, uint8_t port_num, + ibv_port_attr *port_attr) diff --git a/pyverbs/libibverbs_enums.pxd b/pyverbs/libibverbs_enums.pxd index d6e81199fae3..2525e869a201 100644 --- a/pyverbs/libibverbs_enums.pxd +++ b/pyverbs/libibverbs_enums.pxd @@ -3,6 +3,11 @@ cdef extern from '': + cpdef enum: + IBV_LINK_LAYER_UNSPECIFIED + IBV_LINK_LAYER_INFINIBAND + IBV_LINK_LAYER_ETHERNET + cpdef enum ibv_atomic_cap: IBV_ATOMIC_NONE IBV_ATOMIC_HCA @@ -29,6 +34,7 @@ cdef extern from '': 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_CAP_MASK2_SUP = 1 << 15, IBV_PORT_CM_SUP = 1 << 16 IBV_PORT_SNMP_TUNNEL_SUP = 1 << 17 IBV_PORT_REINIT_SUP = 1 << 18 @@ -41,6 +47,14 @@ cdef extern from '': IBV_PORT_CLIENT_REG_SUP = 1 << 25 IBV_PORT_IP_BASED_GIDS = 1 << 26 + cpdef enum ibv_port_cap_flags2: + IBV_PORT_SET_NODE_DESC_SUP = 1 << 0 + IBV_PORT_INFO_EXT_SUP = 1 << 1 + IBV_PORT_VIRT_SUP = 1 << 2 + IBV_PORT_SWITCH_PORT_STATE_TABLE_SUP = 1 << 3 + IBV_PORT_LINK_WIDTH_2X_SUP = 1 << 4 + IBV_PORT_LINK_SPEED_HDR_SUP = 1 << 5 + cpdef enum ibv_mtu: IBV_MTU_256 = 1 IBV_MTU_512 = 2