aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/cma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/core/cma.c')
-rw-r--r--drivers/infiniband/core/cma.c67
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
606static inline int cma_validate_port(struct ib_device *device, u8 port, 606static const struct ib_gid_attr *
607 enum ib_gid_type gid_type, 607cma_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; 638static 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
640static int cma_acquire_dev(struct rdma_id_private *id_priv, 645static 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}