aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatan Barak <matanb@mellanox.com>2017-08-03 09:06:55 -0400
committerDoug Ledford <dledford@redhat.com>2017-08-30 10:30:38 -0400
commita0aa309c39de58b86b704654434431aeb5a8bdf1 (patch)
treec3791d67018bc7e577119f914eec7fa5e2dbcc74
parent82fb342460362ce81cce2068eb4d9bf7f9e94be2 (diff)
IB/core: Add a generic way to execute an operation on a uobject
The ioctl infrastructure treats all user-objects in the same manner. It gets objects ids from the user-space and by using the object type and type attributes mentioned in the object specification, it executes this required method. Passing an object id from the user-space as an attribute is carried out in three stages. The first is carried out before the actual handler and the last is carried out afterwards. The different supported operations are read, write, destroy and create. In the first stage, the former three actions just fetches the object from the repository (by using its id) and locks it. The last action allocates a new uobject. Afterwards, the second stage is carried out when the handler itself carries out the required modification of the object. The last stage is carried out after the handler finishes and commits the result. The former two operations just unlock the object. Destroy calls the "free object" operation, taking into account the object's type and releases the uobject as well. Creation just adds the new uobject to the repository, making the object visible to the application. In order to abstract these details from the ioctl infrastructure layer, we add uverbs_get_uobject_from_context and uverbs_finalize_object functions which corresponds to the first and last stages respectively. Signed-off-by: Matan Barak <matanb@mellanox.com> Reviewed-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/core/rdma_core.c58
-rw-r--r--drivers/infiniband/core/rdma_core.h17
-rw-r--r--include/rdma/uverbs_ioctl.h52
3 files changed, 127 insertions, 0 deletions
diff --git a/drivers/infiniband/core/rdma_core.c b/drivers/infiniband/core/rdma_core.c
index 41c31a2bf093..2bd58ff17bb8 100644
--- a/drivers/infiniband/core/rdma_core.c
+++ b/drivers/infiniband/core/rdma_core.c
@@ -35,6 +35,7 @@
35#include <rdma/ib_verbs.h> 35#include <rdma/ib_verbs.h>
36#include <rdma/uverbs_types.h> 36#include <rdma/uverbs_types.h>
37#include <linux/rcupdate.h> 37#include <linux/rcupdate.h>
38#include <rdma/uverbs_ioctl.h>
38#include "uverbs.h" 39#include "uverbs.h"
39#include "core_priv.h" 40#include "core_priv.h"
40#include "rdma_core.h" 41#include "rdma_core.h"
@@ -625,3 +626,60 @@ const struct uverbs_obj_type_class uverbs_fd_class = {
625 .needs_kfree_rcu = false, 626 .needs_kfree_rcu = false,
626}; 627};
627 628
629struct ib_uobject *uverbs_get_uobject_from_context(const struct uverbs_obj_type *type_attrs,
630 struct ib_ucontext *ucontext,
631 enum uverbs_obj_access access,
632 int id)
633{
634 switch (access) {
635 case UVERBS_ACCESS_READ:
636 return rdma_lookup_get_uobject(type_attrs, ucontext, id, false);
637 case UVERBS_ACCESS_DESTROY:
638 case UVERBS_ACCESS_WRITE:
639 return rdma_lookup_get_uobject(type_attrs, ucontext, id, true);
640 case UVERBS_ACCESS_NEW:
641 return rdma_alloc_begin_uobject(type_attrs, ucontext);
642 default:
643 WARN_ON(true);
644 return ERR_PTR(-EOPNOTSUPP);
645 }
646}
647
648int uverbs_finalize_object(struct ib_uobject *uobj,
649 enum uverbs_obj_access access,
650 bool commit)
651{
652 int ret = 0;
653
654 /*
655 * refcounts should be handled at the object level and not at the
656 * uobject level. Refcounts of the objects themselves are done in
657 * handlers.
658 */
659
660 switch (access) {
661 case UVERBS_ACCESS_READ:
662 rdma_lookup_put_uobject(uobj, false);
663 break;
664 case UVERBS_ACCESS_WRITE:
665 rdma_lookup_put_uobject(uobj, true);
666 break;
667 case UVERBS_ACCESS_DESTROY:
668 if (commit)
669 ret = rdma_remove_commit_uobject(uobj);
670 else
671 rdma_lookup_put_uobject(uobj, true);
672 break;
673 case UVERBS_ACCESS_NEW:
674 if (commit)
675 ret = rdma_alloc_commit_uobject(uobj);
676 else
677 rdma_alloc_abort_uobject(uobj);
678 break;
679 default:
680 WARN_ON(true);
681 ret = -EOPNOTSUPP;
682 }
683
684 return ret;
685}
diff --git a/drivers/infiniband/core/rdma_core.h b/drivers/infiniband/core/rdma_core.h
index 1b82e7ff7fe8..97483d1a7336 100644
--- a/drivers/infiniband/core/rdma_core.h
+++ b/drivers/infiniband/core/rdma_core.h
@@ -39,6 +39,7 @@
39 39
40#include <linux/idr.h> 40#include <linux/idr.h>
41#include <rdma/uverbs_types.h> 41#include <rdma/uverbs_types.h>
42#include <rdma/uverbs_ioctl.h>
42#include <rdma/ib_verbs.h> 43#include <rdma/ib_verbs.h>
43#include <linux/mutex.h> 44#include <linux/mutex.h>
44 45
@@ -75,4 +76,20 @@ void uverbs_uobject_put(struct ib_uobject *uobject);
75 */ 76 */
76void uverbs_close_fd(struct file *f); 77void uverbs_close_fd(struct file *f);
77 78
79/*
80 * Get an ib_uobject that corresponds to the given id from ucontext, assuming
81 * the object is from the given type. Lock it to the required access when
82 * applicable.
83 * This function could create (access == NEW), destroy (access == DESTROY)
84 * or unlock (access == READ || access == WRITE) objects if required.
85 * The action will be finalized only when uverbs_finalize_object is called.
86 */
87struct ib_uobject *uverbs_get_uobject_from_context(const struct uverbs_obj_type *type_attrs,
88 struct ib_ucontext *ucontext,
89 enum uverbs_obj_access access,
90 int id);
91int uverbs_finalize_object(struct ib_uobject *uobj,
92 enum uverbs_obj_access access,
93 bool commit);
94
78#endif /* RDMA_CORE_H */ 95#endif /* RDMA_CORE_H */
diff --git a/include/rdma/uverbs_ioctl.h b/include/rdma/uverbs_ioctl.h
new file mode 100644
index 000000000000..6885b92db4a8
--- /dev/null
+++ b/include/rdma/uverbs_ioctl.h
@@ -0,0 +1,52 @@
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_IOCTL_
34#define _UVERBS_IOCTL_
35
36#include <rdma/uverbs_types.h>
37
38/*
39 * =======================================
40 * Verbs action specifications
41 * =======================================
42 */
43
44enum uverbs_obj_access {
45 UVERBS_ACCESS_READ,
46 UVERBS_ACCESS_WRITE,
47 UVERBS_ACCESS_NEW,
48 UVERBS_ACCESS_DESTROY
49};
50
51#endif
52