linux/drivers/infiniband/core/uverbs_std_types_srq.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_std_types.h>
   7#include "rdma_core.h"
   8#include "uverbs.h"
   9
  10static int uverbs_free_srq(struct ib_uobject *uobject,
  11                    enum rdma_remove_reason why,
  12                    struct uverbs_attr_bundle *attrs)
  13{
  14        struct ib_srq *srq = uobject->object;
  15        struct ib_uevent_object *uevent =
  16                container_of(uobject, struct ib_uevent_object, uobject);
  17        enum ib_srq_type srq_type = srq->srq_type;
  18        int ret;
  19
  20        ret = ib_destroy_srq_user(srq, &attrs->driver_udata);
  21        if (ret)
  22                return ret;
  23
  24        if (srq_type == IB_SRQT_XRC) {
  25                struct ib_usrq_object *us =
  26                        container_of(uobject, struct ib_usrq_object,
  27                                     uevent.uobject);
  28
  29                atomic_dec(&us->uxrcd->refcnt);
  30        }
  31
  32        ib_uverbs_release_uevent(uevent);
  33        return 0;
  34}
  35
  36static int UVERBS_HANDLER(UVERBS_METHOD_SRQ_CREATE)(
  37        struct uverbs_attr_bundle *attrs)
  38{
  39        struct ib_usrq_object *obj = container_of(
  40                uverbs_attr_get_uobject(attrs, UVERBS_ATTR_CREATE_SRQ_HANDLE),
  41                typeof(*obj), uevent.uobject);
  42        struct ib_pd *pd =
  43                uverbs_attr_get_obj(attrs, UVERBS_ATTR_CREATE_SRQ_PD_HANDLE);
  44        struct ib_srq_init_attr attr = {};
  45        struct ib_uobject *xrcd_uobj;
  46        struct ib_srq *srq;
  47        u64 user_handle;
  48        int ret;
  49
  50        ret = uverbs_copy_from(&attr.attr.max_sge, attrs,
  51                               UVERBS_ATTR_CREATE_SRQ_MAX_SGE);
  52        if (!ret)
  53                ret = uverbs_copy_from(&attr.attr.max_wr, attrs,
  54                                       UVERBS_ATTR_CREATE_SRQ_MAX_WR);
  55        if (!ret)
  56                ret = uverbs_copy_from(&attr.attr.srq_limit, attrs,
  57                                       UVERBS_ATTR_CREATE_SRQ_LIMIT);
  58        if (!ret)
  59                ret = uverbs_copy_from(&user_handle, attrs,
  60                                       UVERBS_ATTR_CREATE_SRQ_USER_HANDLE);
  61        if (!ret)
  62                ret = uverbs_get_const(&attr.srq_type, attrs,
  63                                       UVERBS_ATTR_CREATE_SRQ_TYPE);
  64        if (ret)
  65                return ret;
  66
  67        if (ib_srq_has_cq(attr.srq_type)) {
  68                attr.ext.cq = uverbs_attr_get_obj(attrs,
  69                                        UVERBS_ATTR_CREATE_SRQ_CQ_HANDLE);
  70                if (IS_ERR(attr.ext.cq))
  71                        return PTR_ERR(attr.ext.cq);
  72        }
  73
  74        switch (attr.srq_type) {
  75        case IB_UVERBS_SRQT_XRC:
  76                xrcd_uobj = uverbs_attr_get_uobject(attrs,
  77                                        UVERBS_ATTR_CREATE_SRQ_XRCD_HANDLE);
  78                if (IS_ERR(xrcd_uobj))
  79                        return PTR_ERR(xrcd_uobj);
  80
  81                attr.ext.xrc.xrcd = (struct ib_xrcd *)xrcd_uobj->object;
  82                if (!attr.ext.xrc.xrcd)
  83                        return -EINVAL;
  84                obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object,
  85                                          uobject);
  86                atomic_inc(&obj->uxrcd->refcnt);
  87                break;
  88        case IB_UVERBS_SRQT_TM:
  89                ret = uverbs_copy_from(&attr.ext.tag_matching.max_num_tags,
  90                                       attrs,
  91                                       UVERBS_ATTR_CREATE_SRQ_MAX_NUM_TAGS);
  92                if (ret)
  93                        return ret;
  94                break;
  95        case IB_UVERBS_SRQT_BASIC:
  96                break;
  97        default:
  98                return -EINVAL;
  99        }
 100
 101        obj->uevent.event_file = ib_uverbs_get_async_event(attrs,
 102                                        UVERBS_ATTR_CREATE_SRQ_EVENT_FD);
 103        INIT_LIST_HEAD(&obj->uevent.event_list);
 104        attr.event_handler = ib_uverbs_srq_event_handler;
 105        obj->uevent.uobject.user_handle = user_handle;
 106
 107        srq = ib_create_srq_user(pd, &attr, obj, &attrs->driver_udata);
 108        if (IS_ERR(srq)) {
 109                ret = PTR_ERR(srq);
 110                goto err;
 111        }
 112
 113        obj->uevent.uobject.object = srq;
 114        uverbs_finalize_uobj_create(attrs, UVERBS_ATTR_CREATE_SRQ_HANDLE);
 115
 116        ret = uverbs_copy_to(attrs, UVERBS_ATTR_CREATE_SRQ_RESP_MAX_WR,
 117                             &attr.attr.max_wr,
 118                             sizeof(attr.attr.max_wr));
 119        if (ret)
 120                return ret;
 121
 122        ret = uverbs_copy_to(attrs, UVERBS_ATTR_CREATE_SRQ_RESP_MAX_SGE,
 123                             &attr.attr.max_sge,
 124                             sizeof(attr.attr.max_sge));
 125        if (ret)
 126                return ret;
 127
 128        if (attr.srq_type == IB_SRQT_XRC) {
 129                ret = uverbs_copy_to(attrs,
 130                                     UVERBS_ATTR_CREATE_SRQ_RESP_SRQ_NUM,
 131                                     &srq->ext.xrc.srq_num,
 132                                     sizeof(srq->ext.xrc.srq_num));
 133                if (ret)
 134                        return ret;
 135        }
 136
 137        return 0;
 138err:
 139        if (obj->uevent.event_file)
 140                uverbs_uobject_put(&obj->uevent.event_file->uobj);
 141        if (attr.srq_type == IB_SRQT_XRC)
 142                atomic_dec(&obj->uxrcd->refcnt);
 143        return ret;
 144};
 145
 146DECLARE_UVERBS_NAMED_METHOD(
 147        UVERBS_METHOD_SRQ_CREATE,
 148        UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_SRQ_HANDLE,
 149                        UVERBS_OBJECT_SRQ,
 150                        UVERBS_ACCESS_NEW,
 151                        UA_MANDATORY),
 152        UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_SRQ_PD_HANDLE,
 153                        UVERBS_OBJECT_PD,
 154                        UVERBS_ACCESS_READ,
 155                        UA_MANDATORY),
 156        UVERBS_ATTR_CONST_IN(UVERBS_ATTR_CREATE_SRQ_TYPE,
 157                             enum ib_uverbs_srq_type,
 158                             UA_MANDATORY),
 159        UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_SRQ_USER_HANDLE,
 160                           UVERBS_ATTR_TYPE(u64),
 161                           UA_MANDATORY),
 162        UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_SRQ_MAX_WR,
 163                           UVERBS_ATTR_TYPE(u32),
 164                           UA_MANDATORY),
 165        UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_SRQ_MAX_SGE,
 166                           UVERBS_ATTR_TYPE(u32),
 167                           UA_MANDATORY),
 168        UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_SRQ_LIMIT,
 169                           UVERBS_ATTR_TYPE(u32),
 170                           UA_MANDATORY),
 171        UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_SRQ_XRCD_HANDLE,
 172                        UVERBS_OBJECT_XRCD,
 173                        UVERBS_ACCESS_READ,
 174                        UA_OPTIONAL),
 175        UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_SRQ_CQ_HANDLE,
 176                        UVERBS_OBJECT_CQ,
 177                        UVERBS_ACCESS_READ,
 178                        UA_OPTIONAL),
 179        UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_SRQ_MAX_NUM_TAGS,
 180                           UVERBS_ATTR_TYPE(u32),
 181                           UA_OPTIONAL),
 182        UVERBS_ATTR_FD(UVERBS_ATTR_CREATE_SRQ_EVENT_FD,
 183                       UVERBS_OBJECT_ASYNC_EVENT,
 184                       UVERBS_ACCESS_READ,
 185                       UA_OPTIONAL),
 186        UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_CREATE_SRQ_RESP_MAX_WR,
 187                            UVERBS_ATTR_TYPE(u32),
 188                            UA_MANDATORY),
 189        UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_CREATE_SRQ_RESP_MAX_SGE,
 190                            UVERBS_ATTR_TYPE(u32),
 191                            UA_MANDATORY),
 192        UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_CREATE_SRQ_RESP_SRQ_NUM,
 193                           UVERBS_ATTR_TYPE(u32),
 194                           UA_OPTIONAL),
 195        UVERBS_ATTR_UHW());
 196
 197static int UVERBS_HANDLER(UVERBS_METHOD_SRQ_DESTROY)(
 198        struct uverbs_attr_bundle *attrs)
 199{
 200        struct ib_uobject *uobj =
 201                uverbs_attr_get_uobject(attrs, UVERBS_ATTR_DESTROY_SRQ_HANDLE);
 202        struct ib_usrq_object *obj =
 203                container_of(uobj, struct ib_usrq_object, uevent.uobject);
 204        struct ib_uverbs_destroy_srq_resp resp = {
 205                .events_reported = obj->uevent.events_reported
 206        };
 207
 208        return uverbs_copy_to(attrs, UVERBS_ATTR_DESTROY_SRQ_RESP, &resp,
 209                              sizeof(resp));
 210}
 211
 212DECLARE_UVERBS_NAMED_METHOD(
 213        UVERBS_METHOD_SRQ_DESTROY,
 214        UVERBS_ATTR_IDR(UVERBS_ATTR_DESTROY_SRQ_HANDLE,
 215                        UVERBS_OBJECT_SRQ,
 216                        UVERBS_ACCESS_DESTROY,
 217                        UA_MANDATORY),
 218        UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_DESTROY_SRQ_RESP,
 219                            UVERBS_ATTR_TYPE(struct ib_uverbs_destroy_srq_resp),
 220                            UA_MANDATORY));
 221
 222DECLARE_UVERBS_NAMED_OBJECT(
 223        UVERBS_OBJECT_SRQ,
 224        UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_usrq_object),
 225                                 uverbs_free_srq),
 226        &UVERBS_METHOD(UVERBS_METHOD_SRQ_CREATE),
 227        &UVERBS_METHOD(UVERBS_METHOD_SRQ_DESTROY)
 228);
 229
 230const struct uapi_definition uverbs_def_obj_srq[] = {
 231        UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_SRQ,
 232                                      UAPI_DEF_OBJ_NEEDS_FN(destroy_srq)),
 233        {}
 234};
 235