aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/cm.c32
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
1403error3: atomic_dec(&cm_id_priv->refcount); 1414rejected:
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); 1417destroy:
1406error2: kfree(cm_id_priv->timewait_info); 1418 ib_destroy_cm_id(cm_id);
1407 cm_id_priv->timewait_info = NULL;
1408error1: ib_destroy_cm_id(&cm_id_priv->id);
1409 return ret; 1419 return ret;
1410} 1420}
1411 1421