def test_sched_per_qp_traffic(self): """ Tests attaching a QP to a sched leaf. The test creates a sched tree consisting of a root node and a leaf with max BW and share BW, modifies two RC QPs to be attached to the sched leaf and then run traffic using those QPs. """ self.create_players(RCResources) try: root_node = Mlx5dvSchedNode(self.server.ctx, Mlx5dvSchedAttr()) mixed_flags = dve.MLX5DV_SCHED_ELEM_ATTR_FLAGS_MAX_AVG_BW | \ dve.MLX5DV_SCHED_ELEM_ATTR_FLAGS_BW_SHARE mixed_sched_attr = Mlx5dvSchedAttr(root_node, max_avg_bw=10, bw_share=2, flags=mixed_flags) leaf = Mlx5dvSchedLeaf(self.server.ctx, mixed_sched_attr) Mlx5QP.modify_qp_sched_elem(self.server.qp, req_sched_leaf=leaf, resp_sched_leaf=leaf) except PyverbsRDMAError as ex: if ex.error_code == errno.EOPNOTSUPP: raise unittest.SkipTest( 'Creation or usage of schedule elements is not supported') raise ex u.traffic(**self.traffic_args)
def create_qps(self): # Create the DCI QPs. qp_init_attr = self.create_qp_init_attr(self.send_ops_flags) try: for _ in range(self.qp_count): comp_mask = dve.MLX5DV_QP_INIT_ATTR_MASK_DC if self.create_flags: comp_mask |= dve.MLX5DV_QP_INIT_ATTR_MASK_QP_CREATE_FLAGS attr = Mlx5DVQPInitAttr(comp_mask=comp_mask, create_flags=self.create_flags, dc_init_attr=Mlx5DVDCInitAttr()) qp = Mlx5QP(self.ctx, qp_init_attr, attr) self.qps.append(qp) self.qps_num.append(qp.qp_num) self.psns.append(random.getrandbits(24)) # Create the DCT QP. qp_init_attr = self.create_qp_init_attr() dc_attr = Mlx5DVDCInitAttr(dc_type=dve.MLX5DV_DCTYPE_DCT, dct_access_key=DCT_KEY) attr = Mlx5DVQPInitAttr(comp_mask=dve.MLX5DV_QP_INIT_ATTR_MASK_DC, dc_init_attr=dc_attr) self.dct_qp = Mlx5QP(self.ctx, qp_init_attr, attr) except PyverbsRDMAError as ex: if ex.error_code == errno.EOPNOTSUPP: raise unittest.SkipTest(f'Create DC QP is not supported') raise ex
def create_qp(self, conn_idx=0): """ Create an RDMACM QP. If self.with_ext_qp is set, then an external CQ and DC QP will be created. In case that CQ is already created, it is used for the newly created QP. """ try: if not self.passive: # Create the DCI QPs. cmid = self.cmids[conn_idx] self.create_cq(cmid) qp_init_attr = self.create_qp_init_attr( cmid, e.IBV_QP_EX_WITH_SEND) attr = Mlx5DVQPInitAttr( comp_mask=dve.MLX5DV_QP_INIT_ATTR_MASK_DC, dc_init_attr=Mlx5DVDCInitAttr()) self.qps[conn_idx] = Mlx5QP(cmid.context, qp_init_attr, attr) if self.passive and conn_idx == 0: # Create the DCT QP only for the first connection. cmid = self.child_id self.create_cq(cmid) self.create_srq(cmid) qp_init_attr = self.create_qp_init_attr(cmid) dc_attr = Mlx5DVDCInitAttr(dc_type=dve.MLX5DV_DCTYPE_DCT, dct_access_key=DCT_KEY) attr = Mlx5DVQPInitAttr( comp_mask=dve.MLX5DV_QP_INIT_ATTR_MASK_DC, dc_init_attr=dc_attr) self.qps[conn_idx] = Mlx5QP(cmid.context, qp_init_attr, attr) except PyverbsRDMAError as ex: if ex.error_code == errno.EOPNOTSUPP: raise unittest.SkipTest('Create DC QP is not supported') raise ex
def dci_reset_stream_id(self, qp_idx): stream_id = self.get_stream_id(qp_idx) Mlx5QP.modify_dci_stream_channel_id(self.qps[qp_idx], stream_id) # Check once if error raised when reset wrong stream id if self.stream_check: try: Mlx5QP.modify_dci_stream_channel_id(self.qps[qp_idx], stream_id + 1) except PyverbsRDMAError as ex: self.stream_check = False
def modify_lag(self, resources): try: port_num, active_port_num = Mlx5QP.query_lag_port(resources.qp) # if port_num is 1 - modify to 2, else modify to 1 new_port_num = (2 - port_num) + 1 Mlx5QP.modify_lag_port(resources.qp, new_port_num) port_num, active_port_num = Mlx5QP.query_lag_port(resources.qp) self.assertEqual(port_num, new_port_num, 'Port num is not as expected') except PyverbsRDMAError as ex: if ex.error_code == errno.EOPNOTSUPP: raise unittest.SkipTest('Set LAG affinity is not supported on this device') raise ex
def reset_qp(self, qp_idx): qp_attr = QPAttr(qp_state=e.IBV_QPS_RESET) self.qps[qp_idx].modify(qp_attr, e.IBV_QP_STATE) self.qps[qp_idx].to_rts(qp_attr) err_mask = self.qp_stream_errors[qp_idx][0] index = 0 # Clear all set dci while err_mask != 0: if (err_mask & 0x1) == 0x1: Mlx5QP.modify_dci_stream_channel_id(self.qps[qp_idx], index) index += 1 err_mask >>= 1 self.qp_stream_errors[qp_idx][0] = 0
def create_qps(self): # Create the DCI QPs. qp_init_attr = self.create_qp_init_attr(self.send_ops_flags) self.dcis = {} # This array contains current stream id self.current_qp_stream_id = {} # This array counts different errors in bad_flow self.qp_stream_errors = [] comp_mask = dve.MLX5DV_QP_INIT_ATTR_MASK_DC | \ dve.MLX5DV_QP_INIT_ATTR_MASK_DCI_STREAMS try: for qpn in range(self.qp_count): if self.create_flags: comp_mask |= dve.MLX5DV_QP_INIT_ATTR_MASK_QP_CREATE_FLAGS self.generate_dci_attr(qpn) stream_ctx = Mlx5DCIStreamInitAttr(self.log_dci_streams, self.log_dci_errored) self.dcis[qpn] = { 'stream': 1 << self.log_dci_streams, 'errored': 1 << self.log_dci_errored } attr = Mlx5DVQPInitAttr( comp_mask=comp_mask, create_flags=self.create_flags, dc_init_attr=Mlx5DVDCInitAttr(dci_streams=stream_ctx)) qp = Mlx5QP(self.ctx, qp_init_attr, attr) self.qps.append(qp) # Different values for start point of stream id per qp self.current_qp_stream_id[qpn] = qpn # Array of errors for bad_flow # For DCI_TEST_BAD_FLOW_WITH_RESET # First element - number of injected bad flows # Second element - number of exceptions from bad flows # For DCI_TEST_BAD_FLOW_WITHOUT_RESET # First element - bitmap of bad flow streams # Second element - number of exceptions from bad flows # Third element - flag if reset of qp been executed self.qp_stream_errors.append([0, 0, False]) self.qps_num.append(qp.qp_num) self.psns.append(random.getrandbits(24)) # Create the DCT QP. qp_init_attr = self.create_qp_init_attr() dc_attr = Mlx5DVDCInitAttr(dc_type=dve.MLX5DV_DCTYPE_DCT, dct_access_key=DCT_KEY) attr = Mlx5DVQPInitAttr(comp_mask=dve.MLX5DV_QP_INIT_ATTR_MASK_DC, dc_init_attr=dc_attr) self.dct_qp = Mlx5QP(self.ctx, qp_init_attr, attr) except PyverbsRDMAError as ex: if ex.error_code in [errno.EOPNOTSUPP, errno.EPROTONOSUPPORT]: raise unittest.SkipTest('Create DC QP is not supported') raise ex
def test_dc_ah_to_qp_mapping(self): self.create_players(Mlx5DcResources, qp_count=2, send_ops_flags=e.IBV_QP_EX_WITH_SEND) client_ah = u.get_global_ah(self.client, self.gid_index, self.ib_port) try: Mlx5QP.map_ah_to_qp(client_ah, self.server.qps[0].qp_num) except PyverbsRDMAError as ex: if ex.error_code == errno.EOPNOTSUPP: raise unittest.SkipTest('Mapping AH to QP is not supported') raise ex u.traffic(**self.traffic_args, new_send=True, send_op=e.IBV_QP_EX_WITH_SEND)
def test_rc_modify_udp_sport(self): """ Create RC resources and change the server QP's UDP source port to an arbitrary legal value (55555). Then run SEND traffic. :return: None """ self.create_players(RCResources) try: Mlx5QP.modify_udp_sport(self.server.qp, udp_sport=55555) except PyverbsRDMAError as ex: if ex.error_code == errno.EOPNOTSUPP: raise unittest.SkipTest( 'Modifying a QP UDP sport is not supported') raise ex u.traffic(self.client, self.server, self.iters, self.gid_index, self.ib_port)
def create_qps(self): try: qp_init_attr = self.create_qp_init_attr() comp_mask = dve.MLX5DV_QP_INIT_ATTR_MASK_SEND_OPS_FLAGS attr = Mlx5DVQPInitAttr(comp_mask=comp_mask, send_ops_flags=self.dv_send_ops_flags) qp = Mlx5QP(self.ctx, qp_init_attr, attr) self.qps.append(qp) self.qps_num.append(qp.qp_num) self.psns.append(0) except PyverbsRDMAError as ex: if ex.error_code == errno.EOPNOTSUPP: raise unittest.SkipTest('Create Mlx5DV QP is not supported') raise ex