Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40eb0066 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband

* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband:
  RDMA/addr: Use client registration to fix module unload race
  IB/mthca: Fix MAD extended header format for MAD_IFC firmware command
  IB/uverbs: Return sq_draining value in query_qp response
  IB/amso1100: Fix incorrect pr_debug()
  IB/amso1100: Use dma_alloc_coherent() instead of kmalloc/dma_map_single
  IB/ehca: Fix eHCA driver compilation for uniprocessor
  RDMA/cma: rdma_bind_addr() leaks a cma_dev reference count
  IB/iser: Start connection after enabling iSER
parents e957b00a 7a118df3
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ struct addr_req {
	struct sockaddr src_addr;
	struct sockaddr dst_addr;
	struct rdma_dev_addr *addr;
	struct rdma_addr_client *client;
	void *context;
	void (*callback)(int status, struct sockaddr *src_addr,
			 struct rdma_dev_addr *addr, void *context);
@@ -61,6 +62,26 @@ static LIST_HEAD(req_list);
static DECLARE_WORK(work, process_req, NULL);
static struct workqueue_struct *addr_wq;

void rdma_addr_register_client(struct rdma_addr_client *client)
{
	atomic_set(&client->refcount, 1);
	init_completion(&client->comp);
}
EXPORT_SYMBOL(rdma_addr_register_client);

static inline void put_client(struct rdma_addr_client *client)
{
	if (atomic_dec_and_test(&client->refcount))
		complete(&client->comp);
}

void rdma_addr_unregister_client(struct rdma_addr_client *client)
{
	put_client(client);
	wait_for_completion(&client->comp);
}
EXPORT_SYMBOL(rdma_addr_unregister_client);

int rdma_copy_addr(struct rdma_dev_addr *dev_addr, struct net_device *dev,
		     const unsigned char *dst_dev_addr)
{
@@ -229,6 +250,7 @@ static void process_req(void *data)
		list_del(&req->list);
		req->callback(req->status, &req->src_addr, req->addr,
			      req->context);
		put_client(req->client);
		kfree(req);
	}
}
@@ -264,7 +286,8 @@ static int addr_resolve_local(struct sockaddr_in *src_in,
	return ret;
}

int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr,
int rdma_resolve_ip(struct rdma_addr_client *client,
		    struct sockaddr *src_addr, struct sockaddr *dst_addr,
		    struct rdma_dev_addr *addr, int timeout_ms,
		    void (*callback)(int status, struct sockaddr *src_addr,
				     struct rdma_dev_addr *addr, void *context),
@@ -285,6 +308,8 @@ int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr,
	req->addr = addr;
	req->callback = callback;
	req->context = context;
	req->client = client;
	atomic_inc(&client->refcount);

	src_in = (struct sockaddr_in *) &req->src_addr;
	dst_in = (struct sockaddr_in *) &req->dst_addr;
@@ -305,6 +330,7 @@ int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr,
		break;
	default:
		ret = req->status;
		atomic_dec(&client->refcount);
		kfree(req);
		break;
	}
+21 −10
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ static struct ib_client cma_client = {
};

static struct ib_sa_client sa_client;
static struct rdma_addr_client addr_client;
static LIST_HEAD(dev_list);
static LIST_HEAD(listen_any_list);
static DEFINE_MUTEX(lock);
@@ -1625,8 +1626,8 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr,
	if (cma_any_addr(dst_addr))
		ret = cma_resolve_loopback(id_priv);
	else
		ret = rdma_resolve_ip(&id->route.addr.src_addr, dst_addr,
				      &id->route.addr.dev_addr,
		ret = rdma_resolve_ip(&addr_client, &id->route.addr.src_addr,
				      dst_addr, &id->route.addr.dev_addr,
				      timeout_ms, addr_handler, id_priv);
	if (ret)
		goto err;
@@ -1762,22 +1763,29 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)

	if (!cma_any_addr(addr)) {
		ret = rdma_translate_ip(addr, &id->route.addr.dev_addr);
		if (!ret) {
		if (ret)
			goto err1;

		mutex_lock(&lock);
		ret = cma_acquire_dev(id_priv);
		mutex_unlock(&lock);
		}
		if (ret)
			goto err;
			goto err1;
	}

	memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr));
	ret = cma_get_port(id_priv);
	if (ret)
		goto err;
		goto err2;

	return 0;
err:
err2:
	if (!cma_any_addr(addr)) {
		mutex_lock(&lock);
		cma_detach_from_dev(id_priv);
		mutex_unlock(&lock);
	}
err1:
	cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE);
	return ret;
}
@@ -2210,6 +2218,7 @@ static int cma_init(void)
		return -ENOMEM;

	ib_sa_register_client(&sa_client);
	rdma_addr_register_client(&addr_client);

	ret = ib_register_client(&cma_client);
	if (ret)
@@ -2217,6 +2226,7 @@ static int cma_init(void)
	return 0;

err:
	rdma_addr_unregister_client(&addr_client);
	ib_sa_unregister_client(&sa_client);
	destroy_workqueue(cma_wq);
	return ret;
@@ -2225,6 +2235,7 @@ err:
static void cma_cleanup(void)
{
	ib_unregister_client(&cma_client);
	rdma_addr_unregister_client(&addr_client);
	ib_sa_unregister_client(&sa_client);
	destroy_workqueue(cma_wq);
	idr_destroy(&sdp_ps);
+1 −1
Original line number Diff line number Diff line
@@ -1214,7 +1214,7 @@ ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file,
	resp.qp_access_flags        = attr->qp_access_flags;
	resp.pkey_index             = attr->pkey_index;
	resp.alt_pkey_index         = attr->alt_pkey_index;
	resp.en_sqd_async_notify    = attr->en_sqd_async_notify;
	resp.sq_draining            = attr->sq_draining;
	resp.max_rd_atomic          = attr->max_rd_atomic;
	resp.max_dest_rd_atomic     = attr->max_dest_rd_atomic;
	resp.min_rnr_timer          = attr->min_rnr_timer;
+6 −7
Original line number Diff line number Diff line
@@ -42,13 +42,14 @@ static int c2_alloc_mqsp_chunk(struct c2_dev *c2dev, gfp_t gfp_mask,
{
	int i;
	struct sp_chunk *new_head;
	dma_addr_t dma_addr;

	new_head = (struct sp_chunk *) __get_free_page(gfp_mask);
	new_head = dma_alloc_coherent(&c2dev->pcidev->dev, PAGE_SIZE,
				      &dma_addr, gfp_mask);
	if (new_head == NULL)
		return -ENOMEM;

	new_head->dma_addr = dma_map_single(c2dev->ibdev.dma_device, new_head,
					    PAGE_SIZE, DMA_FROM_DEVICE);
	new_head->dma_addr = dma_addr;
	pci_unmap_addr_set(new_head, mapping, new_head->dma_addr);

	new_head->next = NULL;
@@ -80,10 +81,8 @@ void c2_free_mqsp_pool(struct c2_dev *c2dev, struct sp_chunk *root)

	while (root) {
		next = root->next;
		dma_unmap_single(c2dev->ibdev.dma_device,
				 pci_unmap_addr(root, mapping), PAGE_SIZE,
			         DMA_FROM_DEVICE);
		__free_page((struct page *) root);
		dma_free_coherent(&c2dev->pcidev->dev, PAGE_SIZE, root,
				  pci_unmap_addr(root, mapping));
		root = next;
	}
}
+6 −12
Original line number Diff line number Diff line
@@ -246,20 +246,17 @@ int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify)

static void c2_free_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq)
{

	dma_unmap_single(c2dev->ibdev.dma_device, pci_unmap_addr(mq, mapping),
			 mq->q_size * mq->msg_size, DMA_FROM_DEVICE);
	free_pages((unsigned long) mq->msg_pool.host,
		   get_order(mq->q_size * mq->msg_size));
	dma_free_coherent(&c2dev->pcidev->dev, mq->q_size * mq->msg_size,
			  mq->msg_pool.host, pci_unmap_addr(mq, mapping));
}

static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, int q_size,
			   int msg_size)
{
	unsigned long pool_start;
	u8 *pool_start;

	pool_start = __get_free_pages(GFP_KERNEL,
				      get_order(q_size * msg_size));
	pool_start = dma_alloc_coherent(&c2dev->pcidev->dev, q_size * msg_size,
					&mq->host_dma, GFP_KERNEL);
	if (!pool_start)
		return -ENOMEM;

@@ -267,13 +264,10 @@ static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, int q_size,
		       0,		/* index (currently unknown) */
		       q_size,
		       msg_size,
		       (u8 *) pool_start,
		       pool_start,
		       NULL,	/* peer (currently unknown) */
		       C2_MQ_HOST_TARGET);

	mq->host_dma = dma_map_single(c2dev->ibdev.dma_device,
				      (void *)pool_start,
				      q_size * msg_size, DMA_FROM_DEVICE);
	pci_unmap_addr_set(mq, mapping, mq->host_dma);

	return 0;
Loading