xref: /linux/drivers/infiniband/hw/mlx5/qos.c (revision 0ac8903c)
130f2fe40SYishai Hadas // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
230f2fe40SYishai Hadas /*
330f2fe40SYishai Hadas  * Copyright (c) 2020, Mellanox Technologies inc.  All rights reserved.
430f2fe40SYishai Hadas  */
530f2fe40SYishai Hadas 
630f2fe40SYishai Hadas #include <rdma/uverbs_ioctl.h>
730f2fe40SYishai Hadas #include <rdma/mlx5_user_ioctl_cmds.h>
830f2fe40SYishai Hadas #include <rdma/mlx5_user_ioctl_verbs.h>
930f2fe40SYishai Hadas #include <linux/mlx5/driver.h>
1030f2fe40SYishai Hadas #include "mlx5_ib.h"
1130f2fe40SYishai Hadas 
1230f2fe40SYishai Hadas #define UVERBS_MODULE_NAME mlx5_ib
1330f2fe40SYishai Hadas #include <rdma/uverbs_named_ioctl.h>
1430f2fe40SYishai Hadas 
pp_is_supported(struct ib_device * device)1530f2fe40SYishai Hadas static bool pp_is_supported(struct ib_device *device)
1630f2fe40SYishai Hadas {
1730f2fe40SYishai Hadas 	struct mlx5_ib_dev *dev = to_mdev(device);
1830f2fe40SYishai Hadas 
1930f2fe40SYishai Hadas 	return (MLX5_CAP_GEN(dev->mdev, qos) &&
2030f2fe40SYishai Hadas 		MLX5_CAP_QOS(dev->mdev, packet_pacing) &&
2130f2fe40SYishai Hadas 		MLX5_CAP_QOS(dev->mdev, packet_pacing_uid));
2230f2fe40SYishai Hadas }
2330f2fe40SYishai Hadas 
UVERBS_HANDLER(MLX5_IB_METHOD_PP_OBJ_ALLOC)2430f2fe40SYishai Hadas static int UVERBS_HANDLER(MLX5_IB_METHOD_PP_OBJ_ALLOC)(
2530f2fe40SYishai Hadas 	struct uverbs_attr_bundle *attrs)
2630f2fe40SYishai Hadas {
2730f2fe40SYishai Hadas 	u8 rl_raw[MLX5_ST_SZ_BYTES(set_pp_rate_limit_context)] = {};
2830f2fe40SYishai Hadas 	struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs,
2930f2fe40SYishai Hadas 		MLX5_IB_ATTR_PP_OBJ_ALLOC_HANDLE);
3030f2fe40SYishai Hadas 	struct mlx5_ib_dev *dev;
3130f2fe40SYishai Hadas 	struct mlx5_ib_ucontext *c;
3230f2fe40SYishai Hadas 	struct mlx5_ib_pp *pp_entry;
3330f2fe40SYishai Hadas 	void *in_ctx;
3430f2fe40SYishai Hadas 	u16 uid;
3530f2fe40SYishai Hadas 	int inlen;
3630f2fe40SYishai Hadas 	u32 flags;
3730f2fe40SYishai Hadas 	int err;
3830f2fe40SYishai Hadas 
3930f2fe40SYishai Hadas 	c = to_mucontext(ib_uverbs_get_ucontext(attrs));
4030f2fe40SYishai Hadas 	if (IS_ERR(c))
4130f2fe40SYishai Hadas 		return PTR_ERR(c);
4230f2fe40SYishai Hadas 
4330f2fe40SYishai Hadas 	/* The allocated entry can be used only by a DEVX context */
4430f2fe40SYishai Hadas 	if (!c->devx_uid)
4530f2fe40SYishai Hadas 		return -EINVAL;
4630f2fe40SYishai Hadas 
4730f2fe40SYishai Hadas 	dev = to_mdev(c->ibucontext.device);
4830f2fe40SYishai Hadas 	pp_entry = kzalloc(sizeof(*pp_entry), GFP_KERNEL);
49a766fa84SDan Carpenter 	if (!pp_entry)
50a766fa84SDan Carpenter 		return -ENOMEM;
5130f2fe40SYishai Hadas 
5230f2fe40SYishai Hadas 	in_ctx = uverbs_attr_get_alloced_ptr(attrs,
5330f2fe40SYishai Hadas 					     MLX5_IB_ATTR_PP_OBJ_ALLOC_CTX);
5430f2fe40SYishai Hadas 	inlen = uverbs_attr_get_len(attrs,
5530f2fe40SYishai Hadas 				    MLX5_IB_ATTR_PP_OBJ_ALLOC_CTX);
5630f2fe40SYishai Hadas 	memcpy(rl_raw, in_ctx, inlen);
5730f2fe40SYishai Hadas 	err = uverbs_get_flags32(&flags, attrs,
5830f2fe40SYishai Hadas 		MLX5_IB_ATTR_PP_OBJ_ALLOC_FLAGS,
5930f2fe40SYishai Hadas 		MLX5_IB_UAPI_PP_ALLOC_FLAGS_DEDICATED_INDEX);
6030f2fe40SYishai Hadas 	if (err)
6130f2fe40SYishai Hadas 		goto err;
6230f2fe40SYishai Hadas 
6330f2fe40SYishai Hadas 	uid = (flags & MLX5_IB_UAPI_PP_ALLOC_FLAGS_DEDICATED_INDEX) ?
6430f2fe40SYishai Hadas 		c->devx_uid : MLX5_SHARED_RESOURCE_UID;
6530f2fe40SYishai Hadas 
6630f2fe40SYishai Hadas 	err = mlx5_rl_add_rate_raw(dev->mdev, rl_raw, uid,
6730f2fe40SYishai Hadas 			(flags & MLX5_IB_UAPI_PP_ALLOC_FLAGS_DEDICATED_INDEX),
6830f2fe40SYishai Hadas 			&pp_entry->index);
6930f2fe40SYishai Hadas 	if (err)
7030f2fe40SYishai Hadas 		goto err;
7130f2fe40SYishai Hadas 
7230f2fe40SYishai Hadas 	pp_entry->mdev = dev->mdev;
7330f2fe40SYishai Hadas 	uobj->object = pp_entry;
74*0ac8903cSJason Gunthorpe 	uverbs_finalize_uobj_create(attrs, MLX5_IB_ATTR_PP_OBJ_ALLOC_HANDLE);
7530f2fe40SYishai Hadas 
76*0ac8903cSJason Gunthorpe 	err = uverbs_copy_to(attrs, MLX5_IB_ATTR_PP_OBJ_ALLOC_INDEX,
77*0ac8903cSJason Gunthorpe 			     &pp_entry->index, sizeof(pp_entry->index));
78*0ac8903cSJason Gunthorpe 	return err;
79*0ac8903cSJason Gunthorpe 
8030f2fe40SYishai Hadas err:
8130f2fe40SYishai Hadas 	kfree(pp_entry);
8230f2fe40SYishai Hadas 	return err;
8330f2fe40SYishai Hadas }
8430f2fe40SYishai Hadas 
pp_obj_cleanup(struct ib_uobject * uobject,enum rdma_remove_reason why,struct uverbs_attr_bundle * attrs)8530f2fe40SYishai Hadas static int pp_obj_cleanup(struct ib_uobject *uobject,
8630f2fe40SYishai Hadas 			  enum rdma_remove_reason why,
8730f2fe40SYishai Hadas 			  struct uverbs_attr_bundle *attrs)
8830f2fe40SYishai Hadas {
8930f2fe40SYishai Hadas 	struct mlx5_ib_pp *pp_entry = uobject->object;
9030f2fe40SYishai Hadas 
9130f2fe40SYishai Hadas 	mlx5_rl_remove_rate_raw(pp_entry->mdev, pp_entry->index);
9230f2fe40SYishai Hadas 	kfree(pp_entry);
9330f2fe40SYishai Hadas 	return 0;
9430f2fe40SYishai Hadas }
9530f2fe40SYishai Hadas 
9630f2fe40SYishai Hadas DECLARE_UVERBS_NAMED_METHOD(
9730f2fe40SYishai Hadas 	MLX5_IB_METHOD_PP_OBJ_ALLOC,
9830f2fe40SYishai Hadas 	UVERBS_ATTR_IDR(MLX5_IB_ATTR_PP_OBJ_ALLOC_HANDLE,
9930f2fe40SYishai Hadas 			MLX5_IB_OBJECT_PP,
10030f2fe40SYishai Hadas 			UVERBS_ACCESS_NEW,
10130f2fe40SYishai Hadas 			UA_MANDATORY),
10230f2fe40SYishai Hadas 	UVERBS_ATTR_PTR_IN(
10330f2fe40SYishai Hadas 		MLX5_IB_ATTR_PP_OBJ_ALLOC_CTX,
10430f2fe40SYishai Hadas 		UVERBS_ATTR_SIZE(1,
10530f2fe40SYishai Hadas 			MLX5_ST_SZ_BYTES(set_pp_rate_limit_context)),
10630f2fe40SYishai Hadas 		UA_MANDATORY,
10730f2fe40SYishai Hadas 		UA_ALLOC_AND_COPY),
10830f2fe40SYishai Hadas 	UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_PP_OBJ_ALLOC_FLAGS,
10930f2fe40SYishai Hadas 			enum mlx5_ib_uapi_pp_alloc_flags,
11030f2fe40SYishai Hadas 			UA_MANDATORY),
11130f2fe40SYishai Hadas 	UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_PP_OBJ_ALLOC_INDEX,
11230f2fe40SYishai Hadas 			   UVERBS_ATTR_TYPE(u16),
11330f2fe40SYishai Hadas 			   UA_MANDATORY));
11430f2fe40SYishai Hadas 
11530f2fe40SYishai Hadas DECLARE_UVERBS_NAMED_METHOD_DESTROY(
11630f2fe40SYishai Hadas 	MLX5_IB_METHOD_PP_OBJ_DESTROY,
11730f2fe40SYishai Hadas 	UVERBS_ATTR_IDR(MLX5_IB_ATTR_PP_OBJ_DESTROY_HANDLE,
11830f2fe40SYishai Hadas 			MLX5_IB_OBJECT_PP,
11930f2fe40SYishai Hadas 			UVERBS_ACCESS_DESTROY,
12030f2fe40SYishai Hadas 			UA_MANDATORY));
12130f2fe40SYishai Hadas 
12230f2fe40SYishai Hadas DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_PP,
12330f2fe40SYishai Hadas 			    UVERBS_TYPE_ALLOC_IDR(pp_obj_cleanup),
12430f2fe40SYishai Hadas 			    &UVERBS_METHOD(MLX5_IB_METHOD_PP_OBJ_ALLOC),
12530f2fe40SYishai Hadas 			    &UVERBS_METHOD(MLX5_IB_METHOD_PP_OBJ_DESTROY));
12630f2fe40SYishai Hadas 
12730f2fe40SYishai Hadas 
12830f2fe40SYishai Hadas const struct uapi_definition mlx5_ib_qos_defs[] = {
12930f2fe40SYishai Hadas 	UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
13030f2fe40SYishai Hadas 		MLX5_IB_OBJECT_PP,
13130f2fe40SYishai Hadas 		UAPI_DEF_IS_OBJ_SUPPORTED(pp_is_supported)),
13230f2fe40SYishai Hadas 	{},
13330f2fe40SYishai Hadas };
134