diff options
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_verbs.c')
| -rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.c | 64 | 
1 files changed, 43 insertions, 21 deletions
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 932e56fcf77..d36c9a0bf1b 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -220,14 +220,14 @@ static int nes_bind_mw(struct ib_qp *ibqp, struct ib_mw *ibmw,  	if (nesqp->ibqp_state > IB_QPS_RTS)  		return -EINVAL; -		spin_lock_irqsave(&nesqp->lock, flags); +	spin_lock_irqsave(&nesqp->lock, flags);  	head = nesqp->hwqp.sq_head;  	qsize = nesqp->hwqp.sq_tail;  	/* Check for SQ overflow */  	if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) { -			spin_unlock_irqrestore(&nesqp->lock, flags); +		spin_unlock_irqrestore(&nesqp->lock, flags);  		return -EINVAL;  	} @@ -269,7 +269,7 @@ static int nes_bind_mw(struct ib_qp *ibqp, struct ib_mw *ibmw,  	nes_write32(nesdev->regs+NES_WQE_ALLOC,  			(1 << 24) | 0x00800000 | nesqp->hwqp.qp_id); -		spin_unlock_irqrestore(&nesqp->lock, flags); +	spin_unlock_irqrestore(&nesqp->lock, flags);  	return 0;  } @@ -349,7 +349,7 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd,  			if (nesfmr->nesmr.pbls_used > nesadapter->free_4kpbl) {  				spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);  				ret = -ENOMEM; -				goto failed_vpbl_alloc; +				goto failed_vpbl_avail;  			} else {  				nesadapter->free_4kpbl -= nesfmr->nesmr.pbls_used;  			} @@ -357,7 +357,7 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd,  			if (nesfmr->nesmr.pbls_used > nesadapter->free_256pbl) {  				spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);  				ret = -ENOMEM; -				goto failed_vpbl_alloc; +				goto failed_vpbl_avail;  			} else {  				nesadapter->free_256pbl -= nesfmr->nesmr.pbls_used;  			} @@ -391,14 +391,14 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd,  			goto failed_vpbl_alloc;  		} -		nesfmr->root_vpbl.leaf_vpbl = kzalloc(sizeof(*nesfmr->root_vpbl.leaf_vpbl)*1024, GFP_KERNEL); +		nesfmr->leaf_pbl_cnt = nesfmr->nesmr.pbls_used-1; +		nesfmr->root_vpbl.leaf_vpbl = kzalloc(sizeof(*nesfmr->root_vpbl.leaf_vpbl)*1024, GFP_ATOMIC);  		if (!nesfmr->root_vpbl.leaf_vpbl) {  			spin_unlock_irqrestore(&nesadapter->pbl_lock, flags);  			ret = -ENOMEM;  			goto failed_leaf_vpbl_alloc;  		} -		nesfmr->leaf_pbl_cnt = nesfmr->nesmr.pbls_used-1;  		nes_debug(NES_DBG_MR, "two level pbl, root_vpbl.pbl_vbase=%p"  				" leaf_pbl_cnt=%d root_vpbl.leaf_vpbl=%p\n",  				nesfmr->root_vpbl.pbl_vbase, nesfmr->leaf_pbl_cnt, nesfmr->root_vpbl.leaf_vpbl); @@ -519,6 +519,16 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd,  				nesfmr->root_vpbl.pbl_pbase);  	failed_vpbl_alloc: +	if (nesfmr->nesmr.pbls_used != 0) { +		spin_lock_irqsave(&nesadapter->pbl_lock, flags); +		if (nesfmr->nesmr.pbl_4k) +			nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used; +		else +			nesadapter->free_256pbl += nesfmr->nesmr.pbls_used; +		spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); +	} + +failed_vpbl_avail:  	kfree(nesfmr);  	failed_fmr_alloc: @@ -534,18 +544,14 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd,   */  static int nes_dealloc_fmr(struct ib_fmr *ibfmr)  { +	unsigned long flags;  	struct nes_mr *nesmr = to_nesmr_from_ibfmr(ibfmr);  	struct nes_fmr *nesfmr = to_nesfmr(nesmr);  	struct nes_vnic *nesvnic = to_nesvnic(ibfmr->device);  	struct nes_device *nesdev = nesvnic->nesdev; -	struct nes_mr temp_nesmr = *nesmr; +	struct nes_adapter *nesadapter = nesdev->nesadapter;  	int i = 0; -	temp_nesmr.ibmw.device = ibfmr->device; -	temp_nesmr.ibmw.pd = ibfmr->pd; -	temp_nesmr.ibmw.rkey = ibfmr->rkey; -	temp_nesmr.ibmw.uobject = NULL; -  	/* free the resources */  	if (nesfmr->leaf_pbl_cnt == 0) {  		/* single PBL case */ @@ -561,8 +567,24 @@ static int nes_dealloc_fmr(struct ib_fmr *ibfmr)  		pci_free_consistent(nesdev->pcidev, 8192, nesfmr->root_vpbl.pbl_vbase,  				nesfmr->root_vpbl.pbl_pbase);  	} +	nesmr->ibmw.device = ibfmr->device; +	nesmr->ibmw.pd = ibfmr->pd; +	nesmr->ibmw.rkey = ibfmr->rkey; +	nesmr->ibmw.uobject = NULL; -	return nes_dealloc_mw(&temp_nesmr.ibmw); +	if (nesfmr->nesmr.pbls_used != 0) { +		spin_lock_irqsave(&nesadapter->pbl_lock, flags); +		if (nesfmr->nesmr.pbl_4k) { +			nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used; +			WARN_ON(nesadapter->free_4kpbl > nesadapter->max_4kpbl); +		} else { +			nesadapter->free_256pbl += nesfmr->nesmr.pbls_used; +			WARN_ON(nesadapter->free_256pbl > nesadapter->max_256pbl); +		} +		spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); +	} + +	return nes_dealloc_mw(&nesmr->ibmw);  } @@ -1595,7 +1617,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries,  		nes_ucontext->mcrqf = req.mcrqf;  		if (nes_ucontext->mcrqf) {  			if (nes_ucontext->mcrqf & 0x80000000) -				nescq->hw_cq.cq_number = nesvnic->nic.qp_id + 12 + (nes_ucontext->mcrqf & 0xf) - 1; +				nescq->hw_cq.cq_number = nesvnic->nic.qp_id + 28 + 2 * ((nes_ucontext->mcrqf & 0xf) - 1);  			else if (nes_ucontext->mcrqf & 0x40000000)  				nescq->hw_cq.cq_number = nes_ucontext->mcrqf & 0xffff;  			else @@ -3212,7 +3234,7 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,  	if (nesqp->ibqp_state > IB_QPS_RTS)  		return -EINVAL; -		spin_lock_irqsave(&nesqp->lock, flags); +	spin_lock_irqsave(&nesqp->lock, flags);  	head = nesqp->hwqp.sq_head; @@ -3337,7 +3359,7 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,  				(counter << 24) | 0x00800000 | nesqp->hwqp.qp_id);  	} -		spin_unlock_irqrestore(&nesqp->lock, flags); +	spin_unlock_irqrestore(&nesqp->lock, flags);  	if (err)  		*bad_wr = ib_wr; @@ -3368,7 +3390,7 @@ static int nes_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr,  	if (nesqp->ibqp_state > IB_QPS_RTS)  		return -EINVAL; -		spin_lock_irqsave(&nesqp->lock, flags); +	spin_lock_irqsave(&nesqp->lock, flags);  	head = nesqp->hwqp.rq_head; @@ -3421,7 +3443,7 @@ static int nes_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr,  		nes_write32(nesdev->regs+NES_WQE_ALLOC, (counter<<24) | nesqp->hwqp.qp_id);  	} -		spin_unlock_irqrestore(&nesqp->lock, flags); +	spin_unlock_irqrestore(&nesqp->lock, flags);  	if (err)  		*bad_wr = ib_wr; @@ -3453,7 +3475,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)  	nes_debug(NES_DBG_CQ, "\n"); -		spin_lock_irqsave(&nescq->lock, flags); +	spin_lock_irqsave(&nescq->lock, flags);  	head = nescq->hw_cq.cq_head;  	cq_size = nescq->hw_cq.cq_size; @@ -3562,7 +3584,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry)  	nes_debug(NES_DBG_CQ, "Reporting %u completions for CQ%u.\n",  			cqe_count, nescq->hw_cq.cq_number); -		spin_unlock_irqrestore(&nescq->lock, flags); +	spin_unlock_irqrestore(&nescq->lock, flags);  	return cqe_count;  }  |