aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2007-05-07 14:49:00 -0400
committerRoland Dreier <rolandd@cisco.com>2007-05-14 16:54:49 -0400
commit8aa08602bdd617a9cdd147f19076a8c8a70e03ef (patch)
tree29f2565b26d1e74fa5f1af8f168007286a479929 /drivers/infiniband
parent4e430dcb7b132a4076e533a9d69907acecbe71be (diff)
RDMA/cma: Simplify device removal handling code
Add a new routine and rename another to encapsulate common code for synchronizing with device removal. Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/cma.c89
1 files changed, 48 insertions, 41 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index fde92ce45153..d026764c7e9c 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -346,7 +346,23 @@ static void cma_deref_id(struct rdma_id_private *id_priv)
346 complete(&id_priv->comp); 346 complete(&id_priv->comp);
347} 347}
348 348
349static void cma_release_remove(struct rdma_id_private *id_priv) 349static int cma_disable_remove(struct rdma_id_private *id_priv,
350 enum cma_state state)
351{
352 unsigned long flags;
353 int ret;
354
355 spin_lock_irqsave(&id_priv->lock, flags);
356 if (id_priv->state == state) {
357 atomic_inc(&id_priv->dev_remove);
358 ret = 0;
359 } else
360 ret = -EINVAL;
361 spin_unlock_irqrestore(&id_priv->lock, flags);
362 return ret;
363}
364
365static void cma_enable_remove(struct rdma_id_private *id_priv)
350{ 366{
351 if (atomic_dec_and_test(&id_priv->dev_remove)) 367 if (atomic_dec_and_test(&id_priv->dev_remove))
352 wake_up(&id_priv->wait_remove); 368 wake_up(&id_priv->wait_remove);
@@ -884,9 +900,8 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
884 struct rdma_cm_event event; 900 struct rdma_cm_event event;
885 int ret = 0; 901 int ret = 0;
886 902
887 atomic_inc(&id_priv->dev_remove); 903 if (cma_disable_remove(id_priv, CMA_CONNECT))
888 if (!cma_comp(id_priv, CMA_CONNECT)) 904 return 0;
889 goto out;
890 905
891 memset(&event, 0, sizeof event); 906 memset(&event, 0, sizeof event);
892 switch (ib_event->event) { 907 switch (ib_event->event) {
@@ -942,12 +957,12 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
942 /* Destroy the CM ID by returning a non-zero value. */ 957 /* Destroy the CM ID by returning a non-zero value. */
943 id_priv->cm_id.ib = NULL; 958 id_priv->cm_id.ib = NULL;
944 cma_exch(id_priv, CMA_DESTROYING); 959 cma_exch(id_priv, CMA_DESTROYING);
945 cma_release_remove(id_priv); 960 cma_enable_remove(id_priv);
946 rdma_destroy_id(&id_priv->id); 961 rdma_destroy_id(&id_priv->id);
947 return ret; 962 return ret;
948 } 963 }
949out: 964out:
950 cma_release_remove(id_priv); 965 cma_enable_remove(id_priv);
951 return ret; 966 return ret;
952} 967}
953 968
@@ -1057,11 +1072,8 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
1057 int offset, ret; 1072 int offset, ret;
1058 1073
1059 listen_id = cm_id->context; 1074 listen_id = cm_id->context;
1060 atomic_inc(&listen_id->dev_remove); 1075 if (cma_disable_remove(listen_id, CMA_LISTEN))
1061 if (!cma_comp(listen_id, CMA_LISTEN)) { 1076 return -ECONNABORTED;
1062 ret = -ECONNABORTED;
1063 goto out;
1064 }
1065 1077
1066 memset(&event, 0, sizeof event); 1078 memset(&event, 0, sizeof event);
1067 offset = cma_user_data_offset(listen_id->id.ps); 1079 offset = cma_user_data_offset(listen_id->id.ps);
@@ -1101,11 +1113,11 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
1101 1113
1102release_conn_id: 1114release_conn_id:
1103 cma_exch(conn_id, CMA_DESTROYING); 1115 cma_exch(conn_id, CMA_DESTROYING);
1104 cma_release_remove(conn_id); 1116 cma_enable_remove(conn_id);
1105 rdma_destroy_id(&conn_id->id); 1117 rdma_destroy_id(&conn_id->id);
1106 1118
1107out: 1119out:
1108 cma_release_remove(listen_id); 1120 cma_enable_remove(listen_id);
1109 return ret; 1121 return ret;
1110} 1122}
1111 1123
@@ -1214,12 +1226,12 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event)
1214 /* Destroy the CM ID by returning a non-zero value. */ 1226 /* Destroy the CM ID by returning a non-zero value. */
1215 id_priv->cm_id.iw = NULL; 1227 id_priv->cm_id.iw = NULL;
1216 cma_exch(id_priv, CMA_DESTROYING); 1228 cma_exch(id_priv, CMA_DESTROYING);
1217 cma_release_remove(id_priv); 1229 cma_enable_remove(id_priv);
1218 rdma_destroy_id(&id_priv->id); 1230 rdma_destroy_id(&id_priv->id);
1219 return ret; 1231 return ret;
1220 } 1232 }
1221 1233
1222 cma_release_remove(id_priv); 1234 cma_enable_remove(id_priv);
1223 return ret; 1235 return ret;
1224} 1236}
1225 1237
@@ -1234,11 +1246,8 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
1234 int ret; 1246 int ret;
1235 1247
1236 listen_id = cm_id->context; 1248 listen_id = cm_id->context;
1237 atomic_inc(&listen_id->dev_remove); 1249 if (cma_disable_remove(listen_id, CMA_LISTEN))
1238 if (!cma_comp(listen_id, CMA_LISTEN)) { 1250 return -ECONNABORTED;
1239 ret = -ECONNABORTED;
1240 goto out;
1241 }
1242 1251
1243 /* Create a new RDMA id for the new IW CM ID */ 1252 /* Create a new RDMA id for the new IW CM ID */
1244 new_cm_id = rdma_create_id(listen_id->id.event_handler, 1253 new_cm_id = rdma_create_id(listen_id->id.event_handler,
@@ -1255,13 +1264,13 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
1255 dev = ip_dev_find(iw_event->local_addr.sin_addr.s_addr); 1264 dev = ip_dev_find(iw_event->local_addr.sin_addr.s_addr);
1256 if (!dev) { 1265 if (!dev) {
1257 ret = -EADDRNOTAVAIL; 1266 ret = -EADDRNOTAVAIL;
1258 cma_release_remove(conn_id); 1267 cma_enable_remove(conn_id);
1259 rdma_destroy_id(new_cm_id); 1268 rdma_destroy_id(new_cm_id);
1260 goto out; 1269 goto out;
1261 } 1270 }
1262 ret = rdma_copy_addr(&conn_id->id.route.addr.dev_addr, dev, NULL); 1271 ret = rdma_copy_addr(&conn_id->id.route.addr.dev_addr, dev, NULL);
1263 if (ret) { 1272 if (ret) {
1264 cma_release_remove(conn_id); 1273 cma_enable_remove(conn_id);
1265 rdma_destroy_id(new_cm_id); 1274 rdma_destroy_id(new_cm_id);
1266 goto out; 1275 goto out;
1267 } 1276 }
@@ -1270,7 +1279,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
1270 ret = cma_acquire_dev(conn_id); 1279 ret = cma_acquire_dev(conn_id);
1271 mutex_unlock(&lock); 1280 mutex_unlock(&lock);
1272 if (ret) { 1281 if (ret) {
1273 cma_release_remove(conn_id); 1282 cma_enable_remove(conn_id);
1274 rdma_destroy_id(new_cm_id); 1283 rdma_destroy_id(new_cm_id);
1275 goto out; 1284 goto out;
1276 } 1285 }
@@ -1293,14 +1302,14 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
1293 /* User wants to destroy the CM ID */ 1302 /* User wants to destroy the CM ID */
1294 conn_id->cm_id.iw = NULL; 1303 conn_id->cm_id.iw = NULL;
1295 cma_exch(conn_id, CMA_DESTROYING); 1304 cma_exch(conn_id, CMA_DESTROYING);
1296 cma_release_remove(conn_id); 1305 cma_enable_remove(conn_id);
1297 rdma_destroy_id(&conn_id->id); 1306 rdma_destroy_id(&conn_id->id);
1298 } 1307 }
1299 1308
1300out: 1309out:
1301 if (dev) 1310 if (dev)
1302 dev_put(dev); 1311 dev_put(dev);
1303 cma_release_remove(listen_id); 1312 cma_enable_remove(listen_id);
1304 return ret; 1313 return ret;
1305} 1314}
1306 1315
@@ -1519,7 +1528,7 @@ static void cma_work_handler(struct work_struct *_work)
1519 destroy = 1; 1528 destroy = 1;
1520 } 1529 }
1521out: 1530out:
1522 cma_release_remove(id_priv); 1531 cma_enable_remove(id_priv);
1523 cma_deref_id(id_priv); 1532 cma_deref_id(id_priv);
1524 if (destroy) 1533 if (destroy)
1525 rdma_destroy_id(&id_priv->id); 1534 rdma_destroy_id(&id_priv->id);
@@ -1711,13 +1720,13 @@ static void addr_handler(int status, struct sockaddr *src_addr,
1711 1720
1712 if (id_priv->id.event_handler(&id_priv->id, &event)) { 1721 if (id_priv->id.event_handler(&id_priv->id, &event)) {
1713 cma_exch(id_priv, CMA_DESTROYING); 1722 cma_exch(id_priv, CMA_DESTROYING);
1714 cma_release_remove(id_priv); 1723 cma_enable_remove(id_priv);
1715 cma_deref_id(id_priv); 1724 cma_deref_id(id_priv);
1716 rdma_destroy_id(&id_priv->id); 1725 rdma_destroy_id(&id_priv->id);
1717 return; 1726 return;
1718 } 1727 }
1719out: 1728out:
1720 cma_release_remove(id_priv); 1729 cma_enable_remove(id_priv);
1721 cma_deref_id(id_priv); 1730 cma_deref_id(id_priv);
1722} 1731}
1723 1732
@@ -2042,11 +2051,10 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id,
2042 struct ib_cm_sidr_rep_event_param *rep = &ib_event->param.sidr_rep_rcvd; 2051 struct ib_cm_sidr_rep_event_param *rep = &ib_event->param.sidr_rep_rcvd;
2043 int ret = 0; 2052 int ret = 0;
2044 2053
2045 memset(&event, 0, sizeof event); 2054 if (cma_disable_remove(id_priv, CMA_CONNECT))
2046 atomic_inc(&id_priv->dev_remove); 2055 return 0;
2047 if (!cma_comp(id_priv, CMA_CONNECT))
2048 goto out;
2049 2056
2057 memset(&event, 0, sizeof event);
2050 switch (ib_event->event) { 2058 switch (ib_event->event) {
2051 case IB_CM_SIDR_REQ_ERROR: 2059 case IB_CM_SIDR_REQ_ERROR:
2052 event.event = RDMA_CM_EVENT_UNREACHABLE; 2060 event.event = RDMA_CM_EVENT_UNREACHABLE;
@@ -2084,12 +2092,12 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id,
2084 /* Destroy the CM ID by returning a non-zero value. */ 2092 /* Destroy the CM ID by returning a non-zero value. */
2085 id_priv->cm_id.ib = NULL; 2093 id_priv->cm_id.ib = NULL;
2086 cma_exch(id_priv, CMA_DESTROYING); 2094 cma_exch(id_priv, CMA_DESTROYING);
2087 cma_release_remove(id_priv); 2095 cma_enable_remove(id_priv);
2088 rdma_destroy_id(&id_priv->id); 2096 rdma_destroy_id(&id_priv->id);
2089 return ret; 2097 return ret;
2090 } 2098 }
2091out: 2099out:
2092 cma_release_remove(id_priv); 2100 cma_enable_remove(id_priv);
2093 return ret; 2101 return ret;
2094} 2102}
2095 2103
@@ -2499,10 +2507,9 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast)
2499 int ret; 2507 int ret;
2500 2508
2501 id_priv = mc->id_priv; 2509 id_priv = mc->id_priv;
2502 atomic_inc(&id_priv->dev_remove); 2510 if (cma_disable_remove(id_priv, CMA_ADDR_BOUND) &&
2503 if (!cma_comp(id_priv, CMA_ADDR_BOUND) && 2511 cma_disable_remove(id_priv, CMA_ADDR_RESOLVED))
2504 !cma_comp(id_priv, CMA_ADDR_RESOLVED)) 2512 return 0;
2505 goto out;
2506 2513
2507 if (!status && id_priv->id.qp) 2514 if (!status && id_priv->id.qp)
2508 status = ib_attach_mcast(id_priv->id.qp, &multicast->rec.mgid, 2515 status = ib_attach_mcast(id_priv->id.qp, &multicast->rec.mgid,
@@ -2524,12 +2531,12 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast)
2524 ret = id_priv->id.event_handler(&id_priv->id, &event); 2531 ret = id_priv->id.event_handler(&id_priv->id, &event);
2525 if (ret) { 2532 if (ret) {
2526 cma_exch(id_priv, CMA_DESTROYING); 2533 cma_exch(id_priv, CMA_DESTROYING);
2527 cma_release_remove(id_priv); 2534 cma_enable_remove(id_priv);
2528 rdma_destroy_id(&id_priv->id); 2535 rdma_destroy_id(&id_priv->id);
2529 return 0; 2536 return 0;
2530 } 2537 }
2531out: 2538
2532 cma_release_remove(id_priv); 2539 cma_enable_remove(id_priv);
2533 return 0; 2540 return 0;
2534} 2541}
2535 2542