diff options
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.c | 26 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.h | 7 |
2 files changed, 16 insertions, 17 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 | |||
2450 | */ | 2450 | */ |
2451 | int nes_cm_disconn(struct nes_qp *nesqp) | 2451 | int nes_cm_disconn(struct nes_qp *nesqp) |
2452 | { | 2452 | { |
2453 | unsigned long flags; | 2453 | struct disconn_work *work; |
2454 | 2454 | ||
2455 | spin_lock_irqsave(&nesqp->lock, flags); | 2455 | work = kzalloc(sizeof *work, GFP_ATOMIC); |
2456 | if (nesqp->disconn_pending == 0) { | 2456 | if (!work) |
2457 | nesqp->disconn_pending++; | 2457 | return -ENOMEM; /* Timer will clean up */ |
2458 | spin_unlock_irqrestore(&nesqp->lock, flags); | ||
2459 | nes_add_ref(&nesqp->ibqp); | ||
2460 | /* init our disconnect work element, to */ | ||
2461 | INIT_WORK(&nesqp->disconn_work, nes_disconnect_worker); | ||
2462 | |||
2463 | queue_work(g_cm_core->disconn_wq, &nesqp->disconn_work); | ||
2464 | } else | ||
2465 | spin_unlock_irqrestore(&nesqp->lock, flags); | ||
2466 | 2458 | ||
2459 | nes_add_ref(&nesqp->ibqp); | ||
2460 | work->nesqp = nesqp; | ||
2461 | INIT_WORK(&work->work, nes_disconnect_worker); | ||
2462 | queue_work(g_cm_core->disconn_wq, &work->work); | ||
2467 | return 0; | 2463 | return 0; |
2468 | } | 2464 | } |
2469 | 2465 | ||
@@ -2473,8 +2469,10 @@ int nes_cm_disconn(struct nes_qp *nesqp) | |||
2473 | */ | 2469 | */ |
2474 | static void nes_disconnect_worker(struct work_struct *work) | 2470 | static void nes_disconnect_worker(struct work_struct *work) |
2475 | { | 2471 | { |
2476 | struct nes_qp *nesqp = container_of(work, struct nes_qp, disconn_work); | 2472 | struct disconn_work *dwork = container_of(work, struct disconn_work, work); |
2473 | struct nes_qp *nesqp = dwork->nesqp; | ||
2477 | 2474 | ||
2475 | kfree(dwork); | ||
2478 | nes_debug(NES_DBG_CM, "processing AEQE id 0x%04X for QP%u.\n", | 2476 | nes_debug(NES_DBG_CM, "processing AEQE id 0x%04X for QP%u.\n", |
2479 | nesqp->last_aeq, nesqp->hwqp.qp_id); | 2477 | nesqp->last_aeq, nesqp->hwqp.qp_id); |
2480 | nes_cm_disconn_true(nesqp); | 2478 | nes_cm_disconn_true(nesqp); |
@@ -2557,7 +2555,6 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) | |||
2557 | spin_lock_irqsave(&nesqp->lock, flags); | 2555 | spin_lock_irqsave(&nesqp->lock, flags); |
2558 | } | 2556 | } |
2559 | 2557 | ||
2560 | nesqp->disconn_pending = 0; | ||
2561 | /* There might have been another AE while the lock was released */ | 2558 | /* There might have been another AE while the lock was released */ |
2562 | original_hw_tcp_state = nesqp->hw_tcp_state; | 2559 | original_hw_tcp_state = nesqp->hw_tcp_state; |
2563 | original_ibqp_state = nesqp->ibqp_state; | 2560 | original_ibqp_state = nesqp->ibqp_state; |
@@ -2610,7 +2607,6 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) | |||
2610 | } | 2607 | } |
2611 | } | 2608 | } |
2612 | } else { | 2609 | } else { |
2613 | nesqp->disconn_pending = 0; | ||
2614 | spin_unlock_irqrestore(&nesqp->lock, flags); | 2610 | spin_unlock_irqrestore(&nesqp->lock, flags); |
2615 | } | 2611 | } |
2616 | 2612 | ||
diff --git a/drivers/infiniband/hw/nes/nes_verbs.h b/drivers/infiniband/hw/nes/nes_verbs.h index 41c07f29f7c9..7df34fea2888 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.h +++ b/drivers/infiniband/hw/nes/nes_verbs.h | |||
@@ -119,6 +119,11 @@ struct nes_wq { | |||
119 | spinlock_t lock; | 119 | spinlock_t lock; |
120 | }; | 120 | }; |
121 | 121 | ||
122 | struct disconn_work { | ||
123 | struct work_struct work; | ||
124 | struct nes_qp *nesqp; | ||
125 | }; | ||
126 | |||
122 | struct iw_cm_id; | 127 | struct iw_cm_id; |
123 | struct ietf_mpa_frame; | 128 | struct ietf_mpa_frame; |
124 | 129 | ||
@@ -127,7 +132,6 @@ struct nes_qp { | |||
127 | void *allocated_buffer; | 132 | void *allocated_buffer; |
128 | struct iw_cm_id *cm_id; | 133 | struct iw_cm_id *cm_id; |
129 | struct workqueue_struct *wq; | 134 | struct workqueue_struct *wq; |
130 | struct work_struct disconn_work; | ||
131 | struct nes_cq *nesscq; | 135 | struct nes_cq *nesscq; |
132 | struct nes_cq *nesrcq; | 136 | struct nes_cq *nesrcq; |
133 | struct nes_pd *nespd; | 137 | struct nes_pd *nespd; |
@@ -165,7 +169,6 @@ struct nes_qp { | |||
165 | u8 hw_iwarp_state; | 169 | u8 hw_iwarp_state; |
166 | u8 flush_issued; | 170 | u8 flush_issued; |
167 | u8 hw_tcp_state; | 171 | u8 hw_tcp_state; |
168 | u8 disconn_pending; | ||
169 | u8 destroyed; | 172 | u8 destroyed; |
170 | }; | 173 | }; |
171 | #endif /* NES_VERBS_H */ | 174 | #endif /* NES_VERBS_H */ |