Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB: Add rdma_cap_ib_switch helper and use where appropriate

Persuant to Liran's comments on node_type on linux-rdma
mailing list:

In an effort to reform the RDMA core and ULPs to minimize use of
node_type in struct ib_device, an additional bit is added to
struct ib_device for is_switch (IB switch). This is needed
to be initialized by any IB switch device driver. This is a
NEW requirement on such device drivers which are all
"out of tree".

In addition, an ib_switch helper was added to ib_verbs.h
based on the is_switch device bit rather than node_type
(although those should be consistent).

The RDMA core (MAD, SMI, agent, sa_query, multicast, sysfs)
as well as (IPoIB and SRP) ULPs are updated where
appropriate to use this new helper. In some cases,
the helper is now used under the covers of using
rdma_[start end]_port rather than the open coding
previously used.

Reviewed-by: Sean Hefty <sean.hefty@intel.com>
Reviewed-By: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Tested-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Hal Rosenstock <hal@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>

authored by

Hal Rosenstock and committed by
Doug Ledford
4139032b bc0195aa

+66 -90
+2 -2
drivers/infiniband/core/agent.c
··· 88 88 struct ib_ah *ah; 89 89 struct ib_mad_send_wr_private *mad_send_wr; 90 90 91 - if (device->node_type == RDMA_NODE_IB_SWITCH) 91 + if (rdma_cap_ib_switch(device)) 92 92 port_priv = ib_get_agent_port(device, 0); 93 93 else 94 94 port_priv = ib_get_agent_port(device, port_num); ··· 122 122 memcpy(send_buf->mad, mad_hdr, resp_mad_len); 123 123 send_buf->ah = ah; 124 124 125 - if (device->node_type == RDMA_NODE_IB_SWITCH) { 125 + if (rdma_cap_ib_switch(device)) { 126 126 mad_send_wr = container_of(send_buf, 127 127 struct ib_mad_send_wr_private, 128 128 send_buf);
+16 -29
drivers/infiniband/core/mad.c
··· 769 769 bool opa = rdma_cap_opa_mad(mad_agent_priv->qp_info->port_priv->device, 770 770 mad_agent_priv->qp_info->port_priv->port_num); 771 771 772 - if (device->node_type == RDMA_NODE_IB_SWITCH && 772 + if (rdma_cap_ib_switch(device) && 773 773 smp->mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) 774 774 port_num = send_wr->wr.ud.port_num; 775 775 else ··· 787 787 if ((opa_get_smp_direction(opa_smp) 788 788 ? opa_smp->route.dr.dr_dlid : opa_smp->route.dr.dr_slid) == 789 789 OPA_LID_PERMISSIVE && 790 - opa_smi_handle_dr_smp_send(opa_smp, device->node_type, 790 + opa_smi_handle_dr_smp_send(opa_smp, 791 + rdma_cap_ib_switch(device), 791 792 port_num) == IB_SMI_DISCARD) { 792 793 ret = -EINVAL; 793 794 dev_err(&device->dev, "OPA Invalid directed route\n"); ··· 811 810 } else { 812 811 if ((ib_get_smp_direction(smp) ? smp->dr_dlid : smp->dr_slid) == 813 812 IB_LID_PERMISSIVE && 814 - smi_handle_dr_smp_send(smp, device->node_type, port_num) == 813 + smi_handle_dr_smp_send(smp, rdma_cap_ib_switch(device), port_num) == 815 814 IB_SMI_DISCARD) { 816 815 ret = -EINVAL; 817 816 dev_err(&device->dev, "Invalid directed route\n"); ··· 2031 2030 struct ib_smp *smp = (struct ib_smp *)recv->mad; 2032 2031 2033 2032 if (smi_handle_dr_smp_recv(smp, 2034 - port_priv->device->node_type, 2033 + rdma_cap_ib_switch(port_priv->device), 2035 2034 port_num, 2036 2035 port_priv->device->phys_port_cnt) == 2037 2036 IB_SMI_DISCARD) ··· 2043 2042 2044 2043 if (retsmi == IB_SMI_SEND) { /* don't forward */ 2045 2044 if (smi_handle_dr_smp_send(smp, 2046 - port_priv->device->node_type, 2045 + rdma_cap_ib_switch(port_priv->device), 2047 2046 port_num) == IB_SMI_DISCARD) 2048 2047 return IB_SMI_DISCARD; 2049 2048 2050 2049 if (smi_check_local_smp(smp, port_priv->device) == IB_SMI_DISCARD) 2051 2050 return IB_SMI_DISCARD; 2052 - } else if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH) { 2051 + } else if (rdma_cap_ib_switch(port_priv->device)) { 2053 2052 /* forward case for switches */ 2054 2053 memcpy(response, recv, mad_priv_size(response)); 2055 2054 response->header.recv_wc.wc = &response->header.wc; ··· 2116 2115 struct opa_smp *smp = (struct opa_smp *)recv->mad; 2117 2116 2118 2117 if (opa_smi_handle_dr_smp_recv(smp, 2119 - port_priv->device->node_type, 2118 + rdma_cap_ib_switch(port_priv->device), 2120 2119 port_num, 2121 2120 port_priv->device->phys_port_cnt) == 2122 2121 IB_SMI_DISCARD) ··· 2128 2127 2129 2128 if (retsmi == IB_SMI_SEND) { /* don't forward */ 2130 2129 if (opa_smi_handle_dr_smp_send(smp, 2131 - port_priv->device->node_type, 2130 + rdma_cap_ib_switch(port_priv->device), 2132 2131 port_num) == IB_SMI_DISCARD) 2133 2132 return IB_SMI_DISCARD; 2134 2133 ··· 2136 2135 IB_SMI_DISCARD) 2137 2136 return IB_SMI_DISCARD; 2138 2137 2139 - } else if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH) { 2138 + } else if (rdma_cap_ib_switch(port_priv->device)) { 2140 2139 /* forward case for switches */ 2141 2140 memcpy(response, recv, mad_priv_size(response)); 2142 2141 response->header.recv_wc.wc = &response->header.wc; ··· 2236 2235 goto out; 2237 2236 } 2238 2237 2239 - if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH) 2238 + if (rdma_cap_ib_switch(port_priv->device)) 2240 2239 port_num = wc->port_num; 2241 2240 else 2242 2241 port_num = port_priv->port_num; ··· 3298 3297 3299 3298 static void ib_mad_init_device(struct ib_device *device) 3300 3299 { 3301 - int start, end, i; 3300 + int start, i; 3302 3301 3303 - if (device->node_type == RDMA_NODE_IB_SWITCH) { 3304 - start = 0; 3305 - end = 0; 3306 - } else { 3307 - start = 1; 3308 - end = device->phys_port_cnt; 3309 - } 3302 + start = rdma_start_port(device); 3310 3303 3311 - for (i = start; i <= end; i++) { 3304 + for (i = start; i <= rdma_end_port(device); i++) { 3312 3305 if (!rdma_cap_ib_mad(device, i)) 3313 3306 continue; 3314 3307 ··· 3337 3342 3338 3343 static void ib_mad_remove_device(struct ib_device *device) 3339 3344 { 3340 - int start, end, i; 3345 + int i; 3341 3346 3342 - if (device->node_type == RDMA_NODE_IB_SWITCH) { 3343 - start = 0; 3344 - end = 0; 3345 - } else { 3346 - start = 1; 3347 - end = device->phys_port_cnt; 3348 - } 3349 - 3350 - for (i = start; i <= end; i++) { 3347 + for (i = rdma_start_port(device); i <= rdma_end_port(device); i++) { 3351 3348 if (!rdma_cap_ib_mad(device, i)) 3352 3349 continue; 3353 3350
+2 -6
drivers/infiniband/core/multicast.c
··· 812 812 if (!dev) 813 813 return; 814 814 815 - if (device->node_type == RDMA_NODE_IB_SWITCH) 816 - dev->start_port = dev->end_port = 0; 817 - else { 818 - dev->start_port = 1; 819 - dev->end_port = device->phys_port_cnt; 820 - } 815 + dev->start_port = rdma_start_port(device); 816 + dev->end_port = rdma_end_port(device); 821 817 822 818 for (i = 0; i <= dev->end_port - dev->start_port; i++) { 823 819 if (!rdma_cap_ib_mcast(device, dev->start_port + i))
+2 -2
drivers/infiniband/core/opa_smi.h
··· 39 39 40 40 #include "smi.h" 41 41 42 - enum smi_action opa_smi_handle_dr_smp_recv(struct opa_smp *smp, u8 node_type, 42 + enum smi_action opa_smi_handle_dr_smp_recv(struct opa_smp *smp, bool is_switch, 43 43 int port_num, int phys_port_cnt); 44 44 int opa_smi_get_fwd_port(struct opa_smp *smp); 45 45 extern enum smi_forward_action opa_smi_check_forward_dr_smp(struct opa_smp *smp); 46 46 extern enum smi_action opa_smi_handle_dr_smp_send(struct opa_smp *smp, 47 - u8 node_type, int port_num); 47 + bool is_switch, int port_num); 48 48 49 49 /* 50 50 * Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM
+2 -6
drivers/infiniband/core/sa_query.c
··· 1156 1156 int s, e, i; 1157 1157 int count = 0; 1158 1158 1159 - if (device->node_type == RDMA_NODE_IB_SWITCH) 1160 - s = e = 0; 1161 - else { 1162 - s = 1; 1163 - e = device->phys_port_cnt; 1164 - } 1159 + s = rdma_start_port(device); 1160 + e = rdma_end_port(device); 1165 1161 1166 1162 sa_dev = kzalloc(sizeof *sa_dev + 1167 1163 (e - s + 1) * sizeof (struct ib_sa_port),
+18 -19
drivers/infiniband/core/smi.c
··· 41 41 #include "smi.h" 42 42 #include "opa_smi.h" 43 43 44 - static enum smi_action __smi_handle_dr_smp_send(u8 node_type, int port_num, 44 + static enum smi_action __smi_handle_dr_smp_send(bool is_switch, int port_num, 45 45 u8 *hop_ptr, u8 hop_cnt, 46 46 const u8 *initial_path, 47 47 const u8 *return_path, ··· 64 64 65 65 /* C14-9:2 */ 66 66 if (*hop_ptr && *hop_ptr < hop_cnt) { 67 - if (node_type != RDMA_NODE_IB_SWITCH) 67 + if (!is_switch) 68 68 return IB_SMI_DISCARD; 69 69 70 70 /* return_path set when received */ ··· 77 77 if (*hop_ptr == hop_cnt) { 78 78 /* return_path set when received */ 79 79 (*hop_ptr)++; 80 - return (node_type == RDMA_NODE_IB_SWITCH || 80 + return (is_switch || 81 81 dr_dlid_is_permissive ? 82 82 IB_SMI_HANDLE : IB_SMI_DISCARD); 83 83 } ··· 96 96 97 97 /* C14-13:2 */ 98 98 if (2 <= *hop_ptr && *hop_ptr <= hop_cnt) { 99 - if (node_type != RDMA_NODE_IB_SWITCH) 99 + if (!is_switch) 100 100 return IB_SMI_DISCARD; 101 101 102 102 (*hop_ptr)--; ··· 108 108 if (*hop_ptr == 1) { 109 109 (*hop_ptr)--; 110 110 /* C14-13:3 -- SMPs destined for SM shouldn't be here */ 111 - return (node_type == RDMA_NODE_IB_SWITCH || 111 + return (is_switch || 112 112 dr_slid_is_permissive ? 113 113 IB_SMI_HANDLE : IB_SMI_DISCARD); 114 114 } ··· 127 127 * Return IB_SMI_DISCARD if the SMP should be discarded 128 128 */ 129 129 enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp, 130 - u8 node_type, int port_num) 130 + bool is_switch, int port_num) 131 131 { 132 - return __smi_handle_dr_smp_send(node_type, port_num, 132 + return __smi_handle_dr_smp_send(is_switch, port_num, 133 133 &smp->hop_ptr, smp->hop_cnt, 134 134 smp->initial_path, 135 135 smp->return_path, ··· 139 139 } 140 140 141 141 enum smi_action opa_smi_handle_dr_smp_send(struct opa_smp *smp, 142 - u8 node_type, int port_num) 142 + bool is_switch, int port_num) 143 143 { 144 - return __smi_handle_dr_smp_send(node_type, port_num, 144 + return __smi_handle_dr_smp_send(is_switch, port_num, 145 145 &smp->hop_ptr, smp->hop_cnt, 146 146 smp->route.dr.initial_path, 147 147 smp->route.dr.return_path, ··· 152 152 OPA_LID_PERMISSIVE); 153 153 } 154 154 155 - static enum smi_action __smi_handle_dr_smp_recv(u8 node_type, int port_num, 155 + static enum smi_action __smi_handle_dr_smp_recv(bool is_switch, int port_num, 156 156 int phys_port_cnt, 157 157 u8 *hop_ptr, u8 hop_cnt, 158 158 const u8 *initial_path, ··· 173 173 174 174 /* C14-9:2 -- intermediate hop */ 175 175 if (*hop_ptr && *hop_ptr < hop_cnt) { 176 - if (node_type != RDMA_NODE_IB_SWITCH) 176 + if (!is_switch) 177 177 return IB_SMI_DISCARD; 178 178 179 179 return_path[*hop_ptr] = port_num; ··· 188 188 return_path[*hop_ptr] = port_num; 189 189 /* hop_ptr updated when sending */ 190 190 191 - return (node_type == RDMA_NODE_IB_SWITCH || 191 + return (is_switch || 192 192 dr_dlid_is_permissive ? 193 193 IB_SMI_HANDLE : IB_SMI_DISCARD); 194 194 } ··· 208 208 209 209 /* C14-13:2 */ 210 210 if (2 <= *hop_ptr && *hop_ptr <= hop_cnt) { 211 - if (node_type != RDMA_NODE_IB_SWITCH) 211 + if (!is_switch) 212 212 return IB_SMI_DISCARD; 213 213 214 214 /* hop_ptr updated when sending */ ··· 224 224 return IB_SMI_HANDLE; 225 225 } 226 226 /* hop_ptr updated when sending */ 227 - return (node_type == RDMA_NODE_IB_SWITCH ? 228 - IB_SMI_HANDLE : IB_SMI_DISCARD); 227 + return (is_switch ? IB_SMI_HANDLE : IB_SMI_DISCARD); 229 228 } 230 229 231 230 /* C14-13:4 -- hop_ptr = 0 -> give to SM */ ··· 237 238 * Adjust information for a received SMP 238 239 * Return IB_SMI_DISCARD if the SMP should be dropped 239 240 */ 240 - enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type, 241 + enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, bool is_switch, 241 242 int port_num, int phys_port_cnt) 242 243 { 243 - return __smi_handle_dr_smp_recv(node_type, port_num, phys_port_cnt, 244 + return __smi_handle_dr_smp_recv(is_switch, port_num, phys_port_cnt, 244 245 &smp->hop_ptr, smp->hop_cnt, 245 246 smp->initial_path, 246 247 smp->return_path, ··· 253 254 * Adjust information for a received SMP 254 255 * Return IB_SMI_DISCARD if the SMP should be dropped 255 256 */ 256 - enum smi_action opa_smi_handle_dr_smp_recv(struct opa_smp *smp, u8 node_type, 257 + enum smi_action opa_smi_handle_dr_smp_recv(struct opa_smp *smp, bool is_switch, 257 258 int port_num, int phys_port_cnt) 258 259 { 259 - return __smi_handle_dr_smp_recv(node_type, port_num, phys_port_cnt, 260 + return __smi_handle_dr_smp_recv(is_switch, port_num, phys_port_cnt, 260 261 &smp->hop_ptr, smp->hop_cnt, 261 262 smp->route.dr.initial_path, 262 263 smp->route.dr.return_path,
+2 -2
drivers/infiniband/core/smi.h
··· 51 51 IB_SMI_FORWARD /* SMP should be forwarded (for switches only) */ 52 52 }; 53 53 54 - enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type, 54 + enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, bool is_switch, 55 55 int port_num, int phys_port_cnt); 56 56 int smi_get_fwd_port(struct ib_smp *smp); 57 57 extern enum smi_forward_action smi_check_forward_dr_smp(struct ib_smp *smp); 58 58 extern enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp, 59 - u8 node_type, int port_num); 59 + bool is_switch, int port_num); 60 60 61 61 /* 62 62 * Return IB_SMI_HANDLE if the SMP should be handled by the local SMA/SM
+1 -1
drivers/infiniband/core/sysfs.c
··· 870 870 goto err_put; 871 871 } 872 872 873 - if (device->node_type == RDMA_NODE_IB_SWITCH) { 873 + if (rdma_cap_ib_switch(device)) { 874 874 ret = add_port(device, 0, port_callback); 875 875 if (ret) 876 876 goto err_put;
+2 -10
drivers/infiniband/ulp/ipoib/ipoib_main.c
··· 1684 1684 struct list_head *dev_list; 1685 1685 struct net_device *dev; 1686 1686 struct ipoib_dev_priv *priv; 1687 - int s, e, p; 1687 + int p; 1688 1688 int count = 0; 1689 1689 1690 1690 dev_list = kmalloc(sizeof *dev_list, GFP_KERNEL); ··· 1693 1693 1694 1694 INIT_LIST_HEAD(dev_list); 1695 1695 1696 - if (device->node_type == RDMA_NODE_IB_SWITCH) { 1697 - s = 0; 1698 - e = 0; 1699 - } else { 1700 - s = 1; 1701 - e = device->phys_port_cnt; 1702 - } 1703 - 1704 - for (p = s; p <= e; ++p) { 1696 + for (p = rdma_start_port(device); p <= rdma_end_port(device); ++p) { 1705 1697 if (!rdma_protocol_ib(device, p)) 1706 1698 continue; 1707 1699 dev = ipoib_add_port("ib%d", device, p);
+2 -10
drivers/infiniband/ulp/srp/ib_srp.c
··· 3379 3379 struct srp_device *srp_dev; 3380 3380 struct ib_device_attr *dev_attr; 3381 3381 struct srp_host *host; 3382 - int mr_page_shift, s, e, p; 3382 + int mr_page_shift, p; 3383 3383 u64 max_pages_per_mr; 3384 3384 3385 3385 dev_attr = kmalloc(sizeof *dev_attr, GFP_KERNEL); ··· 3443 3443 if (IS_ERR(srp_dev->mr)) 3444 3444 goto err_pd; 3445 3445 3446 - if (device->node_type == RDMA_NODE_IB_SWITCH) { 3447 - s = 0; 3448 - e = 0; 3449 - } else { 3450 - s = 1; 3451 - e = device->phys_port_cnt; 3452 - } 3453 - 3454 - for (p = s; p <= e; ++p) { 3446 + for (p = rdma_start_port(device); p <= rdma_end_port(device); ++p) { 3455 3447 host = srp_add_port(srp_dev, p); 3456 3448 if (host) 3457 3449 list_add_tail(&host->list, &srp_dev->dev_list);
+17 -3
include/rdma/ib_verbs.h
··· 1745 1745 char node_desc[64]; 1746 1746 __be64 node_guid; 1747 1747 u32 local_dma_lkey; 1748 + u16 is_switch:1; 1748 1749 u8 node_type; 1749 1750 u8 phys_port_cnt; 1750 1751 ··· 1825 1824 u8 port_num); 1826 1825 1827 1826 /** 1827 + * rdma_cap_ib_switch - Check if the device is IB switch 1828 + * @device: Device to check 1829 + * 1830 + * Device driver is responsible for setting is_switch bit on 1831 + * in ib_device structure at init time. 1832 + * 1833 + * Return: true if the device is IB switch. 1834 + */ 1835 + static inline bool rdma_cap_ib_switch(const struct ib_device *device) 1836 + { 1837 + return device->is_switch; 1838 + } 1839 + 1840 + /** 1828 1841 * rdma_start_port - Return the first valid port number for the device 1829 1842 * specified 1830 1843 * ··· 1848 1833 */ 1849 1834 static inline u8 rdma_start_port(const struct ib_device *device) 1850 1835 { 1851 - return (device->node_type == RDMA_NODE_IB_SWITCH) ? 0 : 1; 1836 + return rdma_cap_ib_switch(device) ? 0 : 1; 1852 1837 } 1853 1838 1854 1839 /** ··· 1861 1846 */ 1862 1847 static inline u8 rdma_end_port(const struct ib_device *device) 1863 1848 { 1864 - return (device->node_type == RDMA_NODE_IB_SWITCH) ? 1865 - 0 : device->phys_port_cnt; 1849 + return rdma_cap_ib_switch(device) ? 0 : device->phys_port_cnt; 1866 1850 } 1867 1851 1868 1852 static inline bool rdma_protocol_ib(const struct ib_device *device, u8 port_num)