# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) # Copyright (c) 2020 Mellanox Technologies, Inc. All rights reserved. See COPYING file """ Test module for Shared PD. """ import unittest import errno import os from tests.test_qpex import QpExRCRDMAWrite from tests.base import RDMATestCase from pyverbs.device import Context from pyverbs.pd import PD from pyverbs.mr import MR import pyverbs.enums as e import tests.utils as u def get_import_res_class(base_class): """ This function creates a class that inherits base_class of any BaseResources type. Its purpose is to behave exactly as base_class does, except for the objects creation, which instead of creating context, PD and MR, it imports them. Hence the returned class must be initialized with (cmd_fd, pd_handle, mr_handle, mr_addr, **kwargs), while kwargs are the arguments needed (if any) for base_class. In addition it has unimport_resources() method which unimprot all the resources and closes the imported PD object. :param base_class: The base resources class to inherit from :return: ImportResources(cmd_fd, pd_handle, mr_handle, mr_addr, **kwargs) class """ class ImportResources(base_class): def __init__(self, cmd_fd, pd_handle, mr_handle, mr_addr=None, **kwargs): self.cmd_fd = cmd_fd self.pd_handle = pd_handle self.mr_handle = mr_handle self.mr_addr = mr_addr super(ImportResources, self).__init__(**kwargs) def create_context(self): try: self.ctx = Context(cmd_fd=self.cmd_fd) except u.PyverbsRDMAError as ex: if ex.error_code in [errno.EOPNOTSUPP, errno.EPROTONOSUPPORT]: raise unittest.SkipTest('Importing a device is not supported') raise ex def create_pd(self): self.pd = PD(self.ctx, handle=self.pd_handle) def create_mr(self): self.mr = MR(self.pd, handle=self.mr_handle, address=self.mr_addr) def unimport_resources(self): self.mr.unimport() self.pd.unimport() self.pd.close() return ImportResources class SharedPDTestCase(RDMATestCase): def setUp(self): super().setUp() self.iters = 10 self.server_res = None self.imported_res = [] def tearDown(self): for res in self.imported_res: res.unimport_resources() super().tearDown() def test_imported_rc_ex_rdma_write(self): setup_params = {'dev_name': self.dev_name, 'ib_port': self.ib_port, 'gid_index': self.gid_index} self.server_res = QpExRCRDMAWrite(**setup_params) cmd_fd_dup = os.dup(self.server_res.ctx.cmd_fd) import_cls = get_import_res_class(QpExRCRDMAWrite) server_import = import_cls( cmd_fd_dup, self.server_res.pd.handle, self.server_res.mr.handle, # The imported MR's address is NULL, so using the address of the # "main" MR object to be able to validate the message self.server_res.mr.buf, **setup_params) self.imported_res.append(server_import) client = QpExRCRDMAWrite(**setup_params) client.pre_run(server_import.psns, server_import.qps_num) server_import.pre_run(client.psns, client.qps_num) client.rkey = server_import.mr.rkey server_import.rkey = client.mr.rkey client.raddr = server_import.mr.buf server_import.raddr = client.mr.buf u.rdma_traffic(client, server_import, self.iters, self.gid_index, self.ib_port, send_op=e.IBV_WR_RDMA_WRITE, new_send=True)