diff options
Diffstat (limited to 'drivers/infiniband/core/cma.c')
-rw-r--r-- | drivers/infiniband/core/cma.c | 67 |
1 files changed, 41 insertions, 26 deletions
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 367aa75ac338..de7d2501a740 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -603,46 +603,54 @@ static int cma_translate_addr(struct sockaddr *addr, struct rdma_dev_addr *dev_a | |||
603 | return ret; | 603 | return ret; |
604 | } | 604 | } |
605 | 605 | ||
606 | static inline int cma_validate_port(struct ib_device *device, u8 port, | 606 | static const struct ib_gid_attr * |
607 | enum ib_gid_type gid_type, | 607 | cma_validate_port(struct ib_device *device, u8 port, |
608 | union ib_gid *gid, | 608 | enum ib_gid_type gid_type, |
609 | struct rdma_id_private *id_priv) | 609 | union ib_gid *gid, |
610 | struct rdma_id_private *id_priv) | ||
610 | { | 611 | { |
611 | struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr; | 612 | struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr; |
612 | int bound_if_index = dev_addr->bound_dev_if; | 613 | int bound_if_index = dev_addr->bound_dev_if; |
614 | const struct ib_gid_attr *sgid_attr; | ||
613 | int dev_type = dev_addr->dev_type; | 615 | int dev_type = dev_addr->dev_type; |
614 | struct net_device *ndev = NULL; | 616 | struct net_device *ndev = NULL; |
615 | int ret = -ENODEV; | ||
616 | 617 | ||
617 | if ((dev_type == ARPHRD_INFINIBAND) && !rdma_protocol_ib(device, port)) | 618 | if ((dev_type == ARPHRD_INFINIBAND) && !rdma_protocol_ib(device, port)) |
618 | return ret; | 619 | return ERR_PTR(-ENODEV); |
619 | 620 | ||
620 | if ((dev_type != ARPHRD_INFINIBAND) && rdma_protocol_ib(device, port)) | 621 | if ((dev_type != ARPHRD_INFINIBAND) && rdma_protocol_ib(device, port)) |
621 | return ret; | 622 | return ERR_PTR(-ENODEV); |
622 | 623 | ||
623 | if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port)) { | 624 | if (dev_type == ARPHRD_ETHER && rdma_protocol_roce(device, port)) { |
624 | ndev = dev_get_by_index(dev_addr->net, bound_if_index); | 625 | ndev = dev_get_by_index(dev_addr->net, bound_if_index); |
625 | if (!ndev) | 626 | if (!ndev) |
626 | return ret; | 627 | return ERR_PTR(-ENODEV); |
627 | } else { | 628 | } else { |
628 | gid_type = IB_GID_TYPE_IB; | 629 | gid_type = IB_GID_TYPE_IB; |
629 | } | 630 | } |
630 | 631 | ||
631 | ret = ib_find_cached_gid_by_port(device, gid, gid_type, port, | 632 | sgid_attr = rdma_find_gid_by_port(device, gid, gid_type, port, ndev); |
632 | ndev, NULL); | ||
633 | |||
634 | if (ndev) | 633 | if (ndev) |
635 | dev_put(ndev); | 634 | dev_put(ndev); |
635 | return sgid_attr; | ||
636 | } | ||
636 | 637 | ||
637 | return ret; | 638 | static void cma_bind_sgid_attr(struct rdma_id_private *id_priv, |
639 | const struct ib_gid_attr *sgid_attr) | ||
640 | { | ||
641 | WARN_ON(id_priv->id.route.addr.dev_addr.sgid_attr); | ||
642 | id_priv->id.route.addr.dev_addr.sgid_attr = sgid_attr; | ||
638 | } | 643 | } |
639 | 644 | ||
640 | static int cma_acquire_dev(struct rdma_id_private *id_priv, | 645 | static int cma_acquire_dev(struct rdma_id_private *id_priv, |
641 | struct rdma_id_private *listen_id_priv) | 646 | struct rdma_id_private *listen_id_priv) |
642 | { | 647 | { |
643 | struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr; | 648 | struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr; |
649 | const struct ib_gid_attr *sgid_attr; | ||
644 | struct cma_device *cma_dev; | 650 | struct cma_device *cma_dev; |
645 | union ib_gid gid, iboe_gid, *gidp; | 651 | union ib_gid gid, iboe_gid, *gidp; |
652 | enum ib_gid_type gid_type; | ||
653 | enum ib_gid_type default_type; | ||
646 | int ret = -ENODEV; | 654 | int ret = -ENODEV; |
647 | u8 port; | 655 | u8 port; |
648 | 656 | ||
@@ -662,14 +670,15 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv, | |||
662 | port = listen_id_priv->id.port_num; | 670 | port = listen_id_priv->id.port_num; |
663 | gidp = rdma_protocol_roce(cma_dev->device, port) ? | 671 | gidp = rdma_protocol_roce(cma_dev->device, port) ? |
664 | &iboe_gid : &gid; | 672 | &iboe_gid : &gid; |
665 | 673 | gid_type = rdma_protocol_ib(cma_dev->device, port) ? | |
666 | ret = cma_validate_port(cma_dev->device, port, | 674 | IB_GID_TYPE_IB : |
667 | rdma_protocol_ib(cma_dev->device, port) ? | 675 | listen_id_priv->gid_type; |
668 | IB_GID_TYPE_IB : | 676 | sgid_attr = cma_validate_port(cma_dev->device, port, |
669 | listen_id_priv->gid_type, gidp, | 677 | gid_type, gidp, id_priv); |
670 | id_priv); | 678 | if (!IS_ERR(sgid_attr)) { |
671 | if (!ret) { | ||
672 | id_priv->id.port_num = port; | 679 | id_priv->id.port_num = port; |
680 | cma_bind_sgid_attr(id_priv, sgid_attr); | ||
681 | ret = 0; | ||
673 | goto out; | 682 | goto out; |
674 | } | 683 | } |
675 | } | 684 | } |
@@ -683,14 +692,16 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv, | |||
683 | 692 | ||
684 | gidp = rdma_protocol_roce(cma_dev->device, port) ? | 693 | gidp = rdma_protocol_roce(cma_dev->device, port) ? |
685 | &iboe_gid : &gid; | 694 | &iboe_gid : &gid; |
686 | 695 | default_type = cma_dev->default_gid_type[port - 1]; | |
687 | ret = cma_validate_port(cma_dev->device, port, | 696 | gid_type = |
688 | rdma_protocol_ib(cma_dev->device, port) ? | 697 | rdma_protocol_ib(cma_dev->device, port) ? |
689 | IB_GID_TYPE_IB : | 698 | IB_GID_TYPE_IB : default_type; |
690 | cma_dev->default_gid_type[port - 1], | 699 | sgid_attr = cma_validate_port(cma_dev->device, port, |
691 | gidp, id_priv); | 700 | gid_type, gidp, id_priv); |
692 | if (!ret) { | 701 | if (!IS_ERR(sgid_attr)) { |
693 | id_priv->id.port_num = port; | 702 | id_priv->id.port_num = port; |
703 | cma_bind_sgid_attr(id_priv, sgid_attr); | ||
704 | ret = 0; | ||
694 | goto out; | 705 | goto out; |
695 | } | 706 | } |
696 | } | 707 | } |
@@ -1706,6 +1717,10 @@ void rdma_destroy_id(struct rdma_cm_id *id) | |||
1706 | cma_deref_id(id_priv->id.context); | 1717 | cma_deref_id(id_priv->id.context); |
1707 | 1718 | ||
1708 | kfree(id_priv->id.route.path_rec); | 1719 | kfree(id_priv->id.route.path_rec); |
1720 | |||
1721 | if (id_priv->id.route.addr.dev_addr.sgid_attr) | ||
1722 | rdma_put_gid_attr(id_priv->id.route.addr.dev_addr.sgid_attr); | ||
1723 | |||
1709 | put_net(id_priv->id.route.addr.dev_addr.net); | 1724 | put_net(id_priv->id.route.addr.dev_addr.net); |
1710 | kfree(id_priv); | 1725 | kfree(id_priv); |
1711 | } | 1726 | } |