# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) # Copyright (c) 2021 Nvidia, Inc. All rights reserved. See COPYING file """ This module wraps mlx5dv_ 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 objects. Note: This is not be confused with Mlx5 which holds the ibv__ex that was created using mlx5dv_create_(). """ from libc.stdint cimport uintptr_t, uint32_t from pyverbs.pyverbs_error import PyverbsUserError, PyverbsRDMAError cimport pyverbs.providers.mlx5.mlx5_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 self.dv_cq.buf @property def cq_uar(self): return self.dv_cq.cq_uar @property def dbrec(self): return 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_ = 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_ = qp.qp self.obj.qp.out = &(dv_qp.dv_qp) self.dv_qp = dv_qp if pd: dv_pd = Mlx5DvPD() self.obj.pd.in_ = 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_ = 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