diff options
Diffstat (limited to 'drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c')
-rw-r--r-- | drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c | 14 |
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 | ||