diff options
Diffstat (limited to 'drivers/infiniband/core')
| -rw-r--r-- | drivers/infiniband/core/addr.c | 15 | ||||
| -rw-r--r-- | drivers/infiniband/core/cq.c | 21 | ||||
| -rw-r--r-- | drivers/infiniband/core/device.c | 6 | ||||
| -rw-r--r-- | drivers/infiniband/core/sa_query.c | 7 | ||||
| -rw-r--r-- | drivers/infiniband/core/ucma.c | 6 | 
5 files changed, 29 insertions, 26 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index a5b4cf030c11..9183d148d644 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -550,18 +550,13 @@ static int addr_resolve(struct sockaddr *src_in,  		dst_release(dst);  	} -	if (ndev->flags & IFF_LOOPBACK) { -		ret = rdma_translate_ip(dst_in, addr); -		/* -		 * Put the loopback device and get the translated -		 * device instead. -		 */ +	if (ndev) { +		if (ndev->flags & IFF_LOOPBACK) +			ret = rdma_translate_ip(dst_in, addr); +		else +			addr->bound_dev_if = ndev->ifindex;  		dev_put(ndev); -		ndev = dev_get_by_index(addr->net, addr->bound_dev_if); -	} else { -		addr->bound_dev_if = ndev->ifindex;  	} -	dev_put(ndev);  	return ret;  } diff --git a/drivers/infiniband/core/cq.c b/drivers/infiniband/core/cq.c index bc79ca8215d7..af5ad6a56ae4 100644 --- a/drivers/infiniband/core/cq.c +++ b/drivers/infiniband/core/cq.c @@ -17,6 +17,7 @@  /* # of WCs to poll for with a single call to ib_poll_cq */  #define IB_POLL_BATCH			16 +#define IB_POLL_BATCH_DIRECT		8  /* # of WCs to iterate over before yielding */  #define IB_POLL_BUDGET_IRQ		256 @@ -25,18 +26,18 @@  #define IB_POLL_FLAGS \  	(IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS) -static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc) +static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *wcs, +			   int batch)  {  	int i, n, completed = 0; -	struct ib_wc *wcs = poll_wc ? : cq->wc;  	/*  	 * budget might be (-1) if the caller does not  	 * want to bound this call, thus we need unsigned  	 * minimum here.  	 */ -	while ((n = ib_poll_cq(cq, min_t(u32, IB_POLL_BATCH, -			budget - completed), wcs)) > 0) { +	while ((n = ib_poll_cq(cq, min_t(u32, batch, +					 budget - completed), wcs)) > 0) {  		for (i = 0; i < n; i++) {  			struct ib_wc *wc = &wcs[i]; @@ -48,8 +49,7 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc)  		completed += n; -		if (n != IB_POLL_BATCH || -		    (budget != -1 && completed >= budget)) +		if (n != batch || (budget != -1 && completed >= budget))  			break;  	} @@ -72,9 +72,9 @@ static int __ib_process_cq(struct ib_cq *cq, int budget, struct ib_wc *poll_wc)   */  int ib_process_cq_direct(struct ib_cq *cq, int budget)  { -	struct ib_wc wcs[IB_POLL_BATCH]; +	struct ib_wc wcs[IB_POLL_BATCH_DIRECT]; -	return __ib_process_cq(cq, budget, wcs); +	return __ib_process_cq(cq, budget, wcs, IB_POLL_BATCH_DIRECT);  }  EXPORT_SYMBOL(ib_process_cq_direct); @@ -88,7 +88,7 @@ static int ib_poll_handler(struct irq_poll *iop, int budget)  	struct ib_cq *cq = container_of(iop, struct ib_cq, iop);  	int completed; -	completed = __ib_process_cq(cq, budget, NULL); +	completed = __ib_process_cq(cq, budget, cq->wc, IB_POLL_BATCH);  	if (completed < budget) {  		irq_poll_complete(&cq->iop);  		if (ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0) @@ -108,7 +108,8 @@ static void ib_cq_poll_work(struct work_struct *work)  	struct ib_cq *cq = container_of(work, struct ib_cq, work);  	int completed; -	completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, NULL); +	completed = __ib_process_cq(cq, IB_POLL_BUDGET_WORKQUEUE, cq->wc, +				    IB_POLL_BATCH);  	if (completed >= IB_POLL_BUDGET_WORKQUEUE ||  	    ib_req_notify_cq(cq, IB_POLL_FLAGS) > 0)  		queue_work(ib_comp_wq, &cq->work); diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index e8010e73a1cf..bb065c9449be 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -536,14 +536,14 @@ int ib_register_device(struct ib_device *device,  	ret = device->query_device(device, &device->attrs, &uhw);  	if (ret) {  		pr_warn("Couldn't query the device attributes\n"); -		goto cache_cleanup; +		goto cg_cleanup;  	}  	ret = ib_device_register_sysfs(device, port_callback);  	if (ret) {  		pr_warn("Couldn't register device %s with driver model\n",  			device->name); -		goto cache_cleanup; +		goto cg_cleanup;  	}  	device->reg_state = IB_DEV_REGISTERED; @@ -559,6 +559,8 @@ int ib_register_device(struct ib_device *device,  	mutex_unlock(&device_mutex);  	return 0; +cg_cleanup: +	ib_device_unregister_rdmacg(device);  cache_cleanup:  	ib_cache_cleanup_one(device);  	ib_cache_release_one(device); diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 8cf15d4a8ac4..9f029a1ca5ea 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -1291,10 +1291,9 @@ int ib_init_ah_attr_from_path(struct ib_device *device, u8 port_num,  		resolved_dev = dev_get_by_index(dev_addr.net,  						dev_addr.bound_dev_if); -		if (resolved_dev->flags & IFF_LOOPBACK) { -			dev_put(resolved_dev); -			resolved_dev = idev; -			dev_hold(resolved_dev); +		if (!resolved_dev) { +			dev_put(idev); +			return -ENODEV;  		}  		ndev = ib_get_ndev_from_path(rec);  		rcu_read_lock(); diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index f015f1bf88c9..3a9d0f5b5881 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -1149,6 +1149,9 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file,  	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))  		return -EFAULT; +	if (cmd.qp_state > IB_QPS_ERR) +		return -EINVAL; +  	ctx = ucma_get_ctx(file, cmd.id);  	if (IS_ERR(ctx))  		return PTR_ERR(ctx); @@ -1294,6 +1297,9 @@ static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf,  	if (IS_ERR(ctx))  		return PTR_ERR(ctx); +	if (unlikely(cmd.optval > KMALLOC_MAX_SIZE)) +		return -EINVAL; +  	optval = memdup_user((void __user *) (unsigned long) cmd.optval,  			     cmd.optlen);  	if (IS_ERR(optval)) {  | 
