aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYishai Hadas <yishaih@mellanox.com>2017-08-01 02:41:36 -0400
committerDoug Ledford <dledford@redhat.com>2017-08-04 14:24:05 -0400
commitefdd6f53b10aead0f5cf19a93dd3eb268ac0d991 (patch)
treeafda0c6456a483f38c5440eabdbe7557198df8ab
parentf7a6cb7b38c6845b26aaa8bbdf519ff6e3090831 (diff)
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: 036b10635739 ("IB/uverbs: Enable device removal when there are active user space applications") Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Reviewed-by: Matan Barak <matanb@mellanox.com> Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Tested-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Signed-off-by: Leon Romanovsky <leon@kernel.org> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/core/uverbs_main.c3
1 files changed, 1 insertions, 2 deletions
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 3d2609608f58..c023e2c81b8f 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -250,6 +250,7 @@ void ib_uverbs_release_file(struct kref *ref)
250 if (atomic_dec_and_test(&file->device->refcount)) 250 if (atomic_dec_and_test(&file->device->refcount))
251 ib_uverbs_comp_dev(file->device); 251 ib_uverbs_comp_dev(file->device);
252 252
253 kobject_put(&file->device->kobj);
253 kfree(file); 254 kfree(file);
254} 255}
255 256
@@ -917,7 +918,6 @@ err:
917static int ib_uverbs_close(struct inode *inode, struct file *filp) 918static int ib_uverbs_close(struct inode *inode, struct file *filp)
918{ 919{
919 struct ib_uverbs_file *file = filp->private_data; 920 struct ib_uverbs_file *file = filp->private_data;
920 struct ib_uverbs_device *dev = file->device;
921 921
922 mutex_lock(&file->cleanup_mutex); 922 mutex_lock(&file->cleanup_mutex);
923 if (file->ucontext) { 923 if (file->ucontext) {
@@ -939,7 +939,6 @@ static int ib_uverbs_close(struct inode *inode, struct file *filp)
939 ib_uverbs_release_async_event_file); 939 ib_uverbs_release_async_event_file);
940 940
941 kref_put(&file->ref, ib_uverbs_release_file); 941 kref_put(&file->ref, ib_uverbs_release_file);
942 kobject_put(&dev->kobj);
943 942
944 return 0; 943 return 0;
945} 944}