diff options
Diffstat (limited to 'drivers/infiniband/core/cma.c')
-rw-r--r-- | drivers/infiniband/core/cma.c | 162 |
1 files changed, 81 insertions, 81 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 671f1373805..ae11d5cc74d 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -4,29 +4,33 @@ | |||
4 | * Copyright (c) 1999-2005, Mellanox Technologies, Inc. All rights reserved. | 4 | * Copyright (c) 1999-2005, Mellanox Technologies, Inc. All rights reserved. |
5 | * Copyright (c) 2005-2006 Intel Corporation. All rights reserved. | 5 | * Copyright (c) 2005-2006 Intel Corporation. All rights reserved. |
6 | * | 6 | * |
7 | * This Software is licensed under one of the following licenses: | 7 | * This software is available to you under a choice of one of two |
8 | * licenses. You may choose to be licensed under the terms of the GNU | ||
9 | * General Public License (GPL) Version 2, available from the file | ||
10 | * COPYING in the main directory of this source tree, or the | ||
11 | * OpenIB.org BSD license below: | ||
8 | * | 12 | * |
9 | * 1) under the terms of the "Common Public License 1.0" a copy of which is | 13 | * Redistribution and use in source and binary forms, with or |
10 | * available from the Open Source Initiative, see | 14 | * without modification, are permitted provided that the following |
11 | * http://www.opensource.org/licenses/cpl.php. | 15 | * conditions are met: |
12 | * | 16 | * |
13 | * 2) under the terms of the "The BSD License" a copy of which is | 17 | * - Redistributions of source code must retain the above |
14 | * available from the Open Source Initiative, see | 18 | * copyright notice, this list of conditions and the following |
15 | * http://www.opensource.org/licenses/bsd-license.php. | 19 | * disclaimer. |
16 | * | 20 | * |
17 | * 3) under the terms of the "GNU General Public License (GPL) Version 2" a | 21 | * - Redistributions in binary form must reproduce the above |
18 | * copy of which is available from the Open Source Initiative, see | 22 | * copyright notice, this list of conditions and the following |
19 | * http://www.opensource.org/licenses/gpl-license.php. | 23 | * disclaimer in the documentation and/or other materials |
20 | * | 24 | * provided with the distribution. |
21 | * Licensee has the right to choose one of the above licenses. | ||
22 | * | ||
23 | * Redistributions of source code must retain the above copyright | ||
24 | * notice and one of the license notices. | ||
25 | * | ||
26 | * Redistributions in binary form must reproduce both the above copyright | ||
27 | * notice, one of the license notices in the documentation | ||
28 | * and/or other materials provided with the distribution. | ||
29 | * | 25 | * |
26 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
27 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
28 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
29 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
30 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
31 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
32 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
33 | * SOFTWARE. | ||
30 | */ | 34 | */ |
31 | 35 | ||
32 | #include <linux/completion.h> | 36 | #include <linux/completion.h> |
@@ -126,8 +130,7 @@ struct rdma_id_private { | |||
126 | 130 | ||
127 | struct completion comp; | 131 | struct completion comp; |
128 | atomic_t refcount; | 132 | atomic_t refcount; |
129 | wait_queue_head_t wait_remove; | 133 | struct mutex handler_mutex; |
130 | atomic_t dev_remove; | ||
131 | 134 | ||
132 | int backlog; | 135 | int backlog; |
133 | int timeout_ms; | 136 | int timeout_ms; |
@@ -351,26 +354,15 @@ static void cma_deref_id(struct rdma_id_private *id_priv) | |||
351 | complete(&id_priv->comp); | 354 | complete(&id_priv->comp); |
352 | } | 355 | } |
353 | 356 | ||
354 | static int cma_disable_remove(struct rdma_id_private *id_priv, | 357 | static int cma_disable_callback(struct rdma_id_private *id_priv, |
355 | enum cma_state state) | 358 | enum cma_state state) |
356 | { | 359 | { |
357 | unsigned long flags; | 360 | mutex_lock(&id_priv->handler_mutex); |
358 | int ret; | 361 | if (id_priv->state != state) { |
359 | 362 | mutex_unlock(&id_priv->handler_mutex); | |
360 | spin_lock_irqsave(&id_priv->lock, flags); | 363 | return -EINVAL; |
361 | if (id_priv->state == state) { | 364 | } |
362 | atomic_inc(&id_priv->dev_remove); | 365 | return 0; |
363 | ret = 0; | ||
364 | } else | ||
365 | ret = -EINVAL; | ||
366 | spin_unlock_irqrestore(&id_priv->lock, flags); | ||
367 | return ret; | ||
368 | } | ||
369 | |||
370 | static void cma_enable_remove(struct rdma_id_private *id_priv) | ||
371 | { | ||
372 | if (atomic_dec_and_test(&id_priv->dev_remove)) | ||
373 | wake_up(&id_priv->wait_remove); | ||
374 | } | 366 | } |
375 | 367 | ||
376 | static int cma_has_cm_dev(struct rdma_id_private *id_priv) | 368 | static int cma_has_cm_dev(struct rdma_id_private *id_priv) |
@@ -395,8 +387,7 @@ struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler, | |||
395 | mutex_init(&id_priv->qp_mutex); | 387 | mutex_init(&id_priv->qp_mutex); |
396 | init_completion(&id_priv->comp); | 388 | init_completion(&id_priv->comp); |
397 | atomic_set(&id_priv->refcount, 1); | 389 | atomic_set(&id_priv->refcount, 1); |
398 | init_waitqueue_head(&id_priv->wait_remove); | 390 | mutex_init(&id_priv->handler_mutex); |
399 | atomic_set(&id_priv->dev_remove, 0); | ||
400 | INIT_LIST_HEAD(&id_priv->listen_list); | 391 | INIT_LIST_HEAD(&id_priv->listen_list); |
401 | INIT_LIST_HEAD(&id_priv->mc_list); | 392 | INIT_LIST_HEAD(&id_priv->mc_list); |
402 | get_random_bytes(&id_priv->seq_num, sizeof id_priv->seq_num); | 393 | get_random_bytes(&id_priv->seq_num, sizeof id_priv->seq_num); |
@@ -923,7 +914,7 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
923 | struct rdma_cm_event event; | 914 | struct rdma_cm_event event; |
924 | int ret = 0; | 915 | int ret = 0; |
925 | 916 | ||
926 | if (cma_disable_remove(id_priv, CMA_CONNECT)) | 917 | if (cma_disable_callback(id_priv, CMA_CONNECT)) |
927 | return 0; | 918 | return 0; |
928 | 919 | ||
929 | memset(&event, 0, sizeof event); | 920 | memset(&event, 0, sizeof event); |
@@ -970,7 +961,7 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
970 | event.param.conn.private_data_len = IB_CM_REJ_PRIVATE_DATA_SIZE; | 961 | event.param.conn.private_data_len = IB_CM_REJ_PRIVATE_DATA_SIZE; |
971 | break; | 962 | break; |
972 | default: | 963 | default: |
973 | printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d", | 964 | printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d\n", |
974 | ib_event->event); | 965 | ib_event->event); |
975 | goto out; | 966 | goto out; |
976 | } | 967 | } |
@@ -980,12 +971,12 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
980 | /* Destroy the CM ID by returning a non-zero value. */ | 971 | /* Destroy the CM ID by returning a non-zero value. */ |
981 | id_priv->cm_id.ib = NULL; | 972 | id_priv->cm_id.ib = NULL; |
982 | cma_exch(id_priv, CMA_DESTROYING); | 973 | cma_exch(id_priv, CMA_DESTROYING); |
983 | cma_enable_remove(id_priv); | 974 | mutex_unlock(&id_priv->handler_mutex); |
984 | rdma_destroy_id(&id_priv->id); | 975 | rdma_destroy_id(&id_priv->id); |
985 | return ret; | 976 | return ret; |
986 | } | 977 | } |
987 | out: | 978 | out: |
988 | cma_enable_remove(id_priv); | 979 | mutex_unlock(&id_priv->handler_mutex); |
989 | return ret; | 980 | return ret; |
990 | } | 981 | } |
991 | 982 | ||
@@ -998,6 +989,7 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id, | |||
998 | union cma_ip_addr *src, *dst; | 989 | union cma_ip_addr *src, *dst; |
999 | __be16 port; | 990 | __be16 port; |
1000 | u8 ip_ver; | 991 | u8 ip_ver; |
992 | int ret; | ||
1001 | 993 | ||
1002 | if (cma_get_net_info(ib_event->private_data, listen_id->ps, | 994 | if (cma_get_net_info(ib_event->private_data, listen_id->ps, |
1003 | &ip_ver, &port, &src, &dst)) | 995 | &ip_ver, &port, &src, &dst)) |
@@ -1022,10 +1014,11 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id, | |||
1022 | if (rt->num_paths == 2) | 1014 | if (rt->num_paths == 2) |
1023 | rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; | 1015 | rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; |
1024 | 1016 | ||
1025 | ib_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid); | ||
1026 | ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid); | 1017 | ib_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid); |
1027 | ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey)); | 1018 | ret = rdma_translate_ip(&id->route.addr.src_addr, |
1028 | rt->addr.dev_addr.dev_type = RDMA_NODE_IB_CA; | 1019 | &id->route.addr.dev_addr); |
1020 | if (ret) | ||
1021 | goto destroy_id; | ||
1029 | 1022 | ||
1030 | id_priv = container_of(id, struct rdma_id_private, id); | 1023 | id_priv = container_of(id, struct rdma_id_private, id); |
1031 | id_priv->state = CMA_CONNECT; | 1024 | id_priv->state = CMA_CONNECT; |
@@ -1095,7 +1088,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
1095 | int offset, ret; | 1088 | int offset, ret; |
1096 | 1089 | ||
1097 | listen_id = cm_id->context; | 1090 | listen_id = cm_id->context; |
1098 | if (cma_disable_remove(listen_id, CMA_LISTEN)) | 1091 | if (cma_disable_callback(listen_id, CMA_LISTEN)) |
1099 | return -ECONNABORTED; | 1092 | return -ECONNABORTED; |
1100 | 1093 | ||
1101 | memset(&event, 0, sizeof event); | 1094 | memset(&event, 0, sizeof event); |
@@ -1116,7 +1109,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
1116 | goto out; | 1109 | goto out; |
1117 | } | 1110 | } |
1118 | 1111 | ||
1119 | atomic_inc(&conn_id->dev_remove); | 1112 | mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING); |
1120 | mutex_lock(&lock); | 1113 | mutex_lock(&lock); |
1121 | ret = cma_acquire_dev(conn_id); | 1114 | ret = cma_acquire_dev(conn_id); |
1122 | mutex_unlock(&lock); | 1115 | mutex_unlock(&lock); |
@@ -1138,7 +1131,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
1138 | !cma_is_ud_ps(conn_id->id.ps)) | 1131 | !cma_is_ud_ps(conn_id->id.ps)) |
1139 | ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); | 1132 | ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0); |
1140 | mutex_unlock(&lock); | 1133 | mutex_unlock(&lock); |
1141 | cma_enable_remove(conn_id); | 1134 | mutex_unlock(&conn_id->handler_mutex); |
1142 | goto out; | 1135 | goto out; |
1143 | } | 1136 | } |
1144 | 1137 | ||
@@ -1147,11 +1140,11 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
1147 | 1140 | ||
1148 | release_conn_id: | 1141 | release_conn_id: |
1149 | cma_exch(conn_id, CMA_DESTROYING); | 1142 | cma_exch(conn_id, CMA_DESTROYING); |
1150 | cma_enable_remove(conn_id); | 1143 | mutex_unlock(&conn_id->handler_mutex); |
1151 | rdma_destroy_id(&conn_id->id); | 1144 | rdma_destroy_id(&conn_id->id); |
1152 | 1145 | ||
1153 | out: | 1146 | out: |
1154 | cma_enable_remove(listen_id); | 1147 | mutex_unlock(&listen_id->handler_mutex); |
1155 | return ret; | 1148 | return ret; |
1156 | } | 1149 | } |
1157 | 1150 | ||
@@ -1217,7 +1210,7 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event) | |||
1217 | struct sockaddr_in *sin; | 1210 | struct sockaddr_in *sin; |
1218 | int ret = 0; | 1211 | int ret = 0; |
1219 | 1212 | ||
1220 | if (cma_disable_remove(id_priv, CMA_CONNECT)) | 1213 | if (cma_disable_callback(id_priv, CMA_CONNECT)) |
1221 | return 0; | 1214 | return 0; |
1222 | 1215 | ||
1223 | memset(&event, 0, sizeof event); | 1216 | memset(&event, 0, sizeof event); |
@@ -1261,12 +1254,12 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event) | |||
1261 | /* Destroy the CM ID by returning a non-zero value. */ | 1254 | /* Destroy the CM ID by returning a non-zero value. */ |
1262 | id_priv->cm_id.iw = NULL; | 1255 | id_priv->cm_id.iw = NULL; |
1263 | cma_exch(id_priv, CMA_DESTROYING); | 1256 | cma_exch(id_priv, CMA_DESTROYING); |
1264 | cma_enable_remove(id_priv); | 1257 | mutex_unlock(&id_priv->handler_mutex); |
1265 | rdma_destroy_id(&id_priv->id); | 1258 | rdma_destroy_id(&id_priv->id); |
1266 | return ret; | 1259 | return ret; |
1267 | } | 1260 | } |
1268 | 1261 | ||
1269 | cma_enable_remove(id_priv); | 1262 | mutex_unlock(&id_priv->handler_mutex); |
1270 | return ret; | 1263 | return ret; |
1271 | } | 1264 | } |
1272 | 1265 | ||
@@ -1282,7 +1275,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, | |||
1282 | struct ib_device_attr attr; | 1275 | struct ib_device_attr attr; |
1283 | 1276 | ||
1284 | listen_id = cm_id->context; | 1277 | listen_id = cm_id->context; |
1285 | if (cma_disable_remove(listen_id, CMA_LISTEN)) | 1278 | if (cma_disable_callback(listen_id, CMA_LISTEN)) |
1286 | return -ECONNABORTED; | 1279 | return -ECONNABORTED; |
1287 | 1280 | ||
1288 | /* Create a new RDMA id for the new IW CM ID */ | 1281 | /* Create a new RDMA id for the new IW CM ID */ |
@@ -1294,19 +1287,19 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, | |||
1294 | goto out; | 1287 | goto out; |
1295 | } | 1288 | } |
1296 | conn_id = container_of(new_cm_id, struct rdma_id_private, id); | 1289 | conn_id = container_of(new_cm_id, struct rdma_id_private, id); |
1297 | atomic_inc(&conn_id->dev_remove); | 1290 | mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING); |
1298 | conn_id->state = CMA_CONNECT; | 1291 | conn_id->state = CMA_CONNECT; |
1299 | 1292 | ||
1300 | dev = ip_dev_find(&init_net, iw_event->local_addr.sin_addr.s_addr); | 1293 | dev = ip_dev_find(&init_net, iw_event->local_addr.sin_addr.s_addr); |
1301 | if (!dev) { | 1294 | if (!dev) { |
1302 | ret = -EADDRNOTAVAIL; | 1295 | ret = -EADDRNOTAVAIL; |
1303 | cma_enable_remove(conn_id); | 1296 | mutex_unlock(&conn_id->handler_mutex); |
1304 | rdma_destroy_id(new_cm_id); | 1297 | rdma_destroy_id(new_cm_id); |
1305 | goto out; | 1298 | goto out; |
1306 | } | 1299 | } |
1307 | ret = rdma_copy_addr(&conn_id->id.route.addr.dev_addr, dev, NULL); | 1300 | ret = rdma_copy_addr(&conn_id->id.route.addr.dev_addr, dev, NULL); |
1308 | if (ret) { | 1301 | if (ret) { |
1309 | cma_enable_remove(conn_id); | 1302 | mutex_unlock(&conn_id->handler_mutex); |
1310 | rdma_destroy_id(new_cm_id); | 1303 | rdma_destroy_id(new_cm_id); |
1311 | goto out; | 1304 | goto out; |
1312 | } | 1305 | } |
@@ -1315,7 +1308,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, | |||
1315 | ret = cma_acquire_dev(conn_id); | 1308 | ret = cma_acquire_dev(conn_id); |
1316 | mutex_unlock(&lock); | 1309 | mutex_unlock(&lock); |
1317 | if (ret) { | 1310 | if (ret) { |
1318 | cma_enable_remove(conn_id); | 1311 | mutex_unlock(&conn_id->handler_mutex); |
1319 | rdma_destroy_id(new_cm_id); | 1312 | rdma_destroy_id(new_cm_id); |
1320 | goto out; | 1313 | goto out; |
1321 | } | 1314 | } |
@@ -1331,7 +1324,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, | |||
1331 | 1324 | ||
1332 | ret = ib_query_device(conn_id->id.device, &attr); | 1325 | ret = ib_query_device(conn_id->id.device, &attr); |
1333 | if (ret) { | 1326 | if (ret) { |
1334 | cma_enable_remove(conn_id); | 1327 | mutex_unlock(&conn_id->handler_mutex); |
1335 | rdma_destroy_id(new_cm_id); | 1328 | rdma_destroy_id(new_cm_id); |
1336 | goto out; | 1329 | goto out; |
1337 | } | 1330 | } |
@@ -1347,14 +1340,17 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, | |||
1347 | /* User wants to destroy the CM ID */ | 1340 | /* User wants to destroy the CM ID */ |
1348 | conn_id->cm_id.iw = NULL; | 1341 | conn_id->cm_id.iw = NULL; |
1349 | cma_exch(conn_id, CMA_DESTROYING); | 1342 | cma_exch(conn_id, CMA_DESTROYING); |
1350 | cma_enable_remove(conn_id); | 1343 | mutex_unlock(&conn_id->handler_mutex); |
1351 | rdma_destroy_id(&conn_id->id); | 1344 | rdma_destroy_id(&conn_id->id); |
1345 | goto out; | ||
1352 | } | 1346 | } |
1353 | 1347 | ||
1348 | mutex_unlock(&conn_id->handler_mutex); | ||
1349 | |||
1354 | out: | 1350 | out: |
1355 | if (dev) | 1351 | if (dev) |
1356 | dev_put(dev); | 1352 | dev_put(dev); |
1357 | cma_enable_remove(listen_id); | 1353 | mutex_unlock(&listen_id->handler_mutex); |
1358 | return ret; | 1354 | return ret; |
1359 | } | 1355 | } |
1360 | 1356 | ||
@@ -1446,7 +1442,7 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv, | |||
1446 | ret = rdma_listen(id, id_priv->backlog); | 1442 | ret = rdma_listen(id, id_priv->backlog); |
1447 | if (ret) | 1443 | if (ret) |
1448 | printk(KERN_WARNING "RDMA CMA: cma_listen_on_dev, error %d, " | 1444 | printk(KERN_WARNING "RDMA CMA: cma_listen_on_dev, error %d, " |
1449 | "listening on device %s", ret, cma_dev->device->name); | 1445 | "listening on device %s\n", ret, cma_dev->device->name); |
1450 | } | 1446 | } |
1451 | 1447 | ||
1452 | static void cma_listen_on_all(struct rdma_id_private *id_priv) | 1448 | static void cma_listen_on_all(struct rdma_id_private *id_priv) |
@@ -1586,7 +1582,7 @@ static void cma_work_handler(struct work_struct *_work) | |||
1586 | struct rdma_id_private *id_priv = work->id; | 1582 | struct rdma_id_private *id_priv = work->id; |
1587 | int destroy = 0; | 1583 | int destroy = 0; |
1588 | 1584 | ||
1589 | atomic_inc(&id_priv->dev_remove); | 1585 | mutex_lock(&id_priv->handler_mutex); |
1590 | if (!cma_comp_exch(id_priv, work->old_state, work->new_state)) | 1586 | if (!cma_comp_exch(id_priv, work->old_state, work->new_state)) |
1591 | goto out; | 1587 | goto out; |
1592 | 1588 | ||
@@ -1595,7 +1591,7 @@ static void cma_work_handler(struct work_struct *_work) | |||
1595 | destroy = 1; | 1591 | destroy = 1; |
1596 | } | 1592 | } |
1597 | out: | 1593 | out: |
1598 | cma_enable_remove(id_priv); | 1594 | mutex_unlock(&id_priv->handler_mutex); |
1599 | cma_deref_id(id_priv); | 1595 | cma_deref_id(id_priv); |
1600 | if (destroy) | 1596 | if (destroy) |
1601 | rdma_destroy_id(&id_priv->id); | 1597 | rdma_destroy_id(&id_priv->id); |
@@ -1758,7 +1754,7 @@ static void addr_handler(int status, struct sockaddr *src_addr, | |||
1758 | struct rdma_cm_event event; | 1754 | struct rdma_cm_event event; |
1759 | 1755 | ||
1760 | memset(&event, 0, sizeof event); | 1756 | memset(&event, 0, sizeof event); |
1761 | atomic_inc(&id_priv->dev_remove); | 1757 | mutex_lock(&id_priv->handler_mutex); |
1762 | 1758 | ||
1763 | /* | 1759 | /* |
1764 | * Grab mutex to block rdma_destroy_id() from removing the device while | 1760 | * Grab mutex to block rdma_destroy_id() from removing the device while |
@@ -1787,13 +1783,13 @@ static void addr_handler(int status, struct sockaddr *src_addr, | |||
1787 | 1783 | ||
1788 | if (id_priv->id.event_handler(&id_priv->id, &event)) { | 1784 | if (id_priv->id.event_handler(&id_priv->id, &event)) { |
1789 | cma_exch(id_priv, CMA_DESTROYING); | 1785 | cma_exch(id_priv, CMA_DESTROYING); |
1790 | cma_enable_remove(id_priv); | 1786 | mutex_unlock(&id_priv->handler_mutex); |
1791 | cma_deref_id(id_priv); | 1787 | cma_deref_id(id_priv); |
1792 | rdma_destroy_id(&id_priv->id); | 1788 | rdma_destroy_id(&id_priv->id); |
1793 | return; | 1789 | return; |
1794 | } | 1790 | } |
1795 | out: | 1791 | out: |
1796 | cma_enable_remove(id_priv); | 1792 | mutex_unlock(&id_priv->handler_mutex); |
1797 | cma_deref_id(id_priv); | 1793 | cma_deref_id(id_priv); |
1798 | } | 1794 | } |
1799 | 1795 | ||
@@ -2120,7 +2116,7 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id, | |||
2120 | struct ib_cm_sidr_rep_event_param *rep = &ib_event->param.sidr_rep_rcvd; | 2116 | struct ib_cm_sidr_rep_event_param *rep = &ib_event->param.sidr_rep_rcvd; |
2121 | int ret = 0; | 2117 | int ret = 0; |
2122 | 2118 | ||
2123 | if (cma_disable_remove(id_priv, CMA_CONNECT)) | 2119 | if (cma_disable_callback(id_priv, CMA_CONNECT)) |
2124 | return 0; | 2120 | return 0; |
2125 | 2121 | ||
2126 | memset(&event, 0, sizeof event); | 2122 | memset(&event, 0, sizeof event); |
@@ -2151,7 +2147,7 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id, | |||
2151 | event.status = 0; | 2147 | event.status = 0; |
2152 | break; | 2148 | break; |
2153 | default: | 2149 | default: |
2154 | printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d", | 2150 | printk(KERN_ERR "RDMA CMA: unexpected IB CM event: %d\n", |
2155 | ib_event->event); | 2151 | ib_event->event); |
2156 | goto out; | 2152 | goto out; |
2157 | } | 2153 | } |
@@ -2161,12 +2157,12 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id, | |||
2161 | /* Destroy the CM ID by returning a non-zero value. */ | 2157 | /* Destroy the CM ID by returning a non-zero value. */ |
2162 | id_priv->cm_id.ib = NULL; | 2158 | id_priv->cm_id.ib = NULL; |
2163 | cma_exch(id_priv, CMA_DESTROYING); | 2159 | cma_exch(id_priv, CMA_DESTROYING); |
2164 | cma_enable_remove(id_priv); | 2160 | mutex_unlock(&id_priv->handler_mutex); |
2165 | rdma_destroy_id(&id_priv->id); | 2161 | rdma_destroy_id(&id_priv->id); |
2166 | return ret; | 2162 | return ret; |
2167 | } | 2163 | } |
2168 | out: | 2164 | out: |
2169 | cma_enable_remove(id_priv); | 2165 | mutex_unlock(&id_priv->handler_mutex); |
2170 | return ret; | 2166 | return ret; |
2171 | } | 2167 | } |
2172 | 2168 | ||
@@ -2564,8 +2560,8 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast) | |||
2564 | int ret; | 2560 | int ret; |
2565 | 2561 | ||
2566 | id_priv = mc->id_priv; | 2562 | id_priv = mc->id_priv; |
2567 | if (cma_disable_remove(id_priv, CMA_ADDR_BOUND) && | 2563 | if (cma_disable_callback(id_priv, CMA_ADDR_BOUND) && |
2568 | cma_disable_remove(id_priv, CMA_ADDR_RESOLVED)) | 2564 | cma_disable_callback(id_priv, CMA_ADDR_RESOLVED)) |
2569 | return 0; | 2565 | return 0; |
2570 | 2566 | ||
2571 | mutex_lock(&id_priv->qp_mutex); | 2567 | mutex_lock(&id_priv->qp_mutex); |
@@ -2590,12 +2586,12 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast) | |||
2590 | ret = id_priv->id.event_handler(&id_priv->id, &event); | 2586 | ret = id_priv->id.event_handler(&id_priv->id, &event); |
2591 | if (ret) { | 2587 | if (ret) { |
2592 | cma_exch(id_priv, CMA_DESTROYING); | 2588 | cma_exch(id_priv, CMA_DESTROYING); |
2593 | cma_enable_remove(id_priv); | 2589 | mutex_unlock(&id_priv->handler_mutex); |
2594 | rdma_destroy_id(&id_priv->id); | 2590 | rdma_destroy_id(&id_priv->id); |
2595 | return 0; | 2591 | return 0; |
2596 | } | 2592 | } |
2597 | 2593 | ||
2598 | cma_enable_remove(id_priv); | 2594 | mutex_unlock(&id_priv->handler_mutex); |
2599 | return 0; | 2595 | return 0; |
2600 | } | 2596 | } |
2601 | 2597 | ||
@@ -2754,6 +2750,7 @@ static int cma_remove_id_dev(struct rdma_id_private *id_priv) | |||
2754 | { | 2750 | { |
2755 | struct rdma_cm_event event; | 2751 | struct rdma_cm_event event; |
2756 | enum cma_state state; | 2752 | enum cma_state state; |
2753 | int ret = 0; | ||
2757 | 2754 | ||
2758 | /* Record that we want to remove the device */ | 2755 | /* Record that we want to remove the device */ |
2759 | state = cma_exch(id_priv, CMA_DEVICE_REMOVAL); | 2756 | state = cma_exch(id_priv, CMA_DEVICE_REMOVAL); |
@@ -2761,15 +2758,18 @@ static int cma_remove_id_dev(struct rdma_id_private *id_priv) | |||
2761 | return 0; | 2758 | return 0; |
2762 | 2759 | ||
2763 | cma_cancel_operation(id_priv, state); | 2760 | cma_cancel_operation(id_priv, state); |
2764 | wait_event(id_priv->wait_remove, !atomic_read(&id_priv->dev_remove)); | 2761 | mutex_lock(&id_priv->handler_mutex); |
2765 | 2762 | ||
2766 | /* Check for destruction from another callback. */ | 2763 | /* Check for destruction from another callback. */ |
2767 | if (!cma_comp(id_priv, CMA_DEVICE_REMOVAL)) | 2764 | if (!cma_comp(id_priv, CMA_DEVICE_REMOVAL)) |
2768 | return 0; | 2765 | goto out; |
2769 | 2766 | ||
2770 | memset(&event, 0, sizeof event); | 2767 | memset(&event, 0, sizeof event); |
2771 | event.event = RDMA_CM_EVENT_DEVICE_REMOVAL; | 2768 | event.event = RDMA_CM_EVENT_DEVICE_REMOVAL; |
2772 | return id_priv->id.event_handler(&id_priv->id, &event); | 2769 | ret = id_priv->id.event_handler(&id_priv->id, &event); |
2770 | out: | ||
2771 | mutex_unlock(&id_priv->handler_mutex); | ||
2772 | return ret; | ||
2773 | } | 2773 | } |
2774 | 2774 | ||
2775 | static void cma_process_remove(struct cma_device *cma_dev) | 2775 | static void cma_process_remove(struct cma_device *cma_dev) |