diff options
| -rw-r--r-- | drivers/infiniband/core/cma.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index c62ff9e7f8c6..dadc486b92f0 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
| @@ -349,7 +349,8 @@ static int cma_translate_addr(struct sockaddr *addr, struct rdma_dev_addr *dev_a | |||
| 349 | return ret; | 349 | return ret; |
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | static int cma_acquire_dev(struct rdma_id_private *id_priv) | 352 | static int cma_acquire_dev(struct rdma_id_private *id_priv, |
| 353 | struct rdma_id_private *listen_id_priv) | ||
| 353 | { | 354 | { |
| 354 | struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr; | 355 | struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr; |
| 355 | struct cma_device *cma_dev; | 356 | struct cma_device *cma_dev; |
| @@ -367,8 +368,30 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv) | |||
| 367 | iboe_addr_get_sgid(dev_addr, &iboe_gid); | 368 | iboe_addr_get_sgid(dev_addr, &iboe_gid); |
| 368 | memcpy(&gid, dev_addr->src_dev_addr + | 369 | memcpy(&gid, dev_addr->src_dev_addr + |
| 369 | rdma_addr_gid_offset(dev_addr), sizeof gid); | 370 | rdma_addr_gid_offset(dev_addr), sizeof gid); |
| 371 | if (listen_id_priv && | ||
| 372 | rdma_port_get_link_layer(listen_id_priv->id.device, | ||
| 373 | listen_id_priv->id.port_num) == dev_ll) { | ||
| 374 | cma_dev = listen_id_priv->cma_dev; | ||
| 375 | port = listen_id_priv->id.port_num; | ||
| 376 | if (rdma_node_get_transport(cma_dev->device->node_type) == RDMA_TRANSPORT_IB && | ||
| 377 | rdma_port_get_link_layer(cma_dev->device, port) == IB_LINK_LAYER_ETHERNET) | ||
| 378 | ret = ib_find_cached_gid(cma_dev->device, &iboe_gid, | ||
| 379 | &found_port, NULL); | ||
| 380 | else | ||
| 381 | ret = ib_find_cached_gid(cma_dev->device, &gid, | ||
| 382 | &found_port, NULL); | ||
| 383 | |||
| 384 | if (!ret && (port == found_port)) { | ||
| 385 | id_priv->id.port_num = found_port; | ||
| 386 | goto out; | ||
| 387 | } | ||
| 388 | } | ||
| 370 | list_for_each_entry(cma_dev, &dev_list, list) { | 389 | list_for_each_entry(cma_dev, &dev_list, list) { |
| 371 | for (port = 1; port <= cma_dev->device->phys_port_cnt; ++port) | 390 | for (port = 1; port <= cma_dev->device->phys_port_cnt; ++port) { |
| 391 | if (listen_id_priv && | ||
| 392 | listen_id_priv->cma_dev == cma_dev && | ||
| 393 | listen_id_priv->id.port_num == port) | ||
| 394 | continue; | ||
| 372 | if (rdma_port_get_link_layer(cma_dev->device, port) == dev_ll) { | 395 | if (rdma_port_get_link_layer(cma_dev->device, port) == dev_ll) { |
| 373 | if (rdma_node_get_transport(cma_dev->device->node_type) == RDMA_TRANSPORT_IB && | 396 | if (rdma_node_get_transport(cma_dev->device->node_type) == RDMA_TRANSPORT_IB && |
| 374 | rdma_port_get_link_layer(cma_dev->device, port) == IB_LINK_LAYER_ETHERNET) | 397 | rdma_port_get_link_layer(cma_dev->device, port) == IB_LINK_LAYER_ETHERNET) |
| @@ -381,6 +404,7 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv) | |||
| 381 | goto out; | 404 | goto out; |
| 382 | } | 405 | } |
| 383 | } | 406 | } |
| 407 | } | ||
| 384 | } | 408 | } |
| 385 | 409 | ||
| 386 | out: | 410 | out: |
| @@ -1269,7 +1293,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
| 1269 | } | 1293 | } |
| 1270 | 1294 | ||
| 1271 | mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING); | 1295 | mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING); |
| 1272 | ret = cma_acquire_dev(conn_id); | 1296 | ret = cma_acquire_dev(conn_id, listen_id); |
| 1273 | if (ret) | 1297 | if (ret) |
| 1274 | goto err2; | 1298 | goto err2; |
| 1275 | 1299 | ||
| @@ -1458,7 +1482,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, | |||
| 1458 | goto out; | 1482 | goto out; |
| 1459 | } | 1483 | } |
| 1460 | 1484 | ||
| 1461 | ret = cma_acquire_dev(conn_id); | 1485 | ret = cma_acquire_dev(conn_id, listen_id); |
| 1462 | if (ret) { | 1486 | if (ret) { |
| 1463 | mutex_unlock(&conn_id->handler_mutex); | 1487 | mutex_unlock(&conn_id->handler_mutex); |
| 1464 | rdma_destroy_id(new_cm_id); | 1488 | rdma_destroy_id(new_cm_id); |
| @@ -2027,7 +2051,7 @@ static void addr_handler(int status, struct sockaddr *src_addr, | |||
| 2027 | goto out; | 2051 | goto out; |
| 2028 | 2052 | ||
| 2029 | if (!status && !id_priv->cma_dev) | 2053 | if (!status && !id_priv->cma_dev) |
| 2030 | status = cma_acquire_dev(id_priv); | 2054 | status = cma_acquire_dev(id_priv, NULL); |
| 2031 | 2055 | ||
| 2032 | if (status) { | 2056 | if (status) { |
| 2033 | if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_RESOLVED, | 2057 | if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_RESOLVED, |
| @@ -2524,7 +2548,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) | |||
| 2524 | if (ret) | 2548 | if (ret) |
| 2525 | goto err1; | 2549 | goto err1; |
| 2526 | 2550 | ||
| 2527 | ret = cma_acquire_dev(id_priv); | 2551 | ret = cma_acquire_dev(id_priv, NULL); |
| 2528 | if (ret) | 2552 | if (ret) |
| 2529 | goto err1; | 2553 | goto err1; |
| 2530 | } | 2554 | } |
