return 0;
 }
 
+void _free_qp(struct kref *kref)
+{
+       struct c4iw_qp *qhp;
+
+       qhp = container_of(kref, struct c4iw_qp, kref);
+       PDBG("%s qhp %p\n", __func__, qhp);
+       kfree(qhp);
+}
+
 void c4iw_qp_add_ref(struct ib_qp *qp)
 {
        PDBG("%s ib_qp %p\n", __func__, qp);
-       atomic_inc(&(to_c4iw_qp(qp)->refcnt));
+       kref_get(&to_c4iw_qp(qp)->kref);
 }
 
 void c4iw_qp_rem_ref(struct ib_qp *qp)
 {
        PDBG("%s ib_qp %p\n", __func__, qp);
-       if (atomic_dec_and_test(&(to_c4iw_qp(qp)->refcnt)))
-               wake_up(&(to_c4iw_qp(qp)->wait));
+       kref_put(&to_c4iw_qp(qp)->kref, _free_qp);
 }
 
 static void add_to_fc_list(struct list_head *head, struct list_head *entry)
        wait_event(qhp->wait, !qhp->ep);
 
        remove_handle(rhp, &rhp->qpidr, qhp->wq.sq.qid);
-       atomic_dec(&qhp->refcnt);
-       wait_event(qhp->wait, !atomic_read(&qhp->refcnt));
 
        spin_lock_irq(&rhp->lock);
        if (!list_empty(&qhp->db_fc_entry))
        destroy_qp(&rhp->rdev, &qhp->wq,
                   ucontext ? &ucontext->uctx : &rhp->rdev.uctx);
 
+       c4iw_qp_rem_ref(ib_qp);
+
        PDBG("%s ib_qp %p qpid 0x%0x\n", __func__, ib_qp, qhp->wq.sq.qid);
-       kfree(qhp);
        return 0;
 }
 
        init_completion(&qhp->rq_drained);
        mutex_init(&qhp->mutex);
        init_waitqueue_head(&qhp->wait);
-       atomic_set(&qhp->refcnt, 1);
+       kref_init(&qhp->kref);
 
        ret = insert_handle(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
        if (ret)