Skip to content

Commit 1e7710f

Browse files
matanb10dledford
authored andcommitted
IB/core: Change completion channel to use the reworked objects schema
This patch adds the standard fd based type - completion_channel. The completion_channel is now prefixed with ib_uobject, similarly to the rest of the uobjects. This requires a few changes: (1) We define a new completion channel fd based object type. (2) completion_event and async_event are now two different types. This means they use different fops. (3) We release the completion_channel exactly as we release other idr based objects. (4) Since ib_uobjects are already kref-ed, we only add the kref to the async event. A fd object requires filling out several parameters. Its op pointer should point to uverbs_fd_ops and its size should be at least the size if ib_uobject. We use a macro to make the type declaration easier. Signed-off-by: Matan Barak <[email protected]> Reviewed-by: Yishai Hadas <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent cf8966b commit 1e7710f

File tree

6 files changed

+257
-148
lines changed

6 files changed

+257
-148
lines changed

drivers/infiniband/core/uverbs.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,25 +102,33 @@ struct ib_uverbs_device {
102102
};
103103

104104
struct ib_uverbs_event_file {
105-
struct kref ref;
106-
int is_async;
107-
struct ib_uverbs_file *uverbs_file;
108105
spinlock_t lock;
109106
int is_closed;
110107
wait_queue_head_t poll_wait;
111108
struct fasync_struct *async_queue;
112109
struct list_head event_list;
110+
};
111+
112+
struct ib_uverbs_async_event_file {
113+
struct ib_uverbs_event_file ev_file;
114+
struct ib_uverbs_file *uverbs_file;
115+
struct kref ref;
113116
struct list_head list;
114117
};
115118

119+
struct ib_uverbs_completion_event_file {
120+
struct ib_uobject_file uobj_file;
121+
struct ib_uverbs_event_file ev_file;
122+
};
123+
116124
struct ib_uverbs_file {
117125
struct kref ref;
118126
struct mutex mutex;
119127
struct mutex cleanup_mutex; /* protect cleanup */
120128
struct ib_uverbs_device *device;
121129
struct ib_ucontext *ucontext;
122130
struct ib_event_handler event_handler;
123-
struct ib_uverbs_event_file *async_file;
131+
struct ib_uverbs_async_event_file *async_file;
124132
struct list_head list;
125133
int is_closed;
126134

@@ -182,14 +190,14 @@ struct ib_ucq_object {
182190
u32 async_events_reported;
183191
};
184192

185-
struct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file,
186-
struct ib_device *ib_dev,
187-
int is_async);
193+
extern const struct file_operations uverbs_event_fops;
194+
void ib_uverbs_init_event_file(struct ib_uverbs_event_file *ev_file);
195+
struct file *ib_uverbs_alloc_async_event_file(struct ib_uverbs_file *uverbs_file,
196+
struct ib_device *ib_dev);
188197
void ib_uverbs_free_async_event_file(struct ib_uverbs_file *uverbs_file);
189-
struct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd);
190198

191199
void ib_uverbs_release_ucq(struct ib_uverbs_file *file,
192-
struct ib_uverbs_event_file *ev_file,
200+
struct ib_uverbs_completion_event_file *ev_file,
193201
struct ib_ucq_object *uobj);
194202
void ib_uverbs_release_uevent(struct ib_uverbs_file *file,
195203
struct ib_uevent_object *uobj);

drivers/infiniband/core/uverbs_cmd.c

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,24 @@
4747
#include "uverbs.h"
4848
#include "core_priv.h"
4949

50+
static struct ib_uverbs_completion_event_file *
51+
ib_uverbs_lookup_comp_file(int fd, struct ib_ucontext *context)
52+
{
53+
struct ib_uobject *uobj = uobj_get_read(uobj_get_type(comp_channel),
54+
fd, context);
55+
struct ib_uobject_file *uobj_file;
56+
57+
if (IS_ERR(uobj))
58+
return (void *)uobj;
59+
60+
uverbs_uobject_get(uobj);
61+
uobj_put_read(uobj);
62+
63+
uobj_file = container_of(uobj, struct ib_uobject_file, uobj);
64+
return container_of(uobj_file, struct ib_uverbs_completion_event_file,
65+
uobj_file);
66+
}
67+
5068
ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
5169
struct ib_device *ib_dev,
5270
const char __user *buf,
@@ -116,7 +134,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
116134
goto err_free;
117135
resp.async_fd = ret;
118136

119-
filp = ib_uverbs_alloc_event_file(file, ib_dev, 1);
137+
filp = ib_uverbs_alloc_async_event_file(file, ib_dev);
120138
if (IS_ERR(filp)) {
121139
ret = PTR_ERR(filp);
122140
goto err_fd;
@@ -908,34 +926,32 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
908926
{
909927
struct ib_uverbs_create_comp_channel cmd;
910928
struct ib_uverbs_create_comp_channel_resp resp;
911-
struct file *filp;
912-
int ret;
929+
struct ib_uobject *uobj;
930+
struct ib_uverbs_completion_event_file *ev_file;
913931

914932
if (out_len < sizeof resp)
915933
return -ENOSPC;
916934

917935
if (copy_from_user(&cmd, buf, sizeof cmd))
918936
return -EFAULT;
919937

920-
ret = get_unused_fd_flags(O_CLOEXEC);
921-
if (ret < 0)
922-
return ret;
923-
resp.fd = ret;
938+
uobj = uobj_alloc(uobj_get_type(comp_channel), file->ucontext);
939+
if (IS_ERR(uobj))
940+
return PTR_ERR(uobj);
924941

925-
filp = ib_uverbs_alloc_event_file(file, ib_dev, 0);
926-
if (IS_ERR(filp)) {
927-
put_unused_fd(resp.fd);
928-
return PTR_ERR(filp);
929-
}
942+
resp.fd = uobj->id;
943+
944+
ev_file = container_of(uobj, struct ib_uverbs_completion_event_file,
945+
uobj_file.uobj);
946+
ib_uverbs_init_event_file(&ev_file->ev_file);
930947

931948
if (copy_to_user((void __user *) (unsigned long) cmd.response,
932949
&resp, sizeof resp)) {
933-
put_unused_fd(resp.fd);
934-
fput(filp);
950+
uobj_alloc_abort(uobj);
935951
return -EFAULT;
936952
}
937953

938-
fd_install(resp.fd, filp);
954+
uobj_alloc_commit(uobj);
939955
return in_len;
940956
}
941957

@@ -953,7 +969,7 @@ static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file,
953969
void *context)
954970
{
955971
struct ib_ucq_object *obj;
956-
struct ib_uverbs_event_file *ev_file = NULL;
972+
struct ib_uverbs_completion_event_file *ev_file = NULL;
957973
struct ib_cq *cq;
958974
int ret;
959975
struct ib_uverbs_ex_create_cq_resp resp;
@@ -968,9 +984,10 @@ static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file,
968984
return obj;
969985

970986
if (cmd->comp_channel >= 0) {
971-
ev_file = ib_uverbs_lookup_comp_file(cmd->comp_channel);
972-
if (!ev_file) {
973-
ret = -EINVAL;
987+
ev_file = ib_uverbs_lookup_comp_file(cmd->comp_channel,
988+
file->ucontext);
989+
if (IS_ERR(ev_file)) {
990+
ret = PTR_ERR(ev_file);
974991
goto err;
975992
}
976993
}
@@ -998,7 +1015,7 @@ static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file,
9981015
cq->uobject = &obj->uobject;
9991016
cq->comp_handler = ib_uverbs_comp_handler;
10001017
cq->event_handler = ib_uverbs_cq_event_handler;
1001-
cq->cq_context = ev_file;
1018+
cq->cq_context = &ev_file->ev_file;
10021019
atomic_set(&cq->usecnt, 0);
10031020

10041021
obj->uobject.object = cq;

0 commit comments

Comments
 (0)