diff options
author | Zhu Yanjun <yanjun.zhu@oracle.com> | 2017-03-07 02:48:36 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-03-09 16:09:18 -0500 |
commit | 3b12f73a5c2977153f28a224392fd4729b50d1dc (patch) | |
tree | dc78465b72a0aeaed26e1fdb4e7baac6b9c92db5 /net/rds/ib_cm.c | |
parent | 67e303e0c7683957eb4e530453705a43a6d4f966 (diff) |
rds: ib: add error handle
In the function rds_ib_setup_qp, the error handle is missing. When some
error occurs, it is possible that memory leak occurs. As such, error
handle is added.
Cc: Joe Jin <joe.jin@oracle.com>
Reviewed-by: Junxiao Bi <junxiao.bi@oracle.com>
Reviewed-by: Guanglei Li <guanglei.li@oracle.com>
Signed-off-by: Zhu Yanjun <yanjun.zhu@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/rds/ib_cm.c')
-rw-r--r-- | net/rds/ib_cm.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index ce3775abc6e7..1c38d2c7caa8 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c | |||
@@ -442,7 +442,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
442 | ic->i_send_cq = NULL; | 442 | ic->i_send_cq = NULL; |
443 | ibdev_put_vector(rds_ibdev, ic->i_scq_vector); | 443 | ibdev_put_vector(rds_ibdev, ic->i_scq_vector); |
444 | rdsdebug("ib_create_cq send failed: %d\n", ret); | 444 | rdsdebug("ib_create_cq send failed: %d\n", ret); |
445 | goto out; | 445 | goto rds_ibdev_out; |
446 | } | 446 | } |
447 | 447 | ||
448 | ic->i_rcq_vector = ibdev_get_unused_vector(rds_ibdev); | 448 | ic->i_rcq_vector = ibdev_get_unused_vector(rds_ibdev); |
@@ -456,19 +456,19 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
456 | ic->i_recv_cq = NULL; | 456 | ic->i_recv_cq = NULL; |
457 | ibdev_put_vector(rds_ibdev, ic->i_rcq_vector); | 457 | ibdev_put_vector(rds_ibdev, ic->i_rcq_vector); |
458 | rdsdebug("ib_create_cq recv failed: %d\n", ret); | 458 | rdsdebug("ib_create_cq recv failed: %d\n", ret); |
459 | goto out; | 459 | goto send_cq_out; |
460 | } | 460 | } |
461 | 461 | ||
462 | ret = ib_req_notify_cq(ic->i_send_cq, IB_CQ_NEXT_COMP); | 462 | ret = ib_req_notify_cq(ic->i_send_cq, IB_CQ_NEXT_COMP); |
463 | if (ret) { | 463 | if (ret) { |
464 | rdsdebug("ib_req_notify_cq send failed: %d\n", ret); | 464 | rdsdebug("ib_req_notify_cq send failed: %d\n", ret); |
465 | goto out; | 465 | goto recv_cq_out; |
466 | } | 466 | } |
467 | 467 | ||
468 | ret = ib_req_notify_cq(ic->i_recv_cq, IB_CQ_SOLICITED); | 468 | ret = ib_req_notify_cq(ic->i_recv_cq, IB_CQ_SOLICITED); |
469 | if (ret) { | 469 | if (ret) { |
470 | rdsdebug("ib_req_notify_cq recv failed: %d\n", ret); | 470 | rdsdebug("ib_req_notify_cq recv failed: %d\n", ret); |
471 | goto out; | 471 | goto recv_cq_out; |
472 | } | 472 | } |
473 | 473 | ||
474 | /* XXX negotiate max send/recv with remote? */ | 474 | /* XXX negotiate max send/recv with remote? */ |
@@ -494,7 +494,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
494 | ret = rdma_create_qp(ic->i_cm_id, ic->i_pd, &attr); | 494 | ret = rdma_create_qp(ic->i_cm_id, ic->i_pd, &attr); |
495 | if (ret) { | 495 | if (ret) { |
496 | rdsdebug("rdma_create_qp failed: %d\n", ret); | 496 | rdsdebug("rdma_create_qp failed: %d\n", ret); |
497 | goto out; | 497 | goto recv_cq_out; |
498 | } | 498 | } |
499 | 499 | ||
500 | ic->i_send_hdrs = ib_dma_alloc_coherent(dev, | 500 | ic->i_send_hdrs = ib_dma_alloc_coherent(dev, |
@@ -504,7 +504,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
504 | if (!ic->i_send_hdrs) { | 504 | if (!ic->i_send_hdrs) { |
505 | ret = -ENOMEM; | 505 | ret = -ENOMEM; |
506 | rdsdebug("ib_dma_alloc_coherent send failed\n"); | 506 | rdsdebug("ib_dma_alloc_coherent send failed\n"); |
507 | goto out; | 507 | goto qp_out; |
508 | } | 508 | } |
509 | 509 | ||
510 | ic->i_recv_hdrs = ib_dma_alloc_coherent(dev, | 510 | ic->i_recv_hdrs = ib_dma_alloc_coherent(dev, |
@@ -514,7 +514,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
514 | if (!ic->i_recv_hdrs) { | 514 | if (!ic->i_recv_hdrs) { |
515 | ret = -ENOMEM; | 515 | ret = -ENOMEM; |
516 | rdsdebug("ib_dma_alloc_coherent recv failed\n"); | 516 | rdsdebug("ib_dma_alloc_coherent recv failed\n"); |
517 | goto out; | 517 | goto send_hdrs_dma_out; |
518 | } | 518 | } |
519 | 519 | ||
520 | ic->i_ack = ib_dma_alloc_coherent(dev, sizeof(struct rds_header), | 520 | ic->i_ack = ib_dma_alloc_coherent(dev, sizeof(struct rds_header), |
@@ -522,7 +522,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
522 | if (!ic->i_ack) { | 522 | if (!ic->i_ack) { |
523 | ret = -ENOMEM; | 523 | ret = -ENOMEM; |
524 | rdsdebug("ib_dma_alloc_coherent ack failed\n"); | 524 | rdsdebug("ib_dma_alloc_coherent ack failed\n"); |
525 | goto out; | 525 | goto recv_hdrs_dma_out; |
526 | } | 526 | } |
527 | 527 | ||
528 | ic->i_sends = vzalloc_node(ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work), | 528 | ic->i_sends = vzalloc_node(ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work), |
@@ -530,7 +530,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
530 | if (!ic->i_sends) { | 530 | if (!ic->i_sends) { |
531 | ret = -ENOMEM; | 531 | ret = -ENOMEM; |
532 | rdsdebug("send allocation failed\n"); | 532 | rdsdebug("send allocation failed\n"); |
533 | goto out; | 533 | goto ack_dma_out; |
534 | } | 534 | } |
535 | 535 | ||
536 | ic->i_recvs = vzalloc_node(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work), | 536 | ic->i_recvs = vzalloc_node(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work), |
@@ -538,7 +538,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
538 | if (!ic->i_recvs) { | 538 | if (!ic->i_recvs) { |
539 | ret = -ENOMEM; | 539 | ret = -ENOMEM; |
540 | rdsdebug("recv allocation failed\n"); | 540 | rdsdebug("recv allocation failed\n"); |
541 | goto out; | 541 | goto sends_out; |
542 | } | 542 | } |
543 | 543 | ||
544 | rds_ib_recv_init_ack(ic); | 544 | rds_ib_recv_init_ack(ic); |
@@ -546,8 +546,33 @@ static int rds_ib_setup_qp(struct rds_connection *conn) | |||
546 | rdsdebug("conn %p pd %p cq %p %p\n", conn, ic->i_pd, | 546 | rdsdebug("conn %p pd %p cq %p %p\n", conn, ic->i_pd, |
547 | ic->i_send_cq, ic->i_recv_cq); | 547 | ic->i_send_cq, ic->i_recv_cq); |
548 | 548 | ||
549 | out: | 549 | return ret; |
550 | |||
551 | sends_out: | ||
552 | vfree(ic->i_sends); | ||
553 | ack_dma_out: | ||
554 | ib_dma_free_coherent(dev, sizeof(struct rds_header), | ||
555 | ic->i_ack, ic->i_ack_dma); | ||
556 | recv_hdrs_dma_out: | ||
557 | ib_dma_free_coherent(dev, ic->i_recv_ring.w_nr * | ||
558 | sizeof(struct rds_header), | ||
559 | ic->i_recv_hdrs, ic->i_recv_hdrs_dma); | ||
560 | send_hdrs_dma_out: | ||
561 | ib_dma_free_coherent(dev, ic->i_send_ring.w_nr * | ||
562 | sizeof(struct rds_header), | ||
563 | ic->i_send_hdrs, ic->i_send_hdrs_dma); | ||
564 | qp_out: | ||
565 | rdma_destroy_qp(ic->i_cm_id); | ||
566 | recv_cq_out: | ||
567 | if (!ib_destroy_cq(ic->i_recv_cq)) | ||
568 | ic->i_recv_cq = NULL; | ||
569 | send_cq_out: | ||
570 | if (!ib_destroy_cq(ic->i_send_cq)) | ||
571 | ic->i_send_cq = NULL; | ||
572 | rds_ibdev_out: | ||
573 | rds_ib_remove_conn(rds_ibdev, conn); | ||
550 | rds_ib_dev_put(rds_ibdev); | 574 | rds_ib_dev_put(rds_ibdev); |
575 | |||
551 | return ret; | 576 | return ret; |
552 | } | 577 | } |
553 | 578 | ||