summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/nes/nes_cm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_cm.c')
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c26
1 files changed, 11 insertions, 15 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index fe08eb57c99f..d89bdee0cf55 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -2450,20 +2450,16 @@ static int nes_cm_init_tsa_conn(struct nes_qp *nesqp, struct nes_cm_node *cm_nod
*/
int nes_cm_disconn(struct nes_qp *nesqp)
{
- unsigned long flags;
+ struct disconn_work *work;
- spin_lock_irqsave(&nesqp->lock, flags);
- if (nesqp->disconn_pending == 0) {
- nesqp->disconn_pending++;
- spin_unlock_irqrestore(&nesqp->lock, flags);
- nes_add_ref(&nesqp->ibqp);
- /* init our disconnect work element, to */
- INIT_WORK(&nesqp->disconn_work, nes_disconnect_worker);
-
- queue_work(g_cm_core->disconn_wq, &nesqp->disconn_work);
- } else
- spin_unlock_irqrestore(&nesqp->lock, flags);
+ work = kzalloc(sizeof *work, GFP_ATOMIC);
+ if (!work)
+ return -ENOMEM; /* Timer will clean up */
+ nes_add_ref(&nesqp->ibqp);
+ work->nesqp = nesqp;
+ INIT_WORK(&work->work, nes_disconnect_worker);
+ queue_work(g_cm_core->disconn_wq, &work->work);
return 0;
}
@@ -2473,8 +2469,10 @@ int nes_cm_disconn(struct nes_qp *nesqp)
*/
static void nes_disconnect_worker(struct work_struct *work)
{
- struct nes_qp *nesqp = container_of(work, struct nes_qp, disconn_work);
+ struct disconn_work *dwork = container_of(work, struct disconn_work, work);
+ struct nes_qp *nesqp = dwork->nesqp;
+ kfree(dwork);
nes_debug(NES_DBG_CM, "processing AEQE id 0x%04X for QP%u.\n",
nesqp->last_aeq, nesqp->hwqp.qp_id);
nes_cm_disconn_true(nesqp);
@@ -2557,7 +2555,6 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp)
spin_lock_irqsave(&nesqp->lock, flags);
}
- nesqp->disconn_pending = 0;
/* There might have been another AE while the lock was released */
original_hw_tcp_state = nesqp->hw_tcp_state;
original_ibqp_state = nesqp->ibqp_state;
@@ -2610,7 +2607,6 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp)
}
}
} else {
- nesqp->disconn_pending = 0;
spin_unlock_irqrestore(&nesqp->lock, flags);
}