RDMA/core: Allow the ioctl layer to abort a fully created uobject
While creating a uobject every create reaches a point where the uobject is fully initialized. For ioctls that go on to copy_to_user this means they need to open code the destruction of a fully created uobject - ie the RDMA_REMOVE_DESTROY sort of flow. Open coding this creates bugs, eg the CQ does not properly flush the events list when it does its error unwind. Provide a uverbs_finalize_uobj_create() function which indicates that the uobject is fully initialized and that abort should call to destroy_hw to destroy the uobj->object and related. Methods can call this function if they go on to have error cases after setting uobj->object. Once done those error cases can simply do return, without an error unwind. Link: https://lore.kernel.org/r/20200519072711.257271-2-leon@kernel.org Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
@@ -6187,26 +6187,20 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_VAR_OBJ_ALLOC)(
|
||||
mmap_offset = mlx5_entry_to_mmap_offset(entry);
|
||||
length = entry->rdma_entry.npages * PAGE_SIZE;
|
||||
uobj->object = entry;
|
||||
uverbs_finalize_uobj_create(attrs, MLX5_IB_ATTR_VAR_OBJ_ALLOC_HANDLE);
|
||||
|
||||
err = uverbs_copy_to(attrs, MLX5_IB_ATTR_VAR_OBJ_ALLOC_MMAP_OFFSET,
|
||||
&mmap_offset, sizeof(mmap_offset));
|
||||
if (err)
|
||||
goto err;
|
||||
return err;
|
||||
|
||||
err = uverbs_copy_to(attrs, MLX5_IB_ATTR_VAR_OBJ_ALLOC_PAGE_ID,
|
||||
&entry->page_idx, sizeof(entry->page_idx));
|
||||
if (err)
|
||||
goto err;
|
||||
return err;
|
||||
|
||||
err = uverbs_copy_to(attrs, MLX5_IB_ATTR_VAR_OBJ_ALLOC_MMAP_LENGTH,
|
||||
&length, sizeof(length));
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
rdma_user_mmap_entry_remove(&entry->rdma_entry);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -6320,26 +6314,20 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_UAR_OBJ_ALLOC)(
|
||||
mmap_offset = mlx5_entry_to_mmap_offset(entry);
|
||||
length = entry->rdma_entry.npages * PAGE_SIZE;
|
||||
uobj->object = entry;
|
||||
uverbs_finalize_uobj_create(attrs, MLX5_IB_ATTR_UAR_OBJ_ALLOC_HANDLE);
|
||||
|
||||
err = uverbs_copy_to(attrs, MLX5_IB_ATTR_UAR_OBJ_ALLOC_MMAP_OFFSET,
|
||||
&mmap_offset, sizeof(mmap_offset));
|
||||
if (err)
|
||||
goto err;
|
||||
return err;
|
||||
|
||||
err = uverbs_copy_to(attrs, MLX5_IB_ATTR_UAR_OBJ_ALLOC_PAGE_ID,
|
||||
&entry->page_idx, sizeof(entry->page_idx));
|
||||
if (err)
|
||||
goto err;
|
||||
return err;
|
||||
|
||||
err = uverbs_copy_to(attrs, MLX5_IB_ATTR_UAR_OBJ_ALLOC_MMAP_LENGTH,
|
||||
&length, sizeof(length));
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
rdma_user_mmap_entry_remove(&entry->rdma_entry);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user