Commit efdd6f53 authored by Yishai Hadas's avatar Yishai Hadas Committed by Doug Ledford

IB/uverbs: Fix device cleanup

Uverbs device should be cleaned up only when there is no
potential usage of.

As part of ib_uverbs_remove_one which might be triggered upon reset flow
the device reference count is decreased as expected and leave the final
cleanup to the FDs that were opened.

Current code increases reference count upon opening a new command FD and
decreases it upon closing the file. The event FD is opened internally
and rely on the command FD by taking on it a reference count.

In case that the command FD was closed and just later the event FD we
may ensure that the device resources as of srcu are still alive as they
are still in use.

Fixing the above by moving the reference count decreasing to the place
where the command FD is really freed instead of doing that when it was
just closed.

fixes: 036b1063 ("IB/uverbs: Enable device removal when there are active user space applications")
Signed-off-by: default avatarYishai Hadas <yishaih@mellanox.com>
Reviewed-by: default avatarMatan Barak <matanb@mellanox.com>
Reviewed-by: default avatarJason Gunthorpe <jgunthorpe@obsidianresearch.com>
Tested-by: default avatarJason Gunthorpe <jgunthorpe@obsidianresearch.com>
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent f7a6cb7b
...@@ -250,6 +250,7 @@ void ib_uverbs_release_file(struct kref *ref) ...@@ -250,6 +250,7 @@ void ib_uverbs_release_file(struct kref *ref)
if (atomic_dec_and_test(&file->device->refcount)) if (atomic_dec_and_test(&file->device->refcount))
ib_uverbs_comp_dev(file->device); ib_uverbs_comp_dev(file->device);
kobject_put(&file->device->kobj);
kfree(file); kfree(file);
} }
...@@ -917,7 +918,6 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) ...@@ -917,7 +918,6 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
static int ib_uverbs_close(struct inode *inode, struct file *filp) static int ib_uverbs_close(struct inode *inode, struct file *filp)
{ {
struct ib_uverbs_file *file = filp->private_data; struct ib_uverbs_file *file = filp->private_data;
struct ib_uverbs_device *dev = file->device;
mutex_lock(&file->cleanup_mutex); mutex_lock(&file->cleanup_mutex);
if (file->ucontext) { if (file->ucontext) {
...@@ -939,7 +939,6 @@ static int ib_uverbs_close(struct inode *inode, struct file *filp) ...@@ -939,7 +939,6 @@ static int ib_uverbs_close(struct inode *inode, struct file *filp)
ib_uverbs_release_async_event_file); ib_uverbs_release_async_event_file);
kref_put(&file->ref, ib_uverbs_release_file); kref_put(&file->ref, ib_uverbs_release_file);
kobject_put(&dev->kobj);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment