linux/include/rdma/uverbs_std_types.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2017, Mellanox Technologies inc.  All rights reserved.
   3 *
   4 * This software is available to you under a choice of one of two
   5 * licenses.  You may choose to be licensed under the terms of the GNU
   6 * General Public License (GPL) Version 2, available from the file
   7 * COPYING in the main directory of this source tree, or the
   8 * OpenIB.org BSD license below:
   9 *
  10 *     Redistribution and use in source and binary forms, with or
  11 *     without modification, are permitted provided that the following
  12 *     conditions are met:
  13 *
  14 *      - Redistributions of source code must retain the above
  15 *        copyright notice, this list of conditions and the following
  16 *        disclaimer.
  17 *
  18 *      - Redistributions in binary form must reproduce the above
  19 *        copyright notice, this list of conditions and the following
  20 *        disclaimer in the documentation and/or other materials
  21 *        provided with the distribution.
  22 *
  23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30 * SOFTWARE.
  31 */
  32
  33#ifndef _UVERBS_STD_TYPES__
  34#define _UVERBS_STD_TYPES__
  35
  36#include <rdma/uverbs_types.h>
  37#include <rdma/uverbs_ioctl.h>
  38#include <rdma/ib_user_ioctl_verbs.h>
  39
  40/* Returns _id, or causes a compile error if _id is not a u32.
  41 *
  42 * The uobj APIs should only be used with the write based uAPI to access
  43 * object IDs. The write API must use a u32 for the object handle, which is
  44 * checked by this macro.
  45 */
  46#define _uobj_check_id(_id) ((_id) * typecheck(u32, _id))
  47
  48#define uobj_get_type(_attrs, _object)                                         \
  49        uapi_get_object((_attrs)->ufile->device->uapi, _object)
  50
  51#define uobj_get_read(_type, _id, _attrs)                                      \
  52        rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
  53                                _uobj_check_id(_id), UVERBS_LOOKUP_READ)
  54
  55#define ufd_get_read(_type, _fdnum, _attrs)                                    \
  56        rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
  57                                (_fdnum)*typecheck(s32, _fdnum),               \
  58                                UVERBS_LOOKUP_READ)
  59
  60static inline void *_uobj_get_obj_read(struct ib_uobject *uobj)
  61{
  62        if (IS_ERR(uobj))
  63                return NULL;
  64        return uobj->object;
  65}
  66#define uobj_get_obj_read(_object, _type, _id, _attrs)                         \
  67        ((struct ib_##_object *)_uobj_get_obj_read(                            \
  68                uobj_get_read(_type, _id, _attrs)))
  69
  70#define uobj_get_write(_type, _id, _attrs)                                     \
  71        rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
  72                                _uobj_check_id(_id), UVERBS_LOOKUP_WRITE)
  73
  74int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id,
  75                           const struct uverbs_attr_bundle *attrs);
  76#define uobj_perform_destroy(_type, _id, _attrs)                               \
  77        __uobj_perform_destroy(uobj_get_type(_attrs, _type),                   \
  78                               _uobj_check_id(_id), _attrs)
  79
  80struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
  81                                      u32 id,
  82                                      const struct uverbs_attr_bundle *attrs);
  83
  84#define uobj_get_destroy(_type, _id, _attrs)                                   \
  85        __uobj_get_destroy(uobj_get_type(_attrs, _type), _uobj_check_id(_id),  \
  86                           _attrs)
  87
  88static inline void uobj_put_destroy(struct ib_uobject *uobj)
  89{
  90        rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE);
  91}
  92
  93static inline void uobj_put_read(struct ib_uobject *uobj)
  94{
  95        rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_READ);
  96}
  97
  98#define uobj_put_obj_read(_obj)                                 \
  99        uobj_put_read((_obj)->uobject)
 100
 101static inline void uobj_put_write(struct ib_uobject *uobj)
 102{
 103        rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE);
 104}
 105
 106static inline int __must_check uobj_alloc_commit(struct ib_uobject *uobj)
 107{
 108        int ret = rdma_alloc_commit_uobject(uobj);
 109
 110        if (ret)
 111                return ret;
 112        return 0;
 113}
 114
 115static inline void uobj_alloc_abort(struct ib_uobject *uobj)
 116{
 117        rdma_alloc_abort_uobject(uobj);
 118}
 119
 120static inline struct ib_uobject *
 121__uobj_alloc(const struct uverbs_api_object *obj,
 122             struct uverbs_attr_bundle *attrs, struct ib_device **ib_dev)
 123{
 124        struct ib_uobject *uobj = rdma_alloc_begin_uobject(obj, attrs->ufile);
 125
 126        if (!IS_ERR(uobj))
 127                *ib_dev = uobj->context->device;
 128        return uobj;
 129}
 130
 131#define uobj_alloc(_type, _attrs, _ib_dev)                                     \
 132        __uobj_alloc(uobj_get_type(_attrs, _type), _attrs, _ib_dev)
 133
 134static inline void uverbs_flow_action_fill_action(struct ib_flow_action *action,
 135                                                  struct ib_uobject *uobj,
 136                                                  struct ib_device *ib_dev,
 137                                                  enum ib_flow_action_type type)
 138{
 139        atomic_set(&action->usecnt, 0);
 140        action->device = ib_dev;
 141        action->type = type;
 142        action->uobject = uobj;
 143        uobj->object = action;
 144}
 145
 146struct ib_uflow_resources {
 147        size_t                  max;
 148        size_t                  num;
 149        size_t                  collection_num;
 150        size_t                  counters_num;
 151        struct ib_counters      **counters;
 152        struct ib_flow_action   **collection;
 153};
 154
 155struct ib_uflow_object {
 156        struct ib_uobject               uobject;
 157        struct ib_uflow_resources       *resources;
 158};
 159
 160struct ib_uflow_resources *flow_resources_alloc(size_t num_specs);
 161void flow_resources_add(struct ib_uflow_resources *uflow_res,
 162                        enum ib_flow_spec_type type,
 163                        void *ibobj);
 164void ib_uverbs_flow_resources_free(struct ib_uflow_resources *uflow_res);
 165
 166static inline void ib_set_flow(struct ib_uobject *uobj, struct ib_flow *ibflow,
 167                               struct ib_qp *qp, struct ib_device *device,
 168                               struct ib_uflow_resources *uflow_res)
 169{
 170        struct ib_uflow_object *uflow;
 171
 172        uobj->object = ibflow;
 173        ibflow->uobject = uobj;
 174
 175        if (qp) {
 176                atomic_inc(&qp->usecnt);
 177                ibflow->qp = qp;
 178        }
 179
 180        ibflow->device = device;
 181        uflow = container_of(uobj, typeof(*uflow), uobject);
 182        uflow->resources = uflow_res;
 183}
 184
 185struct uverbs_api_object {
 186        const struct uverbs_obj_type *type_attrs;
 187        const struct uverbs_obj_type_class *type_class;
 188        u8 disabled:1;
 189        u32 id;
 190};
 191
 192static inline u32 uobj_get_object_id(struct ib_uobject *uobj)
 193{
 194        return uobj->uapi_object->id;
 195}
 196
 197#endif
 198
 199