diff options
-rw-r--r-- | drivers/infiniband/core/cm.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 0df1454819ac..1aad33e03528 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -1354,7 +1354,7 @@ static int cm_req_handler(struct cm_work *work) | |||
1354 | id.local_id); | 1354 | id.local_id); |
1355 | if (IS_ERR(cm_id_priv->timewait_info)) { | 1355 | if (IS_ERR(cm_id_priv->timewait_info)) { |
1356 | ret = PTR_ERR(cm_id_priv->timewait_info); | 1356 | ret = PTR_ERR(cm_id_priv->timewait_info); |
1357 | goto error1; | 1357 | goto destroy; |
1358 | } | 1358 | } |
1359 | cm_id_priv->timewait_info->work.remote_id = req_msg->local_comm_id; | 1359 | cm_id_priv->timewait_info->work.remote_id = req_msg->local_comm_id; |
1360 | cm_id_priv->timewait_info->remote_ca_guid = req_msg->local_ca_guid; | 1360 | cm_id_priv->timewait_info->remote_ca_guid = req_msg->local_ca_guid; |
@@ -1363,7 +1363,8 @@ static int cm_req_handler(struct cm_work *work) | |||
1363 | listen_cm_id_priv = cm_match_req(work, cm_id_priv); | 1363 | listen_cm_id_priv = cm_match_req(work, cm_id_priv); |
1364 | if (!listen_cm_id_priv) { | 1364 | if (!listen_cm_id_priv) { |
1365 | ret = -EINVAL; | 1365 | ret = -EINVAL; |
1366 | goto error2; | 1366 | kfree(cm_id_priv->timewait_info); |
1367 | goto destroy; | ||
1367 | } | 1368 | } |
1368 | 1369 | ||
1369 | cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler; | 1370 | cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler; |
@@ -1373,12 +1374,22 @@ static int cm_req_handler(struct cm_work *work) | |||
1373 | 1374 | ||
1374 | cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]); | 1375 | cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]); |
1375 | ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av); | 1376 | ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av); |
1376 | if (ret) | 1377 | if (ret) { |
1377 | goto error3; | 1378 | ib_get_cached_gid(work->port->cm_dev->device, |
1379 | work->port->port_num, 0, &work->path[0].sgid); | ||
1380 | ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_GID, | ||
1381 | &work->path[0].sgid, sizeof work->path[0].sgid, | ||
1382 | NULL, 0); | ||
1383 | goto rejected; | ||
1384 | } | ||
1378 | if (req_msg->alt_local_lid) { | 1385 | if (req_msg->alt_local_lid) { |
1379 | ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av); | 1386 | ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av); |
1380 | if (ret) | 1387 | if (ret) { |
1381 | goto error3; | 1388 | ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_ALT_GID, |
1389 | &work->path[0].sgid, | ||
1390 | sizeof work->path[0].sgid, NULL, 0); | ||
1391 | goto rejected; | ||
1392 | } | ||
1382 | } | 1393 | } |
1383 | cm_id_priv->tid = req_msg->hdr.tid; | 1394 | cm_id_priv->tid = req_msg->hdr.tid; |
1384 | cm_id_priv->timeout_ms = cm_convert_to_ms( | 1395 | cm_id_priv->timeout_ms = cm_convert_to_ms( |
@@ -1400,12 +1411,11 @@ static int cm_req_handler(struct cm_work *work) | |||
1400 | cm_deref_id(listen_cm_id_priv); | 1411 | cm_deref_id(listen_cm_id_priv); |
1401 | return 0; | 1412 | return 0; |
1402 | 1413 | ||
1403 | error3: atomic_dec(&cm_id_priv->refcount); | 1414 | rejected: |
1415 | atomic_dec(&cm_id_priv->refcount); | ||
1404 | cm_deref_id(listen_cm_id_priv); | 1416 | cm_deref_id(listen_cm_id_priv); |
1405 | cm_cleanup_timewait(cm_id_priv->timewait_info); | 1417 | destroy: |
1406 | error2: kfree(cm_id_priv->timewait_info); | 1418 | ib_destroy_cm_id(cm_id); |
1407 | cm_id_priv->timewait_info = NULL; | ||
1408 | error1: ib_destroy_cm_id(&cm_id_priv->id); | ||
1409 | return ret; | 1419 | return ret; |
1410 | } | 1420 | } |
1411 | 1421 | ||