aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c')
-rw-r--r--drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
index 10420a18d02f..4059308e1454 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
@@ -246,7 +246,7 @@ struct ib_qp *pvrdma_create_qp(struct ib_pd *pd,
246 spin_lock_init(&qp->rq.lock); 246 spin_lock_init(&qp->rq.lock);
247 mutex_init(&qp->mutex); 247 mutex_init(&qp->mutex);
248 atomic_set(&qp->refcnt, 1); 248 atomic_set(&qp->refcnt, 1);
249 init_waitqueue_head(&qp->wait); 249 init_completion(&qp->free);
250 250
251 qp->state = IB_QPS_RESET; 251 qp->state = IB_QPS_RESET;
252 252
@@ -428,8 +428,16 @@ static void pvrdma_free_qp(struct pvrdma_qp *qp)
428 428
429 pvrdma_unlock_cqs(scq, rcq, &scq_flags, &rcq_flags); 429 pvrdma_unlock_cqs(scq, rcq, &scq_flags, &rcq_flags);
430 430
431 atomic_dec(&qp->refcnt); 431 if (atomic_dec_and_test(&qp->refcnt))
432 wait_event(qp->wait, !atomic_read(&qp->refcnt)); 432 complete(&qp->free);
433 wait_for_completion(&qp->free);
434
435 if (!qp->is_kernel) {
436 if (qp->rumem)
437 ib_umem_release(qp->rumem);
438 if (qp->sumem)
439 ib_umem_release(qp->sumem);
440 }
433 441
434 pvrdma_page_dir_cleanup(dev, &qp->pdir); 442 pvrdma_page_dir_cleanup(dev, &qp->pdir);
435 443