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 */ |
