diff options
author | Parav Pandit <parav@mellanox.com> | 2018-06-19 03:59:17 -0400 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2018-06-25 16:19:56 -0400 |
commit | 4ed13a5f2d606d2e6bcc5b8adbf08ed52e76cbb5 (patch) | |
tree | f4289925cd27eca09c789bd20498722030684d65 | |
parent | aa74f4878d61c83244ad8613082989b60a566ca4 (diff) |
IB/cm: Keep track of the sgid_attr that created the cm id
Hold reference to the the sgid_attr which is used in a cm_id until the
cm_id is destroyed.
Signed-off-by: Parav Pandit <parav@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
-rw-r--r-- | drivers/infiniband/core/cma.c | 67 | ||||
-rw-r--r-- | include/rdma/ib_addr.h | 2 |
2 files changed, 43 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 | } |
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index c2c8b1fdeead..715394f6d18a 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h | |||
@@ -58,6 +58,7 @@ | |||
58 | * @bound_dev_if: An optional device interface index. | 58 | * @bound_dev_if: An optional device interface index. |
59 | * @transport: The transport type used. | 59 | * @transport: The transport type used. |
60 | * @net: Network namespace containing the bound_dev_if net_dev. | 60 | * @net: Network namespace containing the bound_dev_if net_dev. |
61 | * @sgid_attr: GID attribute to use for identified SGID | ||
61 | */ | 62 | */ |
62 | struct rdma_dev_addr { | 63 | struct rdma_dev_addr { |
63 | unsigned char src_dev_addr[MAX_ADDR_LEN]; | 64 | unsigned char src_dev_addr[MAX_ADDR_LEN]; |
@@ -67,6 +68,7 @@ struct rdma_dev_addr { | |||
67 | int bound_dev_if; | 68 | int bound_dev_if; |
68 | enum rdma_transport_type transport; | 69 | enum rdma_transport_type transport; |
69 | struct net *net; | 70 | struct net *net; |
71 | const struct ib_gid_attr *sgid_attr; | ||
70 | enum rdma_network_type network; | 72 | enum rdma_network_type network; |
71 | int hoplimit; | 73 | int hoplimit; |
72 | }; | 74 | }; |