linux/include/rdma/uverbs_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_TYPES_
  34#define _UVERBS_TYPES_
  35
  36#include <linux/kernel.h>
  37#include <rdma/ib_verbs.h>
  38
  39struct uverbs_obj_type;
  40
  41struct uverbs_obj_type_class {
  42        /*
  43         * Get an ib_uobject that corresponds to the given id from ucontext,
  44         * These functions could create or destroy objects if required.
  45         * The action will be finalized only when commit, abort or put fops are
  46         * called.
  47         * The flow of the different actions is:
  48         * [alloc]:      Starts with alloc_begin. The handlers logic is than
  49         *               executed. If the handler is successful, alloc_commit
  50         *               is called and the object is inserted to the repository.
  51         *               Once alloc_commit completes the object is visible to
  52         *               other threads and userspace.
  53         e               Otherwise, alloc_abort is called and the object is
  54         *               destroyed.
  55         * [lookup]:     Starts with lookup_get which fetches and locks the
  56         *               object. After the handler finished using the object, it
  57         *               needs to call lookup_put to unlock it. The exclusive
  58         *               flag indicates if the object is locked for exclusive
  59         *               access.
  60         * [remove]:     Starts with lookup_get with exclusive flag set. This
  61         *               locks the object for exclusive access. If the handler
  62         *               code completed successfully, remove_commit is called
  63         *               and the ib_uobject is removed from the context's
  64         *               uobjects repository and put. The object itself is
  65         *               destroyed as well. Once remove succeeds new krefs to
  66         *               the object cannot be acquired by other threads or
  67         *               userspace and the hardware driver is removed from the
  68         *               object. Other krefs on the object may still exist.
  69         *               If the handler code failed, lookup_put should be
  70         *               called. This callback is used when the context
  71         *               is destroyed as well (process termination,
  72         *               reset flow).
  73         */
  74        struct ib_uobject *(*alloc_begin)(const struct uverbs_obj_type *type,
  75                                          struct ib_ucontext *ucontext);
  76        void (*alloc_commit)(struct ib_uobject *uobj);
  77        void (*alloc_abort)(struct ib_uobject *uobj);
  78
  79        struct ib_uobject *(*lookup_get)(const struct uverbs_obj_type *type,
  80                                         struct ib_ucontext *ucontext, int id,
  81                                         bool exclusive);
  82        void (*lookup_put)(struct ib_uobject *uobj, bool exclusive);
  83        /*
  84         * Must be called with the exclusive lock held. If successful uobj is
  85         * invalid on return. On failure uobject is left completely
  86         * unchanged
  87         */
  88        int __must_check (*remove_commit)(struct ib_uobject *uobj,
  89                                          enum rdma_remove_reason why);
  90        u8    needs_kfree_rcu;
  91};
  92
  93struct uverbs_obj_type {
  94        const struct uverbs_obj_type_class * const type_class;
  95        size_t       obj_size;
  96        unsigned int destroy_order;
  97};
  98
  99/*
 100 * Objects type classes which support a detach state (object is still alive but
 101 * it's not attached to any context need to make sure:
 102 * (a) no call through to a driver after a detach is called
 103 * (b) detach isn't called concurrently with context_cleanup
 104 */
 105
 106struct uverbs_obj_idr_type {
 107        /*
 108         * In idr based objects, uverbs_obj_type_class points to a generic
 109         * idr operations. In order to specialize the underlying types (e.g. CQ,
 110         * QPs, etc.), we add destroy_object specific callbacks.
 111         */
 112        struct uverbs_obj_type  type;
 113
 114        /* Free driver resources from the uobject, make the driver uncallable,
 115         * and move the uobject to the detached state. If the object was
 116         * destroyed by the user's request, a failure should leave the uobject
 117         * completely unchanged.
 118         */
 119        int __must_check (*destroy_object)(struct ib_uobject *uobj,
 120                                           enum rdma_remove_reason why);
 121};
 122
 123struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_obj_type *type,
 124                                           struct ib_ucontext *ucontext,
 125                                           int id, bool exclusive);
 126void rdma_lookup_put_uobject(struct ib_uobject *uobj, bool exclusive);
 127struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_obj_type *type,
 128                                            struct ib_ucontext *ucontext);
 129void rdma_alloc_abort_uobject(struct ib_uobject *uobj);
 130int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj);
 131int rdma_alloc_commit_uobject(struct ib_uobject *uobj);
 132
 133struct uverbs_obj_fd_type {
 134        /*
 135         * In fd based objects, uverbs_obj_type_ops points to generic
 136         * fd operations. In order to specialize the underlying types (e.g.
 137         * completion_channel), we use fops, name and flags for fd creation.
 138         * context_closed is called when the context is closed either when
 139         * the driver is removed or the process terminated.
 140         */
 141        struct uverbs_obj_type  type;
 142        int (*context_closed)(struct ib_uobject_file *uobj_file,
 143                              enum rdma_remove_reason why);
 144        const struct file_operations    *fops;
 145        const char                      *name;
 146        int                             flags;
 147};
 148
 149extern const struct uverbs_obj_type_class uverbs_idr_class;
 150extern const struct uverbs_obj_type_class uverbs_fd_class;
 151
 152#define UVERBS_BUILD_BUG_ON(cond) (sizeof(char[1 - 2 * !!(cond)]) -     \
 153                                   sizeof(char))
 154#define UVERBS_TYPE_ALLOC_FD(_size, _order)                              \
 155        {                                                                \
 156                .destroy_order = _order,                                 \
 157                .type_class = &uverbs_fd_class,                          \
 158                .obj_size = (_size) +                                    \
 159                          UVERBS_BUILD_BUG_ON((_size) <                  \
 160                                              sizeof(struct ib_uobject_file)),\
 161        }
 162#define UVERBS_TYPE_ALLOC_IDR_SZ(_size, _order)                         \
 163        {                                                               \
 164                .destroy_order = _order,                                \
 165                .type_class = &uverbs_idr_class,                        \
 166                .obj_size = (_size) +                                   \
 167                          UVERBS_BUILD_BUG_ON((_size) <                 \
 168                                              sizeof(struct ib_uobject)), \
 169        }
 170#define UVERBS_TYPE_ALLOC_IDR(_order)                                   \
 171         UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uobject), _order)
 172#endif
 173