alistair23-linux/include/rdma/uverbs_types.h
Matan Barak 4da70da23e IB/core: Explicitly destroy an object while keeping uobject
When some objects are destroyed, we need to extract their status at
destruction. After object's destruction, this status
(e.g. events_reported) relies in the uobject. In order to have the
latest and correct status, the underlying object should be destroyed,
but we should keep the uobject alive and read this information off the
uobject. We introduce a rdma_explicit_destroy function. This function
destroys the class type object (for example, the IDR class type which
destroys the underlying object as well) and then convert the uobject
to be of a null class type. This uobject will then be destroyed as any
other uobject once uverbs_finalize_object[s] is called.

Signed-off-by: Matan Barak <matanb@mellanox.com>
Reviewed-by: Yishai Hadas <yishaih@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
2017-08-31 08:35:11 -04:00

182 lines
7.1 KiB
C

/*
* Copyright (c) 2017, Mellanox Technologies inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef _UVERBS_TYPES_
#define _UVERBS_TYPES_
#include <linux/kernel.h>
#include <rdma/ib_verbs.h>
struct uverbs_obj_type;
struct uverbs_obj_type_class {
/*
* Get an ib_uobject that corresponds to the given id from ucontext,
* These functions could create or destroy objects if required.
* The action will be finalized only when commit, abort or put fops are
* called.
* The flow of the different actions is:
* [alloc]: Starts with alloc_begin. The handlers logic is than
* executed. If the handler is successful, alloc_commit
* is called and the object is inserted to the repository.
* Once alloc_commit completes the object is visible to
* other threads and userspace.
e Otherwise, alloc_abort is called and the object is
* destroyed.
* [lookup]: Starts with lookup_get which fetches and locks the
* object. After the handler finished using the object, it
* needs to call lookup_put to unlock it. The exclusive
* flag indicates if the object is locked for exclusive
* access.
* [remove]: Starts with lookup_get with exclusive flag set. This
* locks the object for exclusive access. If the handler
* code completed successfully, remove_commit is called
* and the ib_uobject is removed from the context's
* uobjects repository and put. The object itself is
* destroyed as well. Once remove succeeds new krefs to
* the object cannot be acquired by other threads or
* userspace and the hardware driver is removed from the
* object. Other krefs on the object may still exist.
* If the handler code failed, lookup_put should be
* called. This callback is used when the context
* is destroyed as well (process termination,
* reset flow).
*/
struct ib_uobject *(*alloc_begin)(const struct uverbs_obj_type *type,
struct ib_ucontext *ucontext);
void (*alloc_commit)(struct ib_uobject *uobj);
void (*alloc_abort)(struct ib_uobject *uobj);
struct ib_uobject *(*lookup_get)(const struct uverbs_obj_type *type,
struct ib_ucontext *ucontext, int id,
bool exclusive);
void (*lookup_put)(struct ib_uobject *uobj, bool exclusive);
/*
* Must be called with the exclusive lock held. If successful uobj is
* invalid on return. On failure uobject is left completely
* unchanged
*/
int __must_check (*remove_commit)(struct ib_uobject *uobj,
enum rdma_remove_reason why);
u8 needs_kfree_rcu;
};
struct uverbs_obj_type {
const struct uverbs_obj_type_class * const type_class;
size_t obj_size;
unsigned int destroy_order;
};
/*
* Objects type classes which support a detach state (object is still alive but
* it's not attached to any context need to make sure:
* (a) no call through to a driver after a detach is called
* (b) detach isn't called concurrently with context_cleanup
*/
struct uverbs_obj_idr_type {
/*
* In idr based objects, uverbs_obj_type_class points to a generic
* idr operations. In order to specialize the underlying types (e.g. CQ,
* QPs, etc.), we add destroy_object specific callbacks.
*/
struct uverbs_obj_type type;
/* Free driver resources from the uobject, make the driver uncallable,
* and move the uobject to the detached state. If the object was
* destroyed by the user's request, a failure should leave the uobject
* completely unchanged.
*/
int __must_check (*destroy_object)(struct ib_uobject *uobj,
enum rdma_remove_reason why);
};
struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_obj_type *type,
struct ib_ucontext *ucontext,
int id, bool exclusive);
void rdma_lookup_put_uobject(struct ib_uobject *uobj, bool exclusive);
struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_obj_type *type,
struct ib_ucontext *ucontext);
void rdma_alloc_abort_uobject(struct ib_uobject *uobj);
int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj);
int rdma_alloc_commit_uobject(struct ib_uobject *uobj);
int rdma_explicit_destroy(struct ib_uobject *uobject);
struct uverbs_obj_fd_type {
/*
* In fd based objects, uverbs_obj_type_ops points to generic
* fd operations. In order to specialize the underlying types (e.g.
* completion_channel), we use fops, name and flags for fd creation.
* context_closed is called when the context is closed either when
* the driver is removed or the process terminated.
*/
struct uverbs_obj_type type;
int (*context_closed)(struct ib_uobject_file *uobj_file,
enum rdma_remove_reason why);
const struct file_operations *fops;
const char *name;
int flags;
};
extern const struct uverbs_obj_type_class uverbs_idr_class;
extern const struct uverbs_obj_type_class uverbs_fd_class;
#define UVERBS_BUILD_BUG_ON(cond) (sizeof(char[1 - 2 * !!(cond)]) - \
sizeof(char))
#define UVERBS_TYPE_ALLOC_FD(_order, _obj_size, _context_closed, _fops, _name, _flags)\
((&((const struct uverbs_obj_fd_type) \
{.type = { \
.destroy_order = _order, \
.type_class = &uverbs_fd_class, \
.obj_size = (_obj_size) + \
UVERBS_BUILD_BUG_ON((_obj_size) < sizeof(struct ib_uobject_file)), \
}, \
.context_closed = _context_closed, \
.fops = _fops, \
.name = _name, \
.flags = _flags}))->type)
#define UVERBS_TYPE_ALLOC_IDR_SZ(_size, _order, _destroy_object) \
((&((const struct uverbs_obj_idr_type) \
{.type = { \
.destroy_order = _order, \
.type_class = &uverbs_idr_class, \
.obj_size = (_size) + \
UVERBS_BUILD_BUG_ON((_size) < \
sizeof(struct ib_uobject)) \
}, \
.destroy_object = _destroy_object,}))->type)
#define UVERBS_TYPE_ALLOC_IDR(_order, _destroy_object) \
UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uobject), _order, \
_destroy_object)
#endif