Commit 4f5d1bea authored by Saeed Mahameed's avatar Saeed Mahameed
Browse files


Misc updates from mlx5-next branch:

1) E-Switch vport metadata support for source vport matching
2) Convert mkey_table to XArray
3) Shared IRQs and to use single IRQ for all async EQs

Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parents 5cdda5f1 92ab1eb3
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -522,8 +522,8 @@ repoll:
	case MLX5_CQE_SIG_ERR:
		sig_err_cqe = (struct mlx5_sig_err_cqe *)cqe64;

		read_lock(&dev->mdev->priv.mkey_table.lock);
		mmkey = __mlx5_mr_lookup(dev->mdev,
		xa_lock(&dev->mdev->priv.mkey_table);
		mmkey = xa_load(&dev->mdev->priv.mkey_table,
				mlx5_base_mkey(be32_to_cpu(sig_err_cqe->mkey)));
		mr = to_mibmr(mmkey);
		get_sig_err_item(sig_err_cqe, &mr->sig->err_item);
@@ -537,7 +537,7 @@ repoll:
			     mr->sig->err_item.expected,
			     mr->sig->err_item.actual);

		read_unlock(&dev->mdev->priv.mkey_table.lock);
		xa_unlock(&dev->mdev->priv.mkey_table);
		goto repoll;
	}

+4 −14
Original line number Diff line number Diff line
@@ -1043,13 +1043,10 @@ static int devx_handle_mkey_indirect(struct devx_obj *obj,
				     struct mlx5_ib_dev *dev,
				     void *in, void *out)
{
	struct mlx5_mkey_table *table = &dev->mdev->priv.mkey_table;
	struct mlx5_ib_devx_mr *devx_mr = &obj->devx_mr;
	unsigned long flags;
	struct mlx5_core_mkey *mkey;
	void *mkc;
	u8 key;
	int err;

	mkey = &devx_mr->mmkey;
	mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
@@ -1062,11 +1059,8 @@ static int devx_handle_mkey_indirect(struct devx_obj *obj,
	mkey->pd = MLX5_GET(mkc, mkc, pd);
	devx_mr->ndescs = MLX5_GET(mkc, mkc, translations_octword_size);

	write_lock_irqsave(&table->lock, flags);
	err = radix_tree_insert(&table->tree, mlx5_base_mkey(mkey->key),
				mkey);
	write_unlock_irqrestore(&table->lock, flags);
	return err;
	return xa_err(xa_store(&dev->mdev->priv.mkey_table,
			       mlx5_base_mkey(mkey->key), mkey, GFP_KERNEL));
}

static int devx_handle_mkey_create(struct mlx5_ib_dev *dev,
@@ -1117,12 +1111,8 @@ static void devx_free_indirect_mkey(struct rcu_head *rcu)
 */
static void devx_cleanup_mkey(struct devx_obj *obj)
{
	struct mlx5_mkey_table *table = &obj->mdev->priv.mkey_table;
	unsigned long flags;

	write_lock_irqsave(&table->lock, flags);
	radix_tree_delete(&table->tree, mlx5_base_mkey(obj->devx_mr.mmkey.key));
	write_unlock_irqrestore(&table->lock, flags);
	xa_erase(&obj->mdev->priv.mkey_table,
		 mlx5_base_mkey(obj->devx_mr.mmkey.key));
}

static int devx_obj_cleanup(struct ib_uobject *uobject,
+8 −5
Original line number Diff line number Diff line
@@ -65,11 +65,12 @@ static const struct uverbs_attr_spec mlx5_ib_flow_type[] = {
static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
	struct uverbs_attr_bundle *attrs)
{
	struct mlx5_flow_act flow_act = {.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG};
	struct mlx5_flow_context flow_context = {.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG};
	struct mlx5_ib_flow_handler *flow_handler;
	struct mlx5_ib_flow_matcher *fs_matcher;
	struct ib_uobject **arr_flow_actions;
	struct ib_uflow_resources *uflow_res;
	struct mlx5_flow_act flow_act = {};
	void *devx_obj;
	int dest_id, dest_type;
	void *cmd_in;
@@ -172,17 +173,19 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
				   arr_flow_actions[i]->object);
	}

	ret = uverbs_copy_from(&flow_act.flow_tag, attrs,
	ret = uverbs_copy_from(&flow_context.flow_tag, attrs,
			       MLX5_IB_ATTR_CREATE_FLOW_TAG);
	if (!ret) {
		if (flow_act.flow_tag >= BIT(24)) {
		if (flow_context.flow_tag >= BIT(24)) {
			ret = -EINVAL;
			goto err_out;
		}
		flow_act.flags |= FLOW_ACT_HAS_TAG;
		flow_context.flags |= FLOW_CONTEXT_HAS_TAG;
	}

	flow_handler = mlx5_ib_raw_fs_rule_add(dev, fs_matcher, &flow_act,
	flow_handler = mlx5_ib_raw_fs_rule_add(dev, fs_matcher,
					       &flow_context,
					       &flow_act,
					       counter_id,
					       cmd_in, inlen,
					       dest_id, dest_type);
+55 −20
Original line number Diff line number Diff line
@@ -2666,11 +2666,15 @@ int parse_flow_flow_action(struct mlx5_ib_flow_action *maction,
	}
}

static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c,
			   u32 *match_v, const union ib_flow_spec *ib_spec,
static int parse_flow_attr(struct mlx5_core_dev *mdev,
			   struct mlx5_flow_spec *spec,
			   const union ib_flow_spec *ib_spec,
			   const struct ib_flow_attr *flow_attr,
			   struct mlx5_flow_act *action, u32 prev_type)
{
	struct mlx5_flow_context *flow_context = &spec->flow_context;
	u32 *match_c = spec->match_criteria;
	u32 *match_v = spec->match_value;
	void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c,
					   misc_parameters);
	void *misc_params_v = MLX5_ADDR_OF(fte_match_param, match_v,
@@ -2989,8 +2993,8 @@ static int parse_flow_attr(struct mlx5_core_dev *mdev, u32 *match_c,
		if (ib_spec->flow_tag.tag_id >= BIT(24))
			return -EINVAL;

		action->flow_tag = ib_spec->flow_tag.tag_id;
		action->flags |= FLOW_ACT_HAS_TAG;
		flow_context->flow_tag = ib_spec->flow_tag.tag_id;
		flow_context->flags |= FLOW_CONTEXT_HAS_TAG;
		break;
	case IB_FLOW_SPEC_ACTION_DROP:
		if (FIELDS_NOT_SUPPORTED(ib_spec->drop,
@@ -3084,7 +3088,8 @@ is_valid_esp_aes_gcm(struct mlx5_core_dev *mdev,
		return VALID_SPEC_NA;

	return is_crypto && is_ipsec &&
		(!egress || (!is_drop && !(flow_act->flags & FLOW_ACT_HAS_TAG))) ?
		(!egress || (!is_drop &&
			     !(spec->flow_context.flags & FLOW_CONTEXT_HAS_TAG))) ?
		VALID_SPEC_VALID : VALID_SPEC_INVALID;
}

@@ -3464,6 +3469,37 @@ free:
	return ret;
}

static void mlx5_ib_set_rule_source_port(struct mlx5_ib_dev *dev,
					 struct mlx5_flow_spec *spec,
					 struct mlx5_eswitch_rep *rep)
{
	struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
	void *misc;

	if (mlx5_eswitch_vport_match_metadata_enabled(esw)) {
		misc = MLX5_ADDR_OF(fte_match_param, spec->match_value,
				    misc_parameters_2);

		MLX5_SET(fte_match_set_misc2, misc, metadata_reg_c_0,
			 mlx5_eswitch_get_vport_metadata_for_match(esw,
								   rep->vport));
		misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
				    misc_parameters_2);

		MLX5_SET_TO_ONES(fte_match_set_misc2, misc, metadata_reg_c_0);
	} else {
		misc = MLX5_ADDR_OF(fte_match_param, spec->match_value,
				    misc_parameters);

		MLX5_SET(fte_match_set_misc, misc, source_port, rep->vport);

		misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
				    misc_parameters);

		MLX5_SET_TO_ONES(fte_match_set_misc, misc, source_port);
	}
}

static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
						      struct mlx5_ib_flow_prio *ft_prio,
						      const struct ib_flow_attr *flow_attr,
@@ -3473,7 +3509,7 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
{
	struct mlx5_flow_table	*ft = ft_prio->flow_table;
	struct mlx5_ib_flow_handler *handler;
	struct mlx5_flow_act flow_act = {.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG};
	struct mlx5_flow_act flow_act = {};
	struct mlx5_flow_spec *spec;
	struct mlx5_flow_destination dest_arr[2] = {};
	struct mlx5_flow_destination *rule_dst = dest_arr;
@@ -3504,8 +3540,7 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
	}

	for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) {
		err = parse_flow_attr(dev->mdev, spec->match_criteria,
				      spec->match_value,
		err = parse_flow_attr(dev->mdev, spec,
				      ib_flow, flow_attr, &flow_act,
				      prev_type);
		if (err < 0)
@@ -3519,19 +3554,15 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
		set_underlay_qp(dev, spec, underlay_qpn);

	if (dev->is_rep) {
		void *misc;
		struct mlx5_eswitch_rep *rep;

		if (!dev->port[flow_attr->port - 1].rep) {
		rep = dev->port[flow_attr->port - 1].rep;
		if (!rep) {
			err = -EINVAL;
			goto free;
		}
		misc = MLX5_ADDR_OF(fte_match_param, spec->match_value,
				    misc_parameters);
		MLX5_SET(fte_match_set_misc, misc, source_port,
			 dev->port[flow_attr->port - 1].rep->vport);
		misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
				    misc_parameters);
		MLX5_SET_TO_ONES(fte_match_set_misc, misc, source_port);

		mlx5_ib_set_rule_source_port(dev, spec, rep);
	}

	spec->match_criteria_enable = get_match_criteria_enable(spec->match_criteria);
@@ -3572,11 +3603,11 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
					MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
	}

	if ((flow_act.flags & FLOW_ACT_HAS_TAG)  &&
	if ((spec->flow_context.flags & FLOW_CONTEXT_HAS_TAG)  &&
	    (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
	     flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT)) {
		mlx5_ib_warn(dev, "Flow tag %u and attribute type %x isn't allowed in leftovers\n",
			     flow_act.flow_tag, flow_attr->type);
			     spec->flow_context.flow_tag, flow_attr->type);
		err = -EINVAL;
		goto free;
	}
@@ -3947,6 +3978,7 @@ _create_raw_flow_rule(struct mlx5_ib_dev *dev,
		      struct mlx5_ib_flow_prio *ft_prio,
		      struct mlx5_flow_destination *dst,
		      struct mlx5_ib_flow_matcher  *fs_matcher,
		      struct mlx5_flow_context *flow_context,
		      struct mlx5_flow_act *flow_act,
		      void *cmd_in, int inlen,
		      int dst_num)
@@ -3969,6 +4001,7 @@ _create_raw_flow_rule(struct mlx5_ib_dev *dev,
	memcpy(spec->match_criteria, fs_matcher->matcher_mask.match_params,
	       fs_matcher->mask_len);
	spec->match_criteria_enable = fs_matcher->match_criteria_enable;
	spec->flow_context = *flow_context;

	handler->rule = mlx5_add_flow_rules(ft, spec,
					    flow_act, dst, dst_num);
@@ -4033,6 +4066,7 @@ static bool raw_fs_is_multicast(struct mlx5_ib_flow_matcher *fs_matcher,
struct mlx5_ib_flow_handler *
mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
			struct mlx5_ib_flow_matcher *fs_matcher,
			struct mlx5_flow_context *flow_context,
			struct mlx5_flow_act *flow_act,
			u32 counter_id,
			void *cmd_in, int inlen, int dest_id,
@@ -4085,7 +4119,8 @@ mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
		dst_num++;
	}

	handler = _create_raw_flow_rule(dev, ft_prio, dst, fs_matcher, flow_act,
	handler = _create_raw_flow_rule(dev, ft_prio, dst, fs_matcher,
					flow_context, flow_act,
					cmd_in, inlen, dst_num);

	if (IS_ERR(handler)) {
+2 −0
Original line number Diff line number Diff line
@@ -920,6 +920,7 @@ struct mlx5_ib_lb_state {
};

struct mlx5_ib_pf_eq {
	struct notifier_block irq_nb;
	struct mlx5_ib_dev *dev;
	struct mlx5_eq *core;
	struct work_struct work;
@@ -1316,6 +1317,7 @@ extern const struct uapi_definition mlx5_ib_devx_defs[];
extern const struct uapi_definition mlx5_ib_flow_defs[];
struct mlx5_ib_flow_handler *mlx5_ib_raw_fs_rule_add(
	struct mlx5_ib_dev *dev, struct mlx5_ib_flow_matcher *fs_matcher,
	struct mlx5_flow_context *flow_context,
	struct mlx5_flow_act *flow_act, u32 counter_id,
	void *cmd_in, int inlen, int dest_id, int dest_type);
bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type);
Loading