aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/cma.c43
1 files changed, 16 insertions, 27 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index e450c5a87727..5ed9d25d021a 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -308,11 +308,13 @@ static inline void release_mc(struct kref *kref)
308 kfree(mc); 308 kfree(mc);
309} 309}
310 310
311static void cma_detach_from_dev(struct rdma_id_private *id_priv) 311static void cma_release_dev(struct rdma_id_private *id_priv)
312{ 312{
313 mutex_lock(&lock);
313 list_del(&id_priv->list); 314 list_del(&id_priv->list);
314 cma_deref_dev(id_priv->cma_dev); 315 cma_deref_dev(id_priv->cma_dev);
315 id_priv->cma_dev = NULL; 316 id_priv->cma_dev = NULL;
317 mutex_unlock(&lock);
316} 318}
317 319
318static int cma_set_qkey(struct rdma_id_private *id_priv) 320static int cma_set_qkey(struct rdma_id_private *id_priv)
@@ -373,6 +375,7 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv)
373 enum rdma_link_layer dev_ll = dev_addr->dev_type == ARPHRD_INFINIBAND ? 375 enum rdma_link_layer dev_ll = dev_addr->dev_type == ARPHRD_INFINIBAND ?
374 IB_LINK_LAYER_INFINIBAND : IB_LINK_LAYER_ETHERNET; 376 IB_LINK_LAYER_INFINIBAND : IB_LINK_LAYER_ETHERNET;
375 377
378 mutex_lock(&lock);
376 iboe_addr_get_sgid(dev_addr, &iboe_gid); 379 iboe_addr_get_sgid(dev_addr, &iboe_gid);
377 memcpy(&gid, dev_addr->src_dev_addr + 380 memcpy(&gid, dev_addr->src_dev_addr +
378 rdma_addr_gid_offset(dev_addr), sizeof gid); 381 rdma_addr_gid_offset(dev_addr), sizeof gid);
@@ -398,6 +401,7 @@ out:
398 if (!ret) 401 if (!ret)
399 cma_attach_to_dev(id_priv, cma_dev); 402 cma_attach_to_dev(id_priv, cma_dev);
400 403
404 mutex_unlock(&lock);
401 return ret; 405 return ret;
402} 406}
403 407
@@ -904,9 +908,14 @@ void rdma_destroy_id(struct rdma_cm_id *id)
904 state = cma_exch(id_priv, CMA_DESTROYING); 908 state = cma_exch(id_priv, CMA_DESTROYING);
905 cma_cancel_operation(id_priv, state); 909 cma_cancel_operation(id_priv, state);
906 910
907 mutex_lock(&lock); 911 /*
912 * Wait for any active callback to finish. New callbacks will find
913 * the id_priv state set to destroying and abort.
914 */
915 mutex_lock(&id_priv->handler_mutex);
916 mutex_unlock(&id_priv->handler_mutex);
917
908 if (id_priv->cma_dev) { 918 if (id_priv->cma_dev) {
909 mutex_unlock(&lock);
910 switch (rdma_node_get_transport(id_priv->id.device->node_type)) { 919 switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
911 case RDMA_TRANSPORT_IB: 920 case RDMA_TRANSPORT_IB:
912 if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib)) 921 if (id_priv->cm_id.ib && !IS_ERR(id_priv->cm_id.ib))
@@ -920,10 +929,8 @@ void rdma_destroy_id(struct rdma_cm_id *id)
920 break; 929 break;
921 } 930 }
922 cma_leave_mc_groups(id_priv); 931 cma_leave_mc_groups(id_priv);
923 mutex_lock(&lock); 932 cma_release_dev(id_priv);
924 cma_detach_from_dev(id_priv);
925 } 933 }
926 mutex_unlock(&lock);
927 934
928 cma_release_port(id_priv); 935 cma_release_port(id_priv);
929 cma_deref_id(id_priv); 936 cma_deref_id(id_priv);
@@ -1200,9 +1207,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
1200 } 1207 }
1201 1208
1202 mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING); 1209 mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING);
1203 mutex_lock(&lock);
1204 ret = cma_acquire_dev(conn_id); 1210 ret = cma_acquire_dev(conn_id);
1205 mutex_unlock(&lock);
1206 if (ret) 1211 if (ret)
1207 goto release_conn_id; 1212 goto release_conn_id;
1208 1213
@@ -1401,9 +1406,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
1401 goto out; 1406 goto out;
1402 } 1407 }
1403 1408
1404 mutex_lock(&lock);
1405 ret = cma_acquire_dev(conn_id); 1409 ret = cma_acquire_dev(conn_id);
1406 mutex_unlock(&lock);
1407 if (ret) { 1410 if (ret) {
1408 mutex_unlock(&conn_id->handler_mutex); 1411 mutex_unlock(&conn_id->handler_mutex);
1409 rdma_destroy_id(new_cm_id); 1412 rdma_destroy_id(new_cm_id);
@@ -1966,20 +1969,11 @@ static void addr_handler(int status, struct sockaddr *src_addr,
1966 1969
1967 memset(&event, 0, sizeof event); 1970 memset(&event, 0, sizeof event);
1968 mutex_lock(&id_priv->handler_mutex); 1971 mutex_lock(&id_priv->handler_mutex);
1969 1972 if (!cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_RESOLVED))
1970 /*
1971 * Grab mutex to block rdma_destroy_id() from removing the device while
1972 * we're trying to acquire it.
1973 */
1974 mutex_lock(&lock);
1975 if (!cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_RESOLVED)) {
1976 mutex_unlock(&lock);
1977 goto out; 1973 goto out;
1978 }
1979 1974
1980 if (!status && !id_priv->cma_dev) 1975 if (!status && !id_priv->cma_dev)
1981 status = cma_acquire_dev(id_priv); 1976 status = cma_acquire_dev(id_priv);
1982 mutex_unlock(&lock);
1983 1977
1984 if (status) { 1978 if (status) {
1985 if (!cma_comp_exch(id_priv, CMA_ADDR_RESOLVED, CMA_ADDR_BOUND)) 1979 if (!cma_comp_exch(id_priv, CMA_ADDR_RESOLVED, CMA_ADDR_BOUND))
@@ -2280,9 +2274,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
2280 if (ret) 2274 if (ret)
2281 goto err1; 2275 goto err1;
2282 2276
2283 mutex_lock(&lock);
2284 ret = cma_acquire_dev(id_priv); 2277 ret = cma_acquire_dev(id_priv);
2285 mutex_unlock(&lock);
2286 if (ret) 2278 if (ret)
2287 goto err1; 2279 goto err1;
2288 } 2280 }
@@ -2294,11 +2286,8 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
2294 2286
2295 return 0; 2287 return 0;
2296err2: 2288err2:
2297 if (id_priv->cma_dev) { 2289 if (id_priv->cma_dev)
2298 mutex_lock(&lock); 2290 cma_release_dev(id_priv);
2299 cma_detach_from_dev(id_priv);
2300 mutex_unlock(&lock);
2301 }
2302err1: 2291err1:
2303 cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE); 2292 cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE);
2304 return ret; 2293 return ret;