Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
0002 /*
0003  * Copyright (c) 2017, Mellanox Technologies inc.  All rights reserved.
0004  */
0005 
0006 #ifndef _UVERBS_STD_TYPES__
0007 #define _UVERBS_STD_TYPES__
0008 
0009 #include <rdma/uverbs_types.h>
0010 #include <rdma/uverbs_ioctl.h>
0011 #include <rdma/ib_user_ioctl_verbs.h>
0012 
0013 /* Returns _id, or causes a compile error if _id is not a u32.
0014  *
0015  * The uobj APIs should only be used with the write based uAPI to access
0016  * object IDs. The write API must use a u32 for the object handle, which is
0017  * checked by this macro.
0018  */
0019 #define _uobj_check_id(_id) ((_id) * typecheck(u32, _id))
0020 
0021 #define uobj_get_type(_attrs, _object)                                         \
0022     uapi_get_object((_attrs)->ufile->device->uapi, _object)
0023 
0024 #define uobj_get_read(_type, _id, _attrs)                                      \
0025     rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
0026                 _uobj_check_id(_id), UVERBS_LOOKUP_READ,       \
0027                 _attrs)
0028 
0029 #define ufd_get_read(_type, _fdnum, _attrs)                                    \
0030     rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
0031                 (_fdnum)*typecheck(s32, _fdnum),               \
0032                 UVERBS_LOOKUP_READ, _attrs)
0033 
0034 static inline void *_uobj_get_obj_read(struct ib_uobject *uobj)
0035 {
0036     if (IS_ERR(uobj))
0037         return NULL;
0038     return uobj->object;
0039 }
0040 #define uobj_get_obj_read(_object, _type, _id, _attrs)                         \
0041     ((struct ib_##_object *)_uobj_get_obj_read(                            \
0042         uobj_get_read(_type, _id, _attrs)))
0043 
0044 #define uobj_get_write(_type, _id, _attrs)                                     \
0045     rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
0046                 _uobj_check_id(_id), UVERBS_LOOKUP_WRITE,      \
0047                 _attrs)
0048 
0049 int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id,
0050                struct uverbs_attr_bundle *attrs);
0051 #define uobj_perform_destroy(_type, _id, _attrs)                               \
0052     __uobj_perform_destroy(uobj_get_type(_attrs, _type),                   \
0053                    _uobj_check_id(_id), _attrs)
0054 
0055 struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
0056                       u32 id, struct uverbs_attr_bundle *attrs);
0057 
0058 #define uobj_get_destroy(_type, _id, _attrs)                                   \
0059     __uobj_get_destroy(uobj_get_type(_attrs, _type), _uobj_check_id(_id),  \
0060                _attrs)
0061 
0062 static inline void uobj_put_destroy(struct ib_uobject *uobj)
0063 {
0064     rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_DESTROY);
0065 }
0066 
0067 static inline void uobj_put_read(struct ib_uobject *uobj)
0068 {
0069     rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_READ);
0070 }
0071 
0072 #define uobj_put_obj_read(_obj)                 \
0073     uobj_put_read((_obj)->uobject)
0074 
0075 static inline void uobj_put_write(struct ib_uobject *uobj)
0076 {
0077     rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE);
0078 }
0079 
0080 static inline void uobj_alloc_abort(struct ib_uobject *uobj,
0081                     struct uverbs_attr_bundle *attrs)
0082 {
0083     rdma_alloc_abort_uobject(uobj, attrs, false);
0084 }
0085 
0086 static inline void uobj_finalize_uobj_create(struct ib_uobject *uobj,
0087                          struct uverbs_attr_bundle *attrs)
0088 {
0089     /*
0090      * Tell the core code that the write() handler has completed
0091      * initializing the object and that the core should commit or
0092      * abort this object based upon the return code from the write()
0093      * method. Similar to what uverbs_finalize_uobj_create() does for
0094      * ioctl()
0095      */
0096     WARN_ON(attrs->uobject);
0097     attrs->uobject = uobj;
0098 }
0099 
0100 static inline struct ib_uobject *
0101 __uobj_alloc(const struct uverbs_api_object *obj,
0102          struct uverbs_attr_bundle *attrs, struct ib_device **ib_dev)
0103 {
0104     struct ib_uobject *uobj = rdma_alloc_begin_uobject(obj, attrs);
0105 
0106     if (!IS_ERR(uobj))
0107         *ib_dev = attrs->context->device;
0108     return uobj;
0109 }
0110 
0111 #define uobj_alloc(_type, _attrs, _ib_dev)                                     \
0112     __uobj_alloc(uobj_get_type(_attrs, _type), _attrs, _ib_dev)
0113 
0114 static inline void uverbs_flow_action_fill_action(struct ib_flow_action *action,
0115                           struct ib_uobject *uobj,
0116                           struct ib_device *ib_dev,
0117                           enum ib_flow_action_type type)
0118 {
0119     atomic_set(&action->usecnt, 0);
0120     action->device = ib_dev;
0121     action->type = type;
0122     action->uobject = uobj;
0123     uobj->object = action;
0124 }
0125 
0126 struct ib_uflow_resources {
0127     size_t          max;
0128     size_t          num;
0129     size_t          collection_num;
0130     size_t          counters_num;
0131     struct ib_counters  **counters;
0132     struct ib_flow_action   **collection;
0133 };
0134 
0135 struct ib_uflow_object {
0136     struct ib_uobject       uobject;
0137     struct ib_uflow_resources   *resources;
0138 };
0139 
0140 struct ib_uflow_resources *flow_resources_alloc(size_t num_specs);
0141 void flow_resources_add(struct ib_uflow_resources *uflow_res,
0142             enum ib_flow_spec_type type,
0143             void *ibobj);
0144 void ib_uverbs_flow_resources_free(struct ib_uflow_resources *uflow_res);
0145 
0146 static inline void ib_set_flow(struct ib_uobject *uobj, struct ib_flow *ibflow,
0147                    struct ib_qp *qp, struct ib_device *device,
0148                    struct ib_uflow_resources *uflow_res)
0149 {
0150     struct ib_uflow_object *uflow;
0151 
0152     uobj->object = ibflow;
0153     ibflow->uobject = uobj;
0154 
0155     if (qp) {
0156         atomic_inc(&qp->usecnt);
0157         ibflow->qp = qp;
0158     }
0159 
0160     ibflow->device = device;
0161     uflow = container_of(uobj, typeof(*uflow), uobject);
0162     uflow->resources = uflow_res;
0163 }
0164 
0165 struct uverbs_api_object {
0166     const struct uverbs_obj_type *type_attrs;
0167     const struct uverbs_obj_type_class *type_class;
0168     u8 disabled:1;
0169     u32 id;
0170 };
0171 
0172 static inline u32 uobj_get_object_id(struct ib_uobject *uobj)
0173 {
0174     return uobj->uapi_object->id;
0175 }
0176 
0177 #endif
0178