diff options
author | Jason Gunthorpe <jgg@mellanox.com> | 2018-06-05 01:40:20 -0400 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2018-06-18 13:09:05 -0400 |
commit | c3d71b69a75cbbc03c8f43571b003ddadd40d056 (patch) | |
tree | 3eb21122ae12813cfb49e1fe8920011e4327316b /drivers/infiniband/core/cache.c | |
parent | ddb457c6993babbcdd41fca638b870d2a2fc3941 (diff) |
IB/core: Provide rdma_ versions of the gid cache API
These versions are functionally similar but all return gid_attrs and
related information via reference instead of via copy.
The old API is preserved, implemented as wrappers around the new, until
all callers can be converted.
Signed-off-by: Parav Pandit <parav@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'drivers/infiniband/core/cache.c')
-rw-r--r-- | drivers/infiniband/core/cache.c | 264 |
1 files changed, 161 insertions, 103 deletions
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index d92525fb47c7..8a06e743c2dd 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c | |||
@@ -649,80 +649,37 @@ static int __ib_cache_gid_get(struct ib_device *ib_dev, u8 port, int index, | |||
649 | return 0; | 649 | return 0; |
650 | } | 650 | } |
651 | 651 | ||
652 | static int _ib_cache_gid_table_find(struct ib_device *ib_dev, | ||
653 | const union ib_gid *gid, | ||
654 | const struct ib_gid_attr *val, | ||
655 | unsigned long mask, | ||
656 | u8 *port, u16 *index) | ||
657 | { | ||
658 | struct ib_gid_table *table; | ||
659 | u8 p; | ||
660 | int local_index; | ||
661 | unsigned long flags; | ||
662 | |||
663 | for (p = 0; p < ib_dev->phys_port_cnt; p++) { | ||
664 | table = ib_dev->cache.ports[p].gid; | ||
665 | read_lock_irqsave(&table->rwlock, flags); | ||
666 | local_index = find_gid(table, gid, val, false, mask, NULL); | ||
667 | if (local_index >= 0) { | ||
668 | if (index) | ||
669 | *index = local_index; | ||
670 | if (port) | ||
671 | *port = p + rdma_start_port(ib_dev); | ||
672 | read_unlock_irqrestore(&table->rwlock, flags); | ||
673 | return 0; | ||
674 | } | ||
675 | read_unlock_irqrestore(&table->rwlock, flags); | ||
676 | } | ||
677 | |||
678 | return -ENOENT; | ||
679 | } | ||
680 | |||
681 | static int ib_cache_gid_find(struct ib_device *ib_dev, | ||
682 | const union ib_gid *gid, | ||
683 | enum ib_gid_type gid_type, | ||
684 | struct net_device *ndev, u8 *port, | ||
685 | u16 *index) | ||
686 | { | ||
687 | unsigned long mask = GID_ATTR_FIND_MASK_GID | | ||
688 | GID_ATTR_FIND_MASK_GID_TYPE; | ||
689 | struct ib_gid_attr gid_attr_val = {.ndev = ndev, .gid_type = gid_type}; | ||
690 | |||
691 | if (ndev) | ||
692 | mask |= GID_ATTR_FIND_MASK_NETDEV; | ||
693 | |||
694 | return _ib_cache_gid_table_find(ib_dev, gid, &gid_attr_val, | ||
695 | mask, port, index); | ||
696 | } | ||
697 | |||
698 | /** | 652 | /** |
699 | * ib_find_cached_gid_by_port - Returns the GID table index where a specified | 653 | * rdma_find_gid_by_port - Returns the GID entry attributes when it finds |
700 | * GID value occurs. It searches for the specified GID value in the local | 654 | * a valid GID entry for given search parameters. It searches for the specified |
701 | * software cache. | 655 | * GID value in the local software cache. |
702 | * @device: The device to query. | 656 | * @device: The device to query. |
703 | * @gid: The GID value to search for. | 657 | * @gid: The GID value to search for. |
704 | * @gid_type: The GID type to search for. | 658 | * @gid_type: The GID type to search for. |
705 | * @port_num: The port number of the device where the GID value should be | 659 | * @port_num: The port number of the device where the GID value should be |
706 | * searched. | 660 | * searched. |
707 | * @ndev: In RoCE, the net device of the device. Null means ignore. | 661 | * @ndev: In RoCE, the net device of the device. NULL means ignore. |
708 | * @index: The index into the cached GID table where the GID was found. This | 662 | * |
709 | * parameter may be NULL. | 663 | * Returns sgid attributes if the GID is found with valid reference or |
664 | * returns ERR_PTR for the error. | ||
665 | * The caller must invoke rdma_put_gid_attr() to release the reference. | ||
710 | */ | 666 | */ |
711 | int ib_find_cached_gid_by_port(struct ib_device *ib_dev, | 667 | const struct ib_gid_attr * |
712 | const union ib_gid *gid, | 668 | rdma_find_gid_by_port(struct ib_device *ib_dev, |
713 | enum ib_gid_type gid_type, | 669 | const union ib_gid *gid, |
714 | u8 port, struct net_device *ndev, | 670 | enum ib_gid_type gid_type, |
715 | u16 *index) | 671 | u8 port, struct net_device *ndev) |
716 | { | 672 | { |
717 | int local_index; | 673 | int local_index; |
718 | struct ib_gid_table *table; | 674 | struct ib_gid_table *table; |
719 | unsigned long mask = GID_ATTR_FIND_MASK_GID | | 675 | unsigned long mask = GID_ATTR_FIND_MASK_GID | |
720 | GID_ATTR_FIND_MASK_GID_TYPE; | 676 | GID_ATTR_FIND_MASK_GID_TYPE; |
721 | struct ib_gid_attr val = {.ndev = ndev, .gid_type = gid_type}; | 677 | struct ib_gid_attr val = {.ndev = ndev, .gid_type = gid_type}; |
678 | const struct ib_gid_attr *attr; | ||
722 | unsigned long flags; | 679 | unsigned long flags; |
723 | 680 | ||
724 | if (!rdma_is_port_valid(ib_dev, port)) | 681 | if (!rdma_is_port_valid(ib_dev, port)) |
725 | return -ENOENT; | 682 | return ERR_PTR(-ENOENT); |
726 | 683 | ||
727 | table = rdma_gid_table(ib_dev, port); | 684 | table = rdma_gid_table(ib_dev, port); |
728 | 685 | ||
@@ -732,55 +689,49 @@ int ib_find_cached_gid_by_port(struct ib_device *ib_dev, | |||
732 | read_lock_irqsave(&table->rwlock, flags); | 689 | read_lock_irqsave(&table->rwlock, flags); |
733 | local_index = find_gid(table, gid, &val, false, mask, NULL); | 690 | local_index = find_gid(table, gid, &val, false, mask, NULL); |
734 | if (local_index >= 0) { | 691 | if (local_index >= 0) { |
735 | if (index) | 692 | get_gid_entry(table->data_vec[local_index]); |
736 | *index = local_index; | 693 | attr = &table->data_vec[local_index]->attr; |
737 | read_unlock_irqrestore(&table->rwlock, flags); | 694 | read_unlock_irqrestore(&table->rwlock, flags); |
738 | return 0; | 695 | return attr; |
739 | } | 696 | } |
740 | 697 | ||
741 | read_unlock_irqrestore(&table->rwlock, flags); | 698 | read_unlock_irqrestore(&table->rwlock, flags); |
742 | return -ENOENT; | 699 | return ERR_PTR(-ENOENT); |
743 | } | 700 | } |
744 | EXPORT_SYMBOL(ib_find_cached_gid_by_port); | 701 | EXPORT_SYMBOL(rdma_find_gid_by_port); |
745 | 702 | ||
746 | /** | 703 | /** |
747 | * ib_cache_gid_find_by_filter - Returns the GID table index where a specified | 704 | * rdma_find_gid_by_filter - Returns the GID table attribute where a |
748 | * GID value occurs | 705 | * specified GID value occurs |
749 | * @device: The device to query. | 706 | * @device: The device to query. |
750 | * @gid: The GID value to search for. | 707 | * @gid: The GID value to search for. |
751 | * @port_num: The port number of the device where the GID value could be | 708 | * @port: The port number of the device where the GID value could be |
752 | * searched. | 709 | * searched. |
753 | * @filter: The filter function is executed on any matching GID in the table. | 710 | * @filter: The filter function is executed on any matching GID in the table. |
754 | * If the filter function returns true, the corresponding index is returned, | 711 | * If the filter function returns true, the corresponding index is returned, |
755 | * otherwise, we continue searching the GID table. It's guaranteed that | 712 | * otherwise, we continue searching the GID table. It's guaranteed that |
756 | * while filter is executed, ndev field is valid and the structure won't | 713 | * while filter is executed, ndev field is valid and the structure won't |
757 | * change. filter is executed in an atomic context. filter must not be NULL. | 714 | * change. filter is executed in an atomic context. filter must not be NULL. |
758 | * @index: The index into the cached GID table where the GID was found. This | ||
759 | * parameter may be NULL. | ||
760 | * | 715 | * |
761 | * ib_cache_gid_find_by_filter() searches for the specified GID value | 716 | * rdma_find_gid_by_filter() searches for the specified GID value |
762 | * of which the filter function returns true in the port's GID table. | 717 | * of which the filter function returns true in the port's GID table. |
763 | * This function is only supported on RoCE ports. | 718 | * This function is only supported on RoCE ports. |
764 | * | 719 | * |
765 | */ | 720 | */ |
766 | static int ib_cache_gid_find_by_filter(struct ib_device *ib_dev, | 721 | const struct ib_gid_attr *rdma_find_gid_by_filter( |
767 | const union ib_gid *gid, | 722 | struct ib_device *ib_dev, const union ib_gid *gid, u8 port, |
768 | u8 port, | 723 | bool (*filter)(const union ib_gid *gid, const struct ib_gid_attr *, |
769 | bool (*filter)(const union ib_gid *, | 724 | void *), |
770 | const struct ib_gid_attr *, | 725 | void *context) |
771 | void *), | ||
772 | void *context, | ||
773 | u16 *index) | ||
774 | { | 726 | { |
727 | const struct ib_gid_attr *res = ERR_PTR(-ENOENT); | ||
775 | struct ib_gid_table *table; | 728 | struct ib_gid_table *table; |
776 | unsigned int i; | ||
777 | unsigned long flags; | 729 | unsigned long flags; |
778 | bool found = false; | 730 | unsigned int i; |
779 | |||
780 | 731 | ||
781 | if (!rdma_is_port_valid(ib_dev, port) || | 732 | if (!rdma_is_port_valid(ib_dev, port) || |
782 | !rdma_protocol_roce(ib_dev, port)) | 733 | !rdma_protocol_roce(ib_dev, port)) |
783 | return -EPROTONOSUPPORT; | 734 | return ERR_PTR(-EPROTONOSUPPORT); |
784 | 735 | ||
785 | table = rdma_gid_table(ib_dev, port); | 736 | table = rdma_gid_table(ib_dev, port); |
786 | 737 | ||
@@ -798,18 +749,34 @@ static int ib_cache_gid_find_by_filter(struct ib_device *ib_dev, | |||
798 | memcpy(&attr, &table->data_vec[i]->attr, sizeof(attr)); | 749 | memcpy(&attr, &table->data_vec[i]->attr, sizeof(attr)); |
799 | 750 | ||
800 | if (filter(gid, &attr, context)) { | 751 | if (filter(gid, &attr, context)) { |
801 | found = true; | 752 | get_gid_entry(table->data_vec[i]); |
802 | if (index) | 753 | res = &table->data_vec[i]->attr; |
803 | *index = i; | ||
804 | break; | 754 | break; |
805 | } | 755 | } |
806 | } | 756 | } |
807 | read_unlock_irqrestore(&table->rwlock, flags); | 757 | read_unlock_irqrestore(&table->rwlock, flags); |
758 | return res; | ||
759 | } | ||
760 | |||
761 | int ib_find_cached_gid_by_port(struct ib_device *ib_dev, | ||
762 | const union ib_gid *gid, | ||
763 | enum ib_gid_type gid_type, | ||
764 | u8 port, struct net_device *ndev, | ||
765 | u16 *index) | ||
766 | { | ||
767 | const struct ib_gid_attr *res; | ||
808 | 768 | ||
809 | if (!found) | 769 | res = rdma_find_gid_by_port(ib_dev, gid, gid_type, port, ndev); |
810 | return -ENOENT; | 770 | if (IS_ERR(res)) |
771 | return PTR_ERR(res); | ||
772 | |||
773 | if (index) | ||
774 | *index = res->index; | ||
775 | rdma_put_gid_attr(res); | ||
811 | return 0; | 776 | return 0; |
777 | |||
812 | } | 778 | } |
779 | EXPORT_SYMBOL(ib_find_cached_gid_by_port); | ||
813 | 780 | ||
814 | static struct ib_gid_table *alloc_gid_table(int sz) | 781 | static struct ib_gid_table *alloc_gid_table(int sz) |
815 | { | 782 | { |
@@ -1016,27 +983,109 @@ int ib_get_cached_gid(struct ib_device *device, | |||
1016 | EXPORT_SYMBOL(ib_get_cached_gid); | 983 | EXPORT_SYMBOL(ib_get_cached_gid); |
1017 | 984 | ||
1018 | /** | 985 | /** |
1019 | * ib_find_cached_gid - Returns the port number and GID table index where | 986 | * rdma_query_gid - Read the GID content from the GID software cache |
1020 | * a specified GID value occurs. | 987 | * @device: Device to query the GID |
988 | * @port_num: Port number of the device | ||
989 | * @index: Index of the GID table entry to read | ||
990 | * @gid: Pointer to GID where to store the entry's GID | ||
991 | * | ||
992 | * rdma_query_gid() only reads the GID entry content for requested device, | ||
993 | * port and index. It reads for IB, RoCE and iWarp link layers. It doesn't | ||
994 | * hold any reference to the GID table entry in the HCA or software cache. | ||
995 | * | ||
996 | * Returns 0 on success or appropriate error code. | ||
997 | * | ||
998 | */ | ||
999 | int rdma_query_gid(struct ib_device *device, u8 port_num, | ||
1000 | int index, union ib_gid *gid) | ||
1001 | { | ||
1002 | struct ib_gid_table *table; | ||
1003 | unsigned long flags; | ||
1004 | int res = -EINVAL; | ||
1005 | |||
1006 | if (!rdma_is_port_valid(device, port_num)) | ||
1007 | return -EINVAL; | ||
1008 | |||
1009 | table = rdma_gid_table(device, port_num); | ||
1010 | read_lock_irqsave(&table->rwlock, flags); | ||
1011 | |||
1012 | if (index < 0 || index >= table->sz || | ||
1013 | !is_gid_entry_valid(table->data_vec[index])) | ||
1014 | goto done; | ||
1015 | |||
1016 | memcpy(gid, &table->data_vec[index]->attr.gid, sizeof(*gid)); | ||
1017 | res = 0; | ||
1018 | |||
1019 | done: | ||
1020 | read_unlock_irqrestore(&table->rwlock, flags); | ||
1021 | return res; | ||
1022 | } | ||
1023 | EXPORT_SYMBOL(rdma_query_gid); | ||
1024 | |||
1025 | /** | ||
1026 | * rdma_find_gid - Returns SGID attributes if the matching GID is found. | ||
1021 | * @device: The device to query. | 1027 | * @device: The device to query. |
1022 | * @gid: The GID value to search for. | 1028 | * @gid: The GID value to search for. |
1023 | * @gid_type: The GID type to search for. | 1029 | * @gid_type: The GID type to search for. |
1024 | * @ndev: In RoCE, the net device of the device. NULL means ignore. | 1030 | * @ndev: In RoCE, the net device of the device. NULL means ignore. |
1025 | * @port_num: The port number of the device where the GID value was found. | ||
1026 | * @index: The index into the cached GID table where the GID was found. This | ||
1027 | * parameter may be NULL. | ||
1028 | * | 1031 | * |
1029 | * ib_find_cached_gid() searches for the specified GID value in | 1032 | * rdma_find_gid() searches for the specified GID value in the software cache. |
1030 | * the local software cache. | 1033 | * |
1034 | * Returns GID attributes if a valid GID is found or returns ERR_PTR for the | ||
1035 | * error. The caller must invoke rdma_put_gid_attr() to release the reference. | ||
1036 | * | ||
1031 | */ | 1037 | */ |
1032 | int ib_find_cached_gid(struct ib_device *device, | 1038 | const struct ib_gid_attr *rdma_find_gid(struct ib_device *device, |
1033 | const union ib_gid *gid, | 1039 | const union ib_gid *gid, |
1034 | enum ib_gid_type gid_type, | 1040 | enum ib_gid_type gid_type, |
1035 | struct net_device *ndev, | 1041 | struct net_device *ndev) |
1036 | u8 *port_num, | ||
1037 | u16 *index) | ||
1038 | { | 1042 | { |
1039 | return ib_cache_gid_find(device, gid, gid_type, ndev, port_num, index); | 1043 | unsigned long mask = GID_ATTR_FIND_MASK_GID | |
1044 | GID_ATTR_FIND_MASK_GID_TYPE; | ||
1045 | struct ib_gid_attr gid_attr_val = {.ndev = ndev, .gid_type = gid_type}; | ||
1046 | u8 p; | ||
1047 | |||
1048 | if (ndev) | ||
1049 | mask |= GID_ATTR_FIND_MASK_NETDEV; | ||
1050 | |||
1051 | for (p = 0; p < device->phys_port_cnt; p++) { | ||
1052 | struct ib_gid_table *table; | ||
1053 | unsigned long flags; | ||
1054 | int index; | ||
1055 | |||
1056 | table = device->cache.ports[p].gid; | ||
1057 | read_lock_irqsave(&table->rwlock, flags); | ||
1058 | index = find_gid(table, gid, &gid_attr_val, false, mask, NULL); | ||
1059 | if (index >= 0) { | ||
1060 | const struct ib_gid_attr *attr; | ||
1061 | |||
1062 | get_gid_entry(table->data_vec[index]); | ||
1063 | attr = &table->data_vec[index]->attr; | ||
1064 | read_unlock_irqrestore(&table->rwlock, flags); | ||
1065 | return attr; | ||
1066 | } | ||
1067 | read_unlock_irqrestore(&table->rwlock, flags); | ||
1068 | } | ||
1069 | |||
1070 | return ERR_PTR(-ENOENT); | ||
1071 | } | ||
1072 | EXPORT_SYMBOL(rdma_find_gid); | ||
1073 | |||
1074 | int ib_find_cached_gid(struct ib_device *device, const union ib_gid *gid, | ||
1075 | enum ib_gid_type gid_type, struct net_device *ndev, | ||
1076 | u8 *port_num, u16 *index) | ||
1077 | { | ||
1078 | const struct ib_gid_attr *res; | ||
1079 | |||
1080 | res = rdma_find_gid(device, gid, gid_type, ndev); | ||
1081 | if (IS_ERR(res)) | ||
1082 | return PTR_ERR(res); | ||
1083 | if (port_num) | ||
1084 | *port_num = res->port_num; | ||
1085 | if (index) | ||
1086 | *index = res->index; | ||
1087 | rdma_put_gid_attr(res); | ||
1088 | return 0; | ||
1040 | } | 1089 | } |
1041 | EXPORT_SYMBOL(ib_find_cached_gid); | 1090 | EXPORT_SYMBOL(ib_find_cached_gid); |
1042 | 1091 | ||
@@ -1048,13 +1097,22 @@ int ib_find_gid_by_filter(struct ib_device *device, | |||
1048 | void *), | 1097 | void *), |
1049 | void *context, u16 *index) | 1098 | void *context, u16 *index) |
1050 | { | 1099 | { |
1100 | const struct ib_gid_attr *res; | ||
1101 | |||
1051 | /* Only RoCE GID table supports filter function */ | 1102 | /* Only RoCE GID table supports filter function */ |
1052 | if (!rdma_protocol_roce(device, port_num) && filter) | 1103 | if (!rdma_protocol_roce(device, port_num) && filter) |
1053 | return -EPROTONOSUPPORT; | 1104 | return -EPROTONOSUPPORT; |
1054 | 1105 | ||
1055 | return ib_cache_gid_find_by_filter(device, gid, | 1106 | res = rdma_find_gid_by_filter(device, gid, port_num, filter, |
1056 | port_num, filter, | 1107 | context); |
1057 | context, index); | 1108 | if (IS_ERR(res)) |
1109 | return PTR_ERR(res); | ||
1110 | |||
1111 | if (index) | ||
1112 | *index = res->index; | ||
1113 | |||
1114 | rdma_put_gid_attr(res); | ||
1115 | return 0; | ||
1058 | } | 1116 | } |
1059 | 1117 | ||
1060 | int ib_get_cached_pkey(struct ib_device *device, | 1118 | int ib_get_cached_pkey(struct ib_device *device, |