diff options
| -rw-r--r-- | drivers/infiniband/hw/ehca/ehca_irq.c | 44 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ehca/ehca_qp.c | 5 | ||||
| -rw-r--r-- | drivers/infiniband/hw/ipath/ipath_ruc.c | 10 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx4/mr.c | 1 | ||||
| -rw-r--r-- | drivers/infiniband/hw/nes/nes.c | 16 | ||||
| -rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.h | 1 | ||||
| -rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.c | 64 | ||||
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 6 | ||||
| -rw-r--r-- | drivers/net/mlx4/mlx4.h | 9 | 
9 files changed, 106 insertions, 50 deletions
| diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index cb55be04442c..757035ea246f 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c @@ -359,36 +359,48 @@ static void notify_port_conf_change(struct ehca_shca *shca, int port_num)  	*old_attr = new_attr;  } +/* replay modify_qp for sqps -- return 0 if all is well, 1 if AQP1 destroyed */ +static int replay_modify_qp(struct ehca_sport *sport) +{ +	int aqp1_destroyed; +	unsigned long flags; + +	spin_lock_irqsave(&sport->mod_sqp_lock, flags); + +	aqp1_destroyed = !sport->ibqp_sqp[IB_QPT_GSI]; + +	if (sport->ibqp_sqp[IB_QPT_SMI]) +		ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_SMI]); +	if (!aqp1_destroyed) +		ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_GSI]); + +	spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); + +	return aqp1_destroyed; +} +  static void parse_ec(struct ehca_shca *shca, u64 eqe)  {  	u8 ec   = EHCA_BMASK_GET(NEQE_EVENT_CODE, eqe);  	u8 port = EHCA_BMASK_GET(NEQE_PORT_NUMBER, eqe);  	u8 spec_event;  	struct ehca_sport *sport = &shca->sport[port - 1]; -	unsigned long flags;  	switch (ec) {  	case 0x30: /* port availability change */  		if (EHCA_BMASK_GET(NEQE_PORT_AVAILABILITY, eqe)) { -			int suppress_event; -			/* replay modify_qp for sqps */ -			spin_lock_irqsave(&sport->mod_sqp_lock, flags); -			suppress_event = !sport->ibqp_sqp[IB_QPT_GSI]; -			if (sport->ibqp_sqp[IB_QPT_SMI]) -				ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_SMI]); -			if (!suppress_event) -				ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_GSI]); -			spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); - -			/* AQP1 was destroyed, ignore this event */ -			if (suppress_event) -				break; +			/* only replay modify_qp calls in autodetect mode; +			 * if AQP1 was destroyed, the port is already down +			 * again and we can drop the event. +			 */ +			if (ehca_nr_ports < 0) +				if (replay_modify_qp(sport)) +					break;  			sport->port_state = IB_PORT_ACTIVE;  			dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE,  					    "is active"); -			ehca_query_sma_attr(shca, port, -					    &sport->saved_attr); +			ehca_query_sma_attr(shca, port, &sport->saved_attr);  		} else {  			sport->port_state = IB_PORT_DOWN;  			dispatch_port_event(shca, port, IB_EVENT_PORT_ERR, diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 4d54b9f64567..9e05ee2db39b 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c @@ -860,6 +860,11 @@ static struct ehca_qp *internal_create_qp(  	if (qp_type == IB_QPT_GSI) {  		h_ret = ehca_define_sqp(shca, my_qp, init_attr);  		if (h_ret != H_SUCCESS) { +			kfree(my_qp->mod_qp_parm); +			my_qp->mod_qp_parm = NULL; +			/* the QP pointer is no longer valid */ +			shca->sport[init_attr->port_num - 1].ibqp_sqp[qp_type] = +				NULL;  			ret = ehca2ib_return_code(h_ret);  			goto create_qp_exit6;  		} diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c index fc0f6d9e6030..2296832f94da 100644 --- a/drivers/infiniband/hw/ipath/ipath_ruc.c +++ b/drivers/infiniband/hw/ipath/ipath_ruc.c @@ -156,7 +156,7 @@ bail:  /**   * ipath_get_rwqe - copy the next RWQE into the QP's RWQE   * @qp: the QP - * @wr_id_only: update wr_id only, not SGEs + * @wr_id_only: update qp->r_wr_id only, not qp->r_sge   *   * Return 0 if no RWQE is available, otherwise return 1.   * @@ -173,8 +173,6 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only)  	u32 tail;  	int ret; -	qp->r_sge.sg_list = qp->r_sg_list; -  	if (qp->ibqp.srq) {  		srq = to_isrq(qp->ibqp.srq);  		handler = srq->ibsrq.event_handler; @@ -206,8 +204,10 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only)  		wqe = get_rwqe_ptr(rq, tail);  		if (++tail >= rq->size)  			tail = 0; -	} while (!wr_id_only && !ipath_init_sge(qp, wqe, &qp->r_len, -						&qp->r_sge)); +		if (wr_id_only) +			break; +		qp->r_sge.sg_list = qp->r_sg_list; +	} while (!ipath_init_sge(qp, wqe, &qp->r_len, &qp->r_sge));  	qp->r_wr_id = wqe->wr_id;  	wq->tail = tail; diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 87f5c5a87b98..8e4d26d56a95 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c @@ -205,6 +205,7 @@ struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd,  		goto err_mr;  	mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key; +	mr->umem = NULL;  	return &mr->ibmr; diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index a2b04d62b1a4..aa1dc41f04c8 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c @@ -95,6 +95,10 @@ unsigned int wqm_quanta = 0x10000;  module_param(wqm_quanta, int, 0644);  MODULE_PARM_DESC(wqm_quanta, "WQM quanta"); +static unsigned int limit_maxrdreqsz; +module_param(limit_maxrdreqsz, bool, 0644); +MODULE_PARM_DESC(limit_maxrdreqsz, "Limit max read request size to 256 Bytes"); +  LIST_HEAD(nes_adapter_list);  static LIST_HEAD(nes_dev_list); @@ -588,6 +592,18 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i  						nesdev->nesadapter->port_count;  	} +	if ((limit_maxrdreqsz || +	     ((nesdev->nesadapter->phy_type[0] == NES_PHY_TYPE_GLADIUS) && +	      (hw_rev == NE020_REV1))) && +	    (pcie_get_readrq(pcidev) > 256)) { +		if (pcie_set_readrq(pcidev, 256)) +			printk(KERN_ERR PFX "Unable to set max read request" +				" to 256 bytes\n"); +		else +			nes_debug(NES_DBG_INIT, "Max read request size set" +				" to 256 bytes\n"); +	} +  	tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev);  	/* bring up the Control QP */ diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 610b9d859597..bc0b4de04450 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h @@ -40,6 +40,7 @@  #define NES_PHY_TYPE_ARGUS     4  #define NES_PHY_TYPE_PUMA_1G   5  #define NES_PHY_TYPE_PUMA_10G  6 +#define NES_PHY_TYPE_GLADIUS   7  #define NES_MULTICAST_PF_MAX 8 diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 932e56fcf774..d36c9a0bf1bb 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;  } diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index fddded7900d1..85257f6b9576 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -106,12 +106,13 @@ int ipoib_open(struct net_device *dev)  	ipoib_dbg(priv, "bringing up interface\n"); -	napi_enable(&priv->napi);  	set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags);  	if (ipoib_pkey_dev_delay_open(dev))  		return 0; +	napi_enable(&priv->napi); +  	if (ipoib_ib_dev_open(dev)) {  		napi_disable(&priv->napi);  		return -EINVAL; @@ -546,6 +547,7 @@ static int path_rec_start(struct net_device *dev,  	if (path->query_id < 0) {  		ipoib_warn(priv, "ib_sa_path_rec_get failed: %d\n", path->query_id);  		path->query = NULL; +		complete(&path->done);  		return path->query_id;  	} @@ -662,7 +664,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,  			skb_push(skb, sizeof *phdr);  			__skb_queue_tail(&path->queue, skb); -			if (path_rec_start(dev, path)) { +			if (!path->query && path_rec_start(dev, path)) {  				spin_unlock_irqrestore(&priv->lock, flags);  				path_free(dev, path);  				return; diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index fa431fad0eec..56a2e213fe62 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h @@ -87,6 +87,9 @@ enum {  #ifdef CONFIG_MLX4_DEBUG  extern int mlx4_debug_level; +#else /* CONFIG_MLX4_DEBUG */ +#define mlx4_debug_level	(0) +#endif /* CONFIG_MLX4_DEBUG */  #define mlx4_dbg(mdev, format, arg...)					\  	do {								\ @@ -94,12 +97,6 @@ extern int mlx4_debug_level;  			dev_printk(KERN_DEBUG, &mdev->pdev->dev, format, ## arg); \  	} while (0) -#else /* CONFIG_MLX4_DEBUG */ - -#define mlx4_dbg(mdev, format, arg...) do { (void) mdev; } while (0) - -#endif /* CONFIG_MLX4_DEBUG */ -  #define mlx4_err(mdev, format, arg...) \  	dev_err(&mdev->pdev->dev, format, ## arg)  #define mlx4_info(mdev, format, arg...) \ | 
