diff options
author | Jason Gunthorpe <jgg@mellanox.com> | 2018-07-25 21:40:20 -0600 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2018-08-01 14:55:48 -0600 |
commit | 0f50d88a6e9ae6d9dd14ed1a7d6b309280a9c23b (patch) | |
tree | c0fb171864e582367f1de93f98320ec21a117465 /drivers/infiniband/core/uverbs_main.c | |
parent | a9b66d6453d70ee01f11bdae40d68996cee7474a (diff) | |
download | linux-0f50d88a6e9ae6d9dd14ed1a7d6b309280a9c23b.tar.gz linux-0f50d88a6e9ae6d9dd14ed1a7d6b309280a9c23b.tar.bz2 linux-0f50d88a6e9ae6d9dd14ed1a7d6b309280a9c23b.zip |
IB/uverbs: Allow all DESTROY commands to succeed after disassociate
The disassociate function was broken by design because it failed all
commands. This prevents userspace from calling destroy on a uobject after
it has detected a device fatal error and thus reclaiming the resources in
userspace is prevented.
This fix is now straightforward, when anything destroys a uobject that is
not the user the object remains on the IDR with a NULL context and object
pointer. All lookup locking modes other than DESTROY will fail. When the
user ultimately calls the destroy function it is simply dropped from the
IDR while any related information is returned.
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'drivers/infiniband/core/uverbs_main.c')
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index a3213245aab2..6f62146e9738 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -253,6 +253,8 @@ void ib_uverbs_release_file(struct kref *ref) struct ib_device *ib_dev; int srcu_key; + release_ufile_idr_uobject(file); + srcu_key = srcu_read_lock(&file->device->disassociate_srcu); ib_dev = srcu_dereference(file->device->ib_dev, &file->device->disassociate_srcu); @@ -867,8 +869,6 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) } file->device = dev; - spin_lock_init(&file->idr_lock); - idr_init(&file->idr); kref_init(&file->ref); mutex_init(&file->ucontext_lock); @@ -885,6 +885,8 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) file->uverbs_cmd_mask = ib_dev->uverbs_cmd_mask; file->uverbs_ex_cmd_mask = ib_dev->uverbs_ex_cmd_mask; + setup_ufile_idr_uobject(file); + return nonseekable_open(inode, filp); err_module: @@ -904,7 +906,6 @@ static int ib_uverbs_close(struct inode *inode, struct file *filp) struct ib_uverbs_file *file = filp->private_data; uverbs_destroy_ufile_hw(file, RDMA_REMOVE_CLOSE); - idr_destroy(&file->idr); mutex_lock(&file->device->lists_mutex); if (!file->is_closed) { |