linux/drivers/infiniband/hw/mlx5/qos.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
   2/*
   3 * Copyright (c) 2020, Mellanox Technologies inc.  All rights reserved.
   4 */
   5
   6#include <rdma/uverbs_ioctl.h>
   7#include <rdma/mlx5_user_ioctl_cmds.h>
   8#include <rdma/mlx5_user_ioctl_verbs.h>
   9#include <linux/mlx5/driver.h>
  10#include "mlx5_ib.h"
  11
  12#define UVERBS_MODULE_NAME mlx5_ib
  13#include <rdma/uverbs_named_ioctl.h>
  14
  15static bool pp_is_supported(struct ib_device *device)
  16{
  17        struct mlx5_ib_dev *dev = to_mdev(device);
  18
  19        return (MLX5_CAP_GEN(dev->mdev, qos) &&
  20                MLX5_CAP_QOS(dev->mdev, packet_pacing) &&
  21                MLX5_CAP_QOS(dev->mdev, packet_pacing_uid));
  22}
  23
  24static int UVERBS_HANDLER(MLX5_IB_METHOD_PP_OBJ_ALLOC)(
  25        struct uverbs_attr_bundle *attrs)
  26{
  27        u8 rl_raw[MLX5_ST_SZ_BYTES(set_pp_rate_limit_context)] = {};
  28        struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs,
  29                MLX5_IB_ATTR_PP_OBJ_ALLOC_HANDLE);
  30        struct mlx5_ib_dev *dev;
  31        struct mlx5_ib_ucontext *c;
  32        struct mlx5_ib_pp *pp_entry;
  33        void *in_ctx;
  34        u16 uid;
  35        int inlen;
  36        u32 flags;
  37        int err;
  38
  39        c = to_mucontext(ib_uverbs_get_ucontext(attrs));
  40        if (IS_ERR(c))
  41                return PTR_ERR(c);
  42
  43        /* The allocated entry can be used only by a DEVX context */
  44        if (!c->devx_uid)
  45                return -EINVAL;
  46
  47        dev = to_mdev(c->ibucontext.device);
  48        pp_entry = kzalloc(sizeof(*pp_entry), GFP_KERNEL);
  49        if (!pp_entry)
  50                return -ENOMEM;
  51
  52        in_ctx = uverbs_attr_get_alloced_ptr(attrs,
  53                                             MLX5_IB_ATTR_PP_OBJ_ALLOC_CTX);
  54        inlen = uverbs_attr_get_len(attrs,
  55                                    MLX5_IB_ATTR_PP_OBJ_ALLOC_CTX);
  56        memcpy(rl_raw, in_ctx, inlen);
  57        err = uverbs_get_flags32(&flags, attrs,
  58                MLX5_IB_ATTR_PP_OBJ_ALLOC_FLAGS,
  59                MLX5_IB_UAPI_PP_ALLOC_FLAGS_DEDICATED_INDEX);
  60        if (err)
  61                goto err;
  62
  63        uid = (flags & MLX5_IB_UAPI_PP_ALLOC_FLAGS_DEDICATED_INDEX) ?
  64                c->devx_uid : MLX5_SHARED_RESOURCE_UID;
  65
  66        err = mlx5_rl_add_rate_raw(dev->mdev, rl_raw, uid,
  67                        (flags & MLX5_IB_UAPI_PP_ALLOC_FLAGS_DEDICATED_INDEX),
  68                        &pp_entry->index);
  69        if (err)
  70                goto err;
  71
  72        pp_entry->mdev = dev->mdev;
  73        uobj->object = pp_entry;
  74        uverbs_finalize_uobj_create(attrs, MLX5_IB_ATTR_PP_OBJ_ALLOC_HANDLE);
  75
  76        err = uverbs_copy_to(attrs, MLX5_IB_ATTR_PP_OBJ_ALLOC_INDEX,
  77                             &pp_entry->index, sizeof(pp_entry->index));
  78        return err;
  79
  80err:
  81        kfree(pp_entry);
  82        return err;
  83}
  84
  85static int pp_obj_cleanup(struct ib_uobject *uobject,
  86                          enum rdma_remove_reason why,
  87                          struct uverbs_attr_bundle *attrs)
  88{
  89        struct mlx5_ib_pp *pp_entry = uobject->object;
  90
  91        mlx5_rl_remove_rate_raw(pp_entry->mdev, pp_entry->index);
  92        kfree(pp_entry);
  93        return 0;
  94}
  95
  96DECLARE_UVERBS_NAMED_METHOD(
  97        MLX5_IB_METHOD_PP_OBJ_ALLOC,
  98        UVERBS_ATTR_IDR(MLX5_IB_ATTR_PP_OBJ_ALLOC_HANDLE,
  99                        MLX5_IB_OBJECT_PP,
 100                        UVERBS_ACCESS_NEW,
 101                        UA_MANDATORY),
 102        UVERBS_ATTR_PTR_IN(
 103                MLX5_IB_ATTR_PP_OBJ_ALLOC_CTX,
 104                UVERBS_ATTR_SIZE(1,
 105                        MLX5_ST_SZ_BYTES(set_pp_rate_limit_context)),
 106                UA_MANDATORY,
 107                UA_ALLOC_AND_COPY),
 108        UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_PP_OBJ_ALLOC_FLAGS,
 109                        enum mlx5_ib_uapi_pp_alloc_flags,
 110                        UA_MANDATORY),
 111        UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_PP_OBJ_ALLOC_INDEX,
 112                           UVERBS_ATTR_TYPE(u16),
 113                           UA_MANDATORY));
 114
 115DECLARE_UVERBS_NAMED_METHOD_DESTROY(
 116        MLX5_IB_METHOD_PP_OBJ_DESTROY,
 117        UVERBS_ATTR_IDR(MLX5_IB_ATTR_PP_OBJ_DESTROY_HANDLE,
 118                        MLX5_IB_OBJECT_PP,
 119                        UVERBS_ACCESS_DESTROY,
 120                        UA_MANDATORY));
 121
 122DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_PP,
 123                            UVERBS_TYPE_ALLOC_IDR(pp_obj_cleanup),
 124                            &UVERBS_METHOD(MLX5_IB_METHOD_PP_OBJ_ALLOC),
 125                            &UVERBS_METHOD(MLX5_IB_METHOD_PP_OBJ_DESTROY));
 126
 127
 128const struct uapi_definition mlx5_ib_qos_defs[] = {
 129        UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
 130                MLX5_IB_OBJECT_PP,
 131                UAPI_DEF_IS_OBJ_SUPPORTED(pp_is_supported)),
 132        {},
 133};
 134