Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 400b1ebc authored by Guy Levi's avatar Guy Levi Committed by Doug Ledford
Browse files

IB/mlx4: Add support for WQ related verbs



Support create/modify/destroy WQ related verbs.

The base IB object to enable RSS functionality is a WQ (i.e. ib_wq).
This patch implements the related WQ verbs as of create, modify and
destroy.

In downstream patches the WQ will be used as part of an indirection
table (i.e. ib_rwq_ind_table) to enable RSS QP creation.

Notes:
ConnectX-3 hardware requires consecutive WQNs list as receive descriptor
queues for the RSS QP. Hence, the driver manages consecutive ranges lists
per context which the user must respect.
Destroying the WQ does not return its WQN back to its range for
reusing. However, destroying all WQs from the same range releases the
range and in turn releases its WQNs for reusing.

Since the WQ object is not a natural object in the hardware, the driver
implements the WQ by the hardware QP.

As such, the WQ inherits its port from its RSS QP parent upon its
RST->INIT transition and by that time its state is applied to the
hardware.

Signed-off-by: default avatarGuy Levi <guyle@mellanox.com>
Reviewed-by: default avatarYishai Hadas <yishaih@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent f3301870
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -81,6 +81,8 @@ static const char mlx4_ib_version[] =
	DRV_VERSION "\n";

static void do_slave_init(struct mlx4_ib_dev *ibdev, int slave, int do_init);
static enum rdma_link_layer mlx4_ib_port_link_layer(struct ib_device *device,
						    u8 port_num);

static struct workqueue_struct *wq;

@@ -552,6 +554,11 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
	props->timestamp_mask = 0xFFFFFFFFFFFFULL;
	props->max_ah = INT_MAX;

	if ((dev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS) &&
	    (mlx4_ib_port_link_layer(ibdev, 1) == IB_LINK_LAYER_ETHERNET ||
	     mlx4_ib_port_link_layer(ibdev, 2) == IB_LINK_LAYER_ETHERNET))
		props->max_wq_type_rq = props->max_qp;

	if (!mlx4_is_slave(dev->dev))
		err = mlx4_get_internal_clock_params(dev->dev, &clock_params);

@@ -1076,6 +1083,9 @@ static struct ib_ucontext *mlx4_ib_alloc_ucontext(struct ib_device *ibdev,
	INIT_LIST_HEAD(&context->db_page_list);
	mutex_init(&context->db_page_mutex);

	INIT_LIST_HEAD(&context->wqn_ranges_list);
	mutex_init(&context->wqn_ranges_mutex);

	if (ibdev->uverbs_abi_ver == MLX4_IB_UVERBS_NO_DEV_CAPS_ABI_VERSION)
		err = ib_copy_to_udata(udata, &resp_v3, sizeof(resp_v3));
	else
@@ -2720,6 +2730,20 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
	ibdev->ib_dev.get_dev_fw_str    = get_fw_ver_str;
	ibdev->ib_dev.disassociate_ucontext = mlx4_ib_disassociate_ucontext;

	if ((dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_RSS) &&
	    ((mlx4_ib_port_link_layer(&ibdev->ib_dev, 1) ==
	    IB_LINK_LAYER_ETHERNET) ||
	    (mlx4_ib_port_link_layer(&ibdev->ib_dev, 2) ==
	    IB_LINK_LAYER_ETHERNET))) {
		ibdev->ib_dev.create_wq		= mlx4_ib_create_wq;
		ibdev->ib_dev.modify_wq		= mlx4_ib_modify_wq;
		ibdev->ib_dev.destroy_wq	= mlx4_ib_destroy_wq;
		ibdev->ib_dev.uverbs_ex_cmd_mask |=
			(1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
			(1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
			(1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ);
	}

	if (!mlx4_is_slave(ibdev->dev)) {
		ibdev->ib_dev.alloc_fmr		= mlx4_ib_fmr_alloc;
		ibdev->ib_dev.map_phys_fmr	= mlx4_ib_map_phys_fmr;
+24 −1
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@ struct mlx4_ib_ucontext {
	struct list_head	db_page_list;
	struct mutex		db_page_mutex;
	struct mlx4_ib_vma_private_data hw_bar_info[HW_BAR_COUNT];
	struct list_head	wqn_ranges_list;
	struct mutex		wqn_ranges_mutex; /* protect wqn_ranges_list */
};

struct mlx4_ib_pd {
@@ -289,8 +291,19 @@ struct mlx4_roce_smac_vlan_info {
	int update_vid;
};

struct mlx4_wqn_range {
	int			base_wqn;
	int			size;
	int			refcount;
	bool			dirty;
	struct list_head	list;
};

struct mlx4_ib_qp {
	union {
		struct ib_qp	ibqp;
		struct ib_wq	ibwq;
	};
	struct mlx4_qp		mqp;
	struct mlx4_buf		buf;

@@ -329,6 +342,9 @@ struct mlx4_ib_qp {
	struct list_head	cq_recv_list;
	struct list_head	cq_send_list;
	struct counter_index	*counter_index;
	struct mlx4_wqn_range	*wqn_range;
	/* Number of RSS QP parents that uses this WQ */
	u32			rss_usecnt;
};

struct mlx4_ib_srq {
@@ -893,4 +909,11 @@ void mlx4_sched_ib_sl2vl_update_work(struct mlx4_ib_dev *ibdev,

void mlx4_ib_sl2vl_update(struct mlx4_ib_dev *mdev, int port);

struct ib_wq *mlx4_ib_create_wq(struct ib_pd *pd,
				struct ib_wq_init_attr *init_attr,
				struct ib_udata *udata);
int mlx4_ib_destroy_wq(struct ib_wq *wq);
int mlx4_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr,
		      u32 wq_attr_mask, struct ib_udata *udata);

#endif /* MLX4_IB_H */
+449 −56

File changed.

Preview size limit exceeded, changes collapsed.

+14 −0
Original line number Diff line number Diff line
@@ -105,4 +105,18 @@ struct mlx4_ib_create_qp {
	__u8	reserved;
};

struct mlx4_ib_create_wq {
	__u64	buf_addr;
	__u64	db_addr;
	__u8	log_range_size;
	__u8	reserved[3];
	__u32   comp_mask;
	__u32   reserved1;
};

struct mlx4_ib_modify_wq {
	__u32	comp_mask;
	__u32	reserved;
};

#endif /* MLX4_ABI_USER_H */