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   */  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);  	} 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 {  	spinlock_t lock;  }; +struct disconn_work { +	struct work_struct    work; +	struct nes_qp         *nesqp; +}; +  struct iw_cm_id;  struct ietf_mpa_frame; @@ -127,7 +132,6 @@ struct nes_qp {  	void                  *allocated_buffer;  	struct iw_cm_id       *cm_id;  	struct workqueue_struct *wq; -	struct work_struct    disconn_work;  	struct nes_cq         *nesscq;  	struct nes_cq         *nesrcq;  	struct nes_pd         *nespd; @@ -165,7 +169,6 @@ struct nes_qp {  	u8                    hw_iwarp_state;  	u8                    flush_issued;  	u8                    hw_tcp_state; -	u8                    disconn_pending;  	u8                    destroyed;  };  #endif			/* NES_VERBS_H */  | 

