aboutsummaryrefslogtreecommitdiff
path: root/drivers/infiniband/core/cma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/core/cma.c')
-rw-r--r--drivers/infiniband/core/cma.c80
1 files changed, 42 insertions, 38 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 9ae4f3a67c7..cf48f269743 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -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);
@@ -343,7 +344,7 @@ static int cma_init_ib_qp(struct rdma_id_private *id_priv, struct ib_qp *qp)
return ret;
qp_attr.qp_state = IB_QPS_INIT;
- qp_attr.qp_access_flags = IB_ACCESS_LOCAL_WRITE;
+ qp_attr.qp_access_flags = 0;
qp_attr.port_num = id_priv->id.port_num;
return ib_modify_qp(qp, &qp_attr, IB_QP_STATE | IB_QP_ACCESS_FLAGS |
IB_QP_PKEY_INDEX | IB_QP_PORT);
@@ -934,13 +935,8 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
mutex_lock(&lock);
ret = cma_acquire_dev(conn_id);
mutex_unlock(&lock);
- if (ret) {
- ret = -ENODEV;
- cma_exch(conn_id, CMA_DESTROYING);
- cma_release_remove(conn_id);
- rdma_destroy_id(&conn_id->id);
- goto out;
- }
+ if (ret)
+ goto release_conn_id;
conn_id->cm_id.ib = cm_id;
cm_id->context = conn_id;
@@ -950,13 +946,17 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
ret = cma_notify_user(conn_id, RDMA_CM_EVENT_CONNECT_REQUEST, 0,
ib_event->private_data + offset,
IB_CM_REQ_PRIVATE_DATA_SIZE - offset);
- if (ret) {
- /* Destroy the CM ID by returning a non-zero value. */
- conn_id->cm_id.ib = NULL;
- cma_exch(conn_id, CMA_DESTROYING);
- cma_release_remove(conn_id);
- rdma_destroy_id(&conn_id->id);
- }
+ if (!ret)
+ goto out;
+
+ /* Destroy the CM ID by returning a non-zero value. */
+ conn_id->cm_id.ib = NULL;
+
+release_conn_id:
+ cma_exch(conn_id, CMA_DESTROYING);
+ cma_release_remove(conn_id);
+ rdma_destroy_id(&conn_id->id);
+
out:
cma_release_remove(listen_id);
return ret;
@@ -1480,19 +1480,18 @@ static int cma_bind_loopback(struct rdma_id_private *id_priv)
u8 p;
mutex_lock(&lock);
+ if (list_empty(&dev_list)) {
+ ret = -ENODEV;
+ goto out;
+ }
list_for_each_entry(cma_dev, &dev_list, list)
for (p = 1; p <= cma_dev->device->phys_port_cnt; ++p)
- if (!ib_query_port (cma_dev->device, p, &port_attr) &&
+ if (!ib_query_port(cma_dev->device, p, &port_attr) &&
port_attr.state == IB_PORT_ACTIVE)
goto port_found;
- if (!list_empty(&dev_list)) {
- p = 1;
- cma_dev = list_entry(dev_list.next, struct cma_device, list);
- } else {
- ret = -ENODEV;
- goto out;
- }
+ p = 1;
+ cma_dev = list_entry(dev_list.next, struct cma_device, list);
port_found:
ret = ib_get_cached_gid(cma_dev->device, p, 0, &gid);
@@ -1625,8 +1624,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 +1761,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) {
- mutex_lock(&lock);
- ret = cma_acquire_dev(id_priv);
- mutex_unlock(&lock);
- }
if (ret)
- goto err;
+ goto err1;
+
+ mutex_lock(&lock);
+ ret = cma_acquire_dev(id_priv);
+ mutex_unlock(&lock);
+ if (ret)
+ 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;
}
@@ -2115,8 +2121,6 @@ static void cma_add_one(struct ib_device *device)
cma_dev->device = device;
cma_dev->node_guid = device->node_guid;
- if (!cma_dev->node_guid)
- goto err;
init_completion(&cma_dev->comp);
atomic_set(&cma_dev->refcount, 1);
@@ -2128,9 +2132,6 @@ static void cma_add_one(struct ib_device *device)
list_for_each_entry(id_priv, &listen_any_list, list)
cma_listen_on_dev(id_priv, cma_dev);
mutex_unlock(&lock);
- return;
-err:
- kfree(cma_dev);
}
static int cma_remove_id_dev(struct rdma_id_private *id_priv)
@@ -2210,6 +2211,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 +2219,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 +2228,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);