|
@@ -715,13 +715,32 @@ static int build_inv_stag(union t4_wr *wqe, struct ib_send_wr *wr, u8 *len16)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static void _free_qp(struct kref *kref)
|
|
|
+static void free_qp_work(struct work_struct *work)
|
|
|
+{
|
|
|
+ struct c4iw_ucontext *ucontext;
|
|
|
+ struct c4iw_qp *qhp;
|
|
|
+ struct c4iw_dev *rhp;
|
|
|
+
|
|
|
+ qhp = container_of(work, struct c4iw_qp, free_work);
|
|
|
+ ucontext = qhp->ucontext;
|
|
|
+ rhp = qhp->rhp;
|
|
|
+
|
|
|
+ PDBG("%s qhp %p ucontext %p\n", __func__, qhp, ucontext);
|
|
|
+ destroy_qp(&rhp->rdev, &qhp->wq,
|
|
|
+ ucontext ? &ucontext->uctx : &rhp->rdev.uctx);
|
|
|
+
|
|
|
+ if (ucontext)
|
|
|
+ c4iw_put_ucontext(ucontext);
|
|
|
+ kfree(qhp);
|
|
|
+}
|
|
|
+
|
|
|
+static void queue_qp_free(struct kref *kref)
|
|
|
{
|
|
|
struct c4iw_qp *qhp;
|
|
|
|
|
|
qhp = container_of(kref, struct c4iw_qp, kref);
|
|
|
PDBG("%s qhp %p\n", __func__, qhp);
|
|
|
- kfree(qhp);
|
|
|
+ queue_work(qhp->rhp->rdev.free_workq, &qhp->free_work);
|
|
|
}
|
|
|
|
|
|
void c4iw_qp_add_ref(struct ib_qp *qp)
|
|
@@ -733,7 +752,7 @@ void c4iw_qp_add_ref(struct ib_qp *qp)
|
|
|
void c4iw_qp_rem_ref(struct ib_qp *qp)
|
|
|
{
|
|
|
PDBG("%s ib_qp %p\n", __func__, qp);
|
|
|
- kref_put(&to_c4iw_qp(qp)->kref, _free_qp);
|
|
|
+ kref_put(&to_c4iw_qp(qp)->kref, queue_qp_free);
|
|
|
}
|
|
|
|
|
|
static void add_to_fc_list(struct list_head *head, struct list_head *entry)
|
|
@@ -1706,7 +1725,6 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
|
|
|
struct c4iw_dev *rhp;
|
|
|
struct c4iw_qp *qhp;
|
|
|
struct c4iw_qp_attributes attrs;
|
|
|
- struct c4iw_ucontext *ucontext;
|
|
|
|
|
|
qhp = to_c4iw_qp(ib_qp);
|
|
|
rhp = qhp->rhp;
|
|
@@ -1726,11 +1744,6 @@ int c4iw_destroy_qp(struct ib_qp *ib_qp)
|
|
|
spin_unlock_irq(&rhp->lock);
|
|
|
free_ird(rhp, qhp->attr.max_ird);
|
|
|
|
|
|
- ucontext = ib_qp->uobject ?
|
|
|
- to_c4iw_ucontext(ib_qp->uobject->context) : NULL;
|
|
|
- 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);
|
|
@@ -1829,6 +1842,7 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
|
|
|
mutex_init(&qhp->mutex);
|
|
|
init_waitqueue_head(&qhp->wait);
|
|
|
kref_init(&qhp->kref);
|
|
|
+ INIT_WORK(&qhp->free_work, free_qp_work);
|
|
|
|
|
|
ret = insert_handle(rhp, &rhp->qpidr, qhp, qhp->wq.sq.qid);
|
|
|
if (ret)
|
|
@@ -1915,6 +1929,9 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
|
|
|
ma_sync_key_mm->len = PAGE_SIZE;
|
|
|
insert_mmap(ucontext, ma_sync_key_mm);
|
|
|
}
|
|
|
+
|
|
|
+ c4iw_get_ucontext(ucontext);
|
|
|
+ qhp->ucontext = ucontext;
|
|
|
}
|
|
|
qhp->ibqp.qp_num = qhp->wq.sq.qid;
|
|
|
init_timer(&(qhp->timer));
|