|
@@ -794,44 +794,6 @@ void uverbs_close_fd(struct file *f)
|
|
uverbs_uobject_put(uobj);
|
|
uverbs_uobject_put(uobj);
|
|
}
|
|
}
|
|
|
|
|
|
-static void ufile_disassociate_ucontext(struct ib_ucontext *ibcontext)
|
|
|
|
-{
|
|
|
|
- struct ib_device *ib_dev = ibcontext->device;
|
|
|
|
- struct task_struct *owning_process = NULL;
|
|
|
|
- struct mm_struct *owning_mm = NULL;
|
|
|
|
-
|
|
|
|
- owning_process = get_pid_task(ibcontext->tgid, PIDTYPE_PID);
|
|
|
|
- if (!owning_process)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- owning_mm = get_task_mm(owning_process);
|
|
|
|
- if (!owning_mm) {
|
|
|
|
- pr_info("no mm, disassociate ucontext is pending task termination\n");
|
|
|
|
- while (1) {
|
|
|
|
- put_task_struct(owning_process);
|
|
|
|
- usleep_range(1000, 2000);
|
|
|
|
- owning_process = get_pid_task(ibcontext->tgid,
|
|
|
|
- PIDTYPE_PID);
|
|
|
|
- if (!owning_process ||
|
|
|
|
- owning_process->state == TASK_DEAD) {
|
|
|
|
- pr_info("disassociate ucontext done, task was terminated\n");
|
|
|
|
- /* in case task was dead need to release the
|
|
|
|
- * task struct.
|
|
|
|
- */
|
|
|
|
- if (owning_process)
|
|
|
|
- put_task_struct(owning_process);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- down_write(&owning_mm->mmap_sem);
|
|
|
|
- ib_dev->disassociate_ucontext(ibcontext);
|
|
|
|
- up_write(&owning_mm->mmap_sem);
|
|
|
|
- mmput(owning_mm);
|
|
|
|
- put_task_struct(owning_process);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Drop the ucontext off the ufile and completely disconnect it from the
|
|
* Drop the ucontext off the ufile and completely disconnect it from the
|
|
* ib_device
|
|
* ib_device
|
|
@@ -840,22 +802,29 @@ static void ufile_destroy_ucontext(struct ib_uverbs_file *ufile,
|
|
enum rdma_remove_reason reason)
|
|
enum rdma_remove_reason reason)
|
|
{
|
|
{
|
|
struct ib_ucontext *ucontext = ufile->ucontext;
|
|
struct ib_ucontext *ucontext = ufile->ucontext;
|
|
|
|
+ struct ib_device *ib_dev = ucontext->device;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * If we are closing the FD then the user mmap VMAs must have
|
|
|
|
+ * already been destroyed as they hold on to the filep, otherwise
|
|
|
|
+ * they need to be zap'd.
|
|
|
|
+ */
|
|
if (reason == RDMA_REMOVE_DRIVER_REMOVE) {
|
|
if (reason == RDMA_REMOVE_DRIVER_REMOVE) {
|
|
uverbs_user_mmap_disassociate(ufile);
|
|
uverbs_user_mmap_disassociate(ufile);
|
|
- ufile_disassociate_ucontext(ucontext);
|
|
|
|
|
|
+ if (ib_dev->disassociate_ucontext)
|
|
|
|
+ ib_dev->disassociate_ucontext(ucontext);
|
|
}
|
|
}
|
|
|
|
|
|
put_pid(ucontext->tgid);
|
|
put_pid(ucontext->tgid);
|
|
- ib_rdmacg_uncharge(&ucontext->cg_obj, ucontext->device,
|
|
|
|
|
|
+ ib_rdmacg_uncharge(&ucontext->cg_obj, ib_dev,
|
|
RDMACG_RESOURCE_HCA_HANDLE);
|
|
RDMACG_RESOURCE_HCA_HANDLE);
|
|
|
|
|
|
/*
|
|
/*
|
|
* FIXME: Drivers are not permitted to fail dealloc_ucontext, remove
|
|
* FIXME: Drivers are not permitted to fail dealloc_ucontext, remove
|
|
* the error return.
|
|
* the error return.
|
|
*/
|
|
*/
|
|
- ret = ucontext->device->dealloc_ucontext(ucontext);
|
|
|
|
|
|
+ ret = ib_dev->dealloc_ucontext(ucontext);
|
|
WARN_ON(ret);
|
|
WARN_ON(ret);
|
|
|
|
|
|
ufile->ucontext = NULL;
|
|
ufile->ucontext = NULL;
|