blob: ec6eeb6d5a2e56b14830a436dd30fce60fb5541f [file]
# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB)
# Copyright (c) 2021 Nvidia, Inc. All rights reserved. See COPYING file
"""
This module wraps mlx5dv_<obj> C structs, such as mlx5dv_cq, mlx5dv_qp etc.
It exposes to the users the mlx5 driver-specific attributes for ibv objects by
extracting them via mlx5dv_init_obj() API by using Mlx5DvObj class, which holds
all the (currently) supported Mlx5Dv<Obj> objects.
Note: This is not be confused with Mlx5<Obj> which holds the ibv_<obj>_ex that
was created using mlx5dv_create_<obj>().
"""
from libc.stdint cimport uintptr_t, uint32_t
from pyverbs.pyverbs_error import PyverbsUserError, PyverbsRDMAError
cimport pyverbs.providers.mlx5.mlx5dv_enums as dve
cimport pyverbs.libibverbs as v
cdef class Mlx5DvPD(PyverbsObject):
@property
def pdn(self):
""" The protection domain object number """
return self.dv_pd.pdn
@property
def comp_mask(self):
return self.dv_pd.comp_mask
cdef class Mlx5DvCQ(PyverbsObject):
@property
def cqe_size(self):
return self.dv_cq.cqe_size
@property
def comp_mask(self):
return self.dv_cq.comp_mask
@property
def cqn(self):
return self.dv_cq.cqn
@property
def buf(self):
return <uintptr_t><void*>self.dv_cq.buf
@property
def cq_uar(self):
return <uintptr_t><void*>self.dv_cq.cq_uar
@property
def dbrec(self):
return <uintptr_t><uint32_t*>self.dv_cq.dbrec
@property
def cqe_cnt(self):
return self.dv_cq.cqe_cnt
cdef class Mlx5DvQP(PyverbsObject):
@property
def rqn(self):
""" The receive queue number of the QP"""
return self.dv_qp.rqn
@property
def sqn(self):
""" The send queue number of the QP"""
return self.dv_qp.sqn
@property
def tirn(self):
"""
The number of the transport interface receive object that attached
to the RQ of the QP
"""
return self.dv_qp.tirn
@property
def tisn(self):
"""
The number of the transport interface send object that attached
to the SQ of the QP
"""
return self.dv_qp.tisn
@property
def comp_mask(self):
return self.dv_qp.comp_mask
@comp_mask.setter
def comp_mask(self, val):
self.dv_qp.comp_mask = val
@property
def uar_mmap_offset(self):
return self.uar_mmap_offset
cdef class Mlx5DvSRQ(PyverbsObject):
@property
def stride(self):
return self.dv_srq.stride
@property
def head(self):
return self.dv_srq.stride
@property
def tail(self):
return self.dv_srq.stride
@property
def comp_mask(self):
return self.dv_srq.comp_mask
@comp_mask.setter
def comp_mask(self, val):
self.dv_srq.comp_mask = val
@property
def srqn(self):
""" The shared receive queue object number """
return self.dv_srq.srqn
cdef class Mlx5DvObj(PyverbsObject):
"""
Mlx5DvObj represents mlx5dv_obj C struct.
"""
def __init__(self, obj_type=None, **kwargs):
"""
Retrieves DV objects from ibv object to be able to extract attributes
(such as cqe_size of a CQ).
Currently supports CQ, QP, PD and SRQ objects.
The initialized objects can be accessed using self.dvobj (e.g. self.dvcq).
:param obj_type: Bitmask which defines what objects was provided.
Currently it supports: MLX5DV_OBJ_CQ, MLX5DV_OBJ_QP,
MLX5DV_OBJ_SRQ and MLX5DV_OBJ_PD.
:param kwargs: List of objects (cq, qp, pd, srq) from which to extract
data and their comp_masks if applicable. If comp_mask is
not provided by user, mask all by default.
"""
self.dv_pd = self.dv_cq = self.dv_qp = self.dv_srq = None
if obj_type is None:
return
self.init_obj(obj_type, **kwargs)
def init_obj(self, obj_type, **kwargs):
"""
Initialize DV objects.
The objects are re-initialized if they're already extracted.
"""
supported_obj_types = dve.MLX5DV_OBJ_CQ | dve.MLX5DV_OBJ_QP | \
dve.MLX5DV_OBJ_PD | dve.MLX5DV_OBJ_SRQ
if obj_type & supported_obj_types is False:
raise PyverbsUserError('Invalid obj_type was provided')
cq = kwargs.get('cq') if obj_type | dve.MLX5DV_OBJ_CQ else None
qp = kwargs.get('qp') if obj_type | dve.MLX5DV_OBJ_QP else None
pd = kwargs.get('pd') if obj_type | dve.MLX5DV_OBJ_PD else None
srq = kwargs.get('srq') if obj_type | dve.MLX5DV_OBJ_SRQ else None
if cq is qp is pd is srq is None:
raise PyverbsUserError("No supported object was provided.")
if cq:
dv_cq = Mlx5DvCQ()
self.obj.cq.in_ = <v.ibv_cq*>cq.cq
self.obj.cq.out = &(dv_cq.dv_cq)
self.dv_cq = dv_cq
if qp:
dv_qp = Mlx5DvQP()
comp_mask = kwargs.get('qp_comp_mask')
dv_qp.comp_mask = comp_mask if comp_mask else \
dv.MLX5DV_QP_MASK_UAR_MMAP_OFFSET | \
dv.MLX5DV_QP_MASK_RAW_QP_HANDLES | \
dv.MLX5DV_QP_MASK_RAW_QP_TIR_ADDR
self.obj.qp.in_ = <v.ibv_qp*>qp.qp
self.obj.qp.out = &(dv_qp.dv_qp)
self.dv_qp = dv_qp
if pd:
dv_pd = Mlx5DvPD()
self.obj.pd.in_ = <v.ibv_pd*>pd.pd
self.obj.pd.out = &(dv_pd.dv_pd)
self.dv_pd = dv_pd
if srq:
dv_srq = Mlx5DvSRQ()
comp_mask = kwargs.get('srq_comp_mask')
dv_srq.comp_mask = comp_mask if comp_mask else dv.MLX5DV_SRQ_MASK_SRQN
self.obj.srq.in_ = <v.ibv_srq*>srq.srq
self.obj.srq.out = &(dv_srq.dv_srq)
self.dv_srq = dv_srq
rc = dv.mlx5dv_init_obj(&self.obj, obj_type)
if rc != 0:
raise PyverbsRDMAError("Failed to initialize Mlx5DvObj", rc)
@property
def dvcq(self):
return self.dv_cq
@property
def dvqp(self):
return self.dv_qp
@property
def dvpd(self):
return self.dv_pd
@property
def dvsrq(self):
return self.dv_srq