Skip to content

Commit

Permalink
pyverbs: Add query_gid_table and query_gid_ex methods
Browse files Browse the repository at this point in the history
Add two new methods to Context class: query_gid_table and query_gid_ex.

query_gid_table queries all GID tables of the device and returns
a list of GIDEntry objects containing all valid GID entries.

query_gid_ex queries the GID table of the given port in the given index
and returns a GIDEntry object.

Signed-off-by: Avihai Horon <avihaih@nvidia.com>
Signed-off-by: Edward Srouji <edwards@nvidia.com>
  • Loading branch information
avihai1122 authored and Yishai Hadas committed Oct 11, 2020
1 parent bbb4f4c commit e03754e
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
3 changes: 3 additions & 0 deletions pyverbs/device.pxd
Expand Up @@ -64,3 +64,6 @@ cdef class DM(PyverbsCM):

cdef class PortAttr(PyverbsObject):
cdef v.ibv_port_attr attr

cdef class GIDEntry(PyverbsObject):
cdef v.ibv_gid_entry entry
106 changes: 106 additions & 0 deletions pyverbs/device.pyx
Expand Up @@ -26,6 +26,8 @@ from libc.stdlib cimport free, malloc
from libc.string cimport memset
from libc.stdint cimport uint64_t
from libc.stdint cimport uint16_t
from libc.stdint cimport uint32_t
from pyverbs.utils import gid_str

cdef extern from 'endian.h':
unsigned long be64toh(unsigned long host_64bits);
Expand Down Expand Up @@ -240,6 +242,53 @@ cdef class Context(PyverbsCM):
format(p=port_num), rc)
return port_attrs

def query_gid_table(self, size_t max_entries, uint32_t flags=0):
"""
Queries the GID tables of the device for at most <max_entries> entries
and returns them.
:param max_entries: Maximum number of GID entries to retrieve
:param flags: Specifies new extra members of struct ibv_gid_entry to
query
:return: List of GIDEntry objects on success
"""
cdef v.ibv_gid_entry *entries
cdef v.ibv_gid_entry entry

entries = <v.ibv_gid_entry *>malloc(max_entries *
sizeof(v.ibv_gid_entry))
rc = v.ibv_query_gid_table(self.context, entries, max_entries, flags)
if rc < 0:
raise PyverbsRDMAError('Failed to query gid tables of the device',
rc)
gid_entries = []
for i in range(rc):
entry = entries[i]
gid_entries.append(GIDEntry(entry.gid._global.subnet_prefix,
entry.gid._global.interface_id, entry.gid_index,
entry.port_num, entry.gid_type,
entry.ndev_ifindex))
free(entries)
return gid_entries

def query_gid_ex(self, uint32_t port_num, uint32_t gid_index,
uint32_t flags=0):
"""
Queries the GID table of port <port_num> in index <gid_index>, and
returns the GID entry.
:param port_num: The port number to query
:param gid_index: The index in the GID table to query
:param flags: Specifies new extra members of struct ibv_gid_entry to
query
:return: GIDEntry object on success
"""
entry = GIDEntry()
rc = v.ibv_query_gid_ex(self.context, port_num, gid_index,
&entry.entry, flags)
if rc != 0:
raise PyverbsRDMAError(f'Failed to query gid table of port '\
f'{port_num} in index {gid_index}', rc)
return entry

cdef add_ref(self, obj):
if isinstance(obj, PD):
self.pds.add(obj)
Expand Down Expand Up @@ -816,6 +865,63 @@ cdef class PortAttr(PyverbsObject):
print_format.format('Flags', self.attr.flags)


cdef class GIDEntry(PyverbsObject):
def __init__(self, subnet_prefix=0, interface_id=0, gid_index=0,
port_num=0, gid_type=0, ndev_ifindex=0):
super().__init__()
self.entry.gid._global.subnet_prefix = subnet_prefix
self.entry.gid._global.interface_id = interface_id
self.entry.gid_index = gid_index
self.entry.port_num = port_num
self.entry.gid_type = gid_type
self.entry.ndev_ifindex = ndev_ifindex

@property
def gid_subnet_prefix(self):
return self.entry.gid._global.subnet_prefix

@property
def gid_interface_id(self):
return self.entry.gid._global.interface_id

@property
def gid_index(self):
return self.entry.gid_index

@property
def port_num(self):
return self.entry.port_num

@property
def gid_type(self):
return self.entry.gid_type

@property
def ndev_ifindex(self):
return self.entry.ndev_ifindex

def gid_str(self):
return gid_str(self.gid_subnet_prefix, self.gid_interface_id)

def __str__(self):
print_format = '{:<24}: {:<20}\n'
return print_format.format('GID', self.gid_str()) +\
print_format.format('GID Index', self.gid_index) +\
print_format.format('Port number', self.port_num) +\
print_format.format('GID type', translate_gid_type(
self.gid_type)) +\
print_format.format('Ndev ifindex', self.ndev_ifindex)


def translate_gid_type(gid_type):
types = {e.IBV_GID_TYPE_IB: 'IB', e.IBV_GID_TYPE_ROCE_V1: 'RoCEv1',
e.IBV_GID_TYPE_ROCE_V2: 'RoCEv2'}
try:
return types[gid_type]
except KeyError:
return f'Unknown gid_type ({gid_type})'


def guid_format(num):
"""
Get GUID representation of the given number, including change of endianness.
Expand Down
13 changes: 13 additions & 0 deletions pyverbs/libibverbs.pxd
Expand Up @@ -483,6 +483,13 @@ cdef extern from 'infiniband/verbs.h':
uint32_t options
uint32_t comp_mask

cdef struct ibv_gid_entry:
ibv_gid gid
uint32_t gid_index
uint32_t port_num
uint32_t gid_type
uint32_t ndev_ifindex

ibv_device **ibv_get_device_list(int *n)
int ibv_get_device_index(ibv_device *device);
void ibv_free_device_list(ibv_device **list)
Expand Down Expand Up @@ -613,6 +620,12 @@ cdef extern from 'infiniband/verbs.h':
void ibv_unimport_mr(ibv_mr *mr)
ibv_pd *ibv_import_pd(ibv_context *context, uint32_t handle)
void ibv_unimport_pd(ibv_pd *pd)
int ibv_query_gid_ex(ibv_context *context, uint32_t port_num,
uint32_t gid_index, ibv_gid_entry *entry,
uint32_t flags)
ssize_t ibv_query_gid_table(ibv_context *context,
ibv_gid_entry *entries, size_t max_entries,
uint32_t flags)


cdef extern from 'infiniband/driver.h':
Expand Down
5 changes: 5 additions & 0 deletions pyverbs/libibverbs_enums.pxd
Expand Up @@ -427,6 +427,11 @@ cdef extern from '<infiniband/verbs.h>':

cdef void *IBV_ALLOCATOR_USE_DEFAULT

cpdef enum ibv_gid_type:
IBV_GID_TYPE_IB
IBV_GID_TYPE_ROCE_V1
IBV_GID_TYPE_ROCE_V2


cdef extern from "<infiniband/verbs_api.h>":
cdef unsigned long long IBV_ADVISE_MR_ADVICE_PREFETCH
Expand Down

0 comments on commit e03754e

Please sign in to comment.