| .. | .. |
|---|
| 52 | 52 | #include <linux/inetdevice.h> |
|---|
| 53 | 53 | #include <rdma/ib_cache.h> |
|---|
| 54 | 54 | |
|---|
| 55 | | -#define DRV_VERSION "1.0.0" |
|---|
| 56 | | - |
|---|
| 57 | | -const char ipoib_driver_version[] = DRV_VERSION; |
|---|
| 58 | | - |
|---|
| 59 | 55 | MODULE_AUTHOR("Roland Dreier"); |
|---|
| 60 | 56 | MODULE_DESCRIPTION("IP-over-InfiniBand net driver"); |
|---|
| 61 | 57 | MODULE_LICENSE("Dual BSD/GPL"); |
|---|
| .. | .. |
|---|
| 90 | 86 | |
|---|
| 91 | 87 | struct ib_sa_client ipoib_sa_client; |
|---|
| 92 | 88 | |
|---|
| 93 | | -static void ipoib_add_one(struct ib_device *device); |
|---|
| 89 | +static int ipoib_add_one(struct ib_device *device); |
|---|
| 94 | 90 | static void ipoib_remove_one(struct ib_device *device, void *client_data); |
|---|
| 95 | 91 | static void ipoib_neigh_reclaim(struct rcu_head *rp); |
|---|
| 96 | 92 | static struct net_device *ipoib_get_net_dev_by_params( |
|---|
| .. | .. |
|---|
| 167 | 163 | if (flags & IFF_UP) |
|---|
| 168 | 164 | continue; |
|---|
| 169 | 165 | |
|---|
| 170 | | - dev_change_flags(cpriv->dev, flags | IFF_UP); |
|---|
| 166 | + dev_change_flags(cpriv->dev, flags | IFF_UP, NULL); |
|---|
| 171 | 167 | } |
|---|
| 172 | 168 | up_read(&priv->vlan_rwsem); |
|---|
| 173 | 169 | } |
|---|
| .. | .. |
|---|
| 207 | 203 | if (!(flags & IFF_UP)) |
|---|
| 208 | 204 | continue; |
|---|
| 209 | 205 | |
|---|
| 210 | | - dev_change_flags(cpriv->dev, flags & ~IFF_UP); |
|---|
| 206 | + dev_change_flags(cpriv->dev, flags & ~IFF_UP, NULL); |
|---|
| 211 | 207 | } |
|---|
| 212 | 208 | up_read(&priv->vlan_rwsem); |
|---|
| 213 | 209 | } |
|---|
| .. | .. |
|---|
| 346 | 342 | struct net_device *result; |
|---|
| 347 | 343 | }; |
|---|
| 348 | 344 | |
|---|
| 349 | | -static int ipoib_upper_walk(struct net_device *upper, void *_data) |
|---|
| 345 | +static int ipoib_upper_walk(struct net_device *upper, |
|---|
| 346 | + struct netdev_nested_priv *priv) |
|---|
| 350 | 347 | { |
|---|
| 351 | | - struct ipoib_walk_data *data = _data; |
|---|
| 348 | + struct ipoib_walk_data *data = (struct ipoib_walk_data *)priv->data; |
|---|
| 352 | 349 | int ret = 0; |
|---|
| 353 | 350 | |
|---|
| 354 | 351 | if (ipoib_is_dev_match_addr_rcu(data->addr, upper)) { |
|---|
| .. | .. |
|---|
| 372 | 369 | static struct net_device *ipoib_get_net_dev_match_addr( |
|---|
| 373 | 370 | const struct sockaddr *addr, struct net_device *dev) |
|---|
| 374 | 371 | { |
|---|
| 372 | + struct netdev_nested_priv priv; |
|---|
| 375 | 373 | struct ipoib_walk_data data = { |
|---|
| 376 | 374 | .addr = addr, |
|---|
| 377 | 375 | }; |
|---|
| 378 | 376 | |
|---|
| 377 | + priv.data = (void *)&data; |
|---|
| 379 | 378 | rcu_read_lock(); |
|---|
| 380 | 379 | if (ipoib_is_dev_match_addr_rcu(addr, dev)) { |
|---|
| 381 | 380 | dev_hold(dev); |
|---|
| .. | .. |
|---|
| 383 | 382 | goto out; |
|---|
| 384 | 383 | } |
|---|
| 385 | 384 | |
|---|
| 386 | | - netdev_walk_all_upper_dev_rcu(dev, ipoib_upper_walk, &data); |
|---|
| 385 | + netdev_walk_all_upper_dev_rcu(dev, ipoib_upper_walk, &priv); |
|---|
| 387 | 386 | out: |
|---|
| 388 | 387 | rcu_read_unlock(); |
|---|
| 389 | 388 | return data.result; |
|---|
| .. | .. |
|---|
| 483 | 482 | if (ret) |
|---|
| 484 | 483 | return NULL; |
|---|
| 485 | 484 | |
|---|
| 486 | | - if (!dev_list) |
|---|
| 487 | | - return NULL; |
|---|
| 488 | | - |
|---|
| 489 | 485 | /* See if we can find a unique device matching the L2 parameters */ |
|---|
| 490 | 486 | matches = __ipoib_get_net_dev_by_params(dev_list, port, pkey_index, |
|---|
| 491 | 487 | gid, NULL, &net_dev); |
|---|
| .. | .. |
|---|
| 509 | 505 | default: |
|---|
| 510 | 506 | dev_warn_ratelimited(&dev->dev, |
|---|
| 511 | 507 | "duplicate IP address detected\n"); |
|---|
| 512 | | - /* Fall through */ |
|---|
| 508 | + fallthrough; |
|---|
| 513 | 509 | case 1: |
|---|
| 514 | 510 | return net_dev; |
|---|
| 515 | 511 | } |
|---|
| .. | .. |
|---|
| 533 | 529 | "will cause multicast packet drops\n"); |
|---|
| 534 | 530 | netdev_update_features(dev); |
|---|
| 535 | 531 | dev_set_mtu(dev, ipoib_cm_max_mtu(dev)); |
|---|
| 532 | + netif_set_real_num_tx_queues(dev, 1); |
|---|
| 536 | 533 | rtnl_unlock(); |
|---|
| 537 | 534 | priv->tx_wr.wr.send_flags &= ~IB_SEND_IP_CSUM; |
|---|
| 538 | 535 | |
|---|
| .. | .. |
|---|
| 544 | 541 | clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); |
|---|
| 545 | 542 | netdev_update_features(dev); |
|---|
| 546 | 543 | dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu)); |
|---|
| 544 | + netif_set_real_num_tx_queues(dev, dev->num_tx_queues); |
|---|
| 547 | 545 | rtnl_unlock(); |
|---|
| 548 | 546 | ipoib_flush_paths(dev); |
|---|
| 549 | 547 | return (!rtnl_trylock()) ? -EBUSY : 0; |
|---|
| .. | .. |
|---|
| 613 | 611 | while ((skb = __skb_dequeue(&path->queue))) |
|---|
| 614 | 612 | dev_kfree_skb_irq(skb); |
|---|
| 615 | 613 | |
|---|
| 616 | | - ipoib_dbg(ipoib_priv(dev), "path_free\n"); |
|---|
| 614 | + ipoib_dbg(ipoib_priv(dev), "%s\n", __func__); |
|---|
| 617 | 615 | |
|---|
| 618 | 616 | /* remove all neigh connected to this path */ |
|---|
| 619 | 617 | ipoib_del_neighs_by_gid(dev, path->pathrec.dgid.raw); |
|---|
| .. | .. |
|---|
| 1182 | 1180 | return NETDEV_TX_OK; |
|---|
| 1183 | 1181 | } |
|---|
| 1184 | 1182 | |
|---|
| 1185 | | -static void ipoib_timeout(struct net_device *dev) |
|---|
| 1183 | +static void ipoib_timeout(struct net_device *dev, unsigned int txqueue) |
|---|
| 1186 | 1184 | { |
|---|
| 1187 | 1185 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
|---|
| 1188 | 1186 | |
|---|
| .. | .. |
|---|
| 1643 | 1641 | { |
|---|
| 1644 | 1642 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
|---|
| 1645 | 1643 | |
|---|
| 1646 | | - ipoib_dbg(priv, "ipoib_neigh_hash_uninit\n"); |
|---|
| 1644 | + ipoib_dbg(priv, "%s\n", __func__); |
|---|
| 1647 | 1645 | init_completion(&priv->ntbl.deleted); |
|---|
| 1648 | 1646 | |
|---|
| 1649 | 1647 | cancel_delayed_work_sync(&priv->neigh_reap_task); |
|---|
| .. | .. |
|---|
| 1825 | 1823 | * running ensures the it will not add more work. |
|---|
| 1826 | 1824 | */ |
|---|
| 1827 | 1825 | rtnl_lock(); |
|---|
| 1828 | | - dev_change_flags(priv->dev, priv->dev->flags & ~IFF_UP); |
|---|
| 1826 | + dev_change_flags(priv->dev, priv->dev->flags & ~IFF_UP, NULL); |
|---|
| 1829 | 1827 | rtnl_unlock(); |
|---|
| 1830 | 1828 | |
|---|
| 1831 | 1829 | /* ipoib_event() cannot be running once this returns */ |
|---|
| .. | .. |
|---|
| 1864 | 1862 | priv->port); |
|---|
| 1865 | 1863 | return result; |
|---|
| 1866 | 1864 | } |
|---|
| 1867 | | - priv->max_ib_mtu = ib_mtu_enum_to_int(attr.max_mtu); |
|---|
| 1865 | + priv->max_ib_mtu = rdma_mtu_from_attr(priv->ca, priv->port, &attr); |
|---|
| 1868 | 1866 | |
|---|
| 1869 | 1867 | result = ib_query_pkey(priv->ca, priv->port, 0, &priv->pkey); |
|---|
| 1870 | 1868 | if (result) { |
|---|
| .. | .. |
|---|
| 1897 | 1895 | |
|---|
| 1898 | 1896 | priv->max_ib_mtu = ppriv->max_ib_mtu; |
|---|
| 1899 | 1897 | set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags); |
|---|
| 1900 | | - memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, INFINIBAND_ALEN); |
|---|
| 1901 | | - memcpy(&priv->local_gid, &ppriv->local_gid, sizeof(priv->local_gid)); |
|---|
| 1898 | + if (memchr_inv(priv->dev->dev_addr, 0, INFINIBAND_ALEN)) |
|---|
| 1899 | + memcpy(&priv->local_gid, priv->dev->dev_addr + 4, |
|---|
| 1900 | + sizeof(priv->local_gid)); |
|---|
| 1901 | + else { |
|---|
| 1902 | + memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, |
|---|
| 1903 | + INFINIBAND_ALEN); |
|---|
| 1904 | + memcpy(&priv->local_gid, &ppriv->local_gid, |
|---|
| 1905 | + sizeof(priv->local_gid)); |
|---|
| 1906 | + } |
|---|
| 1902 | 1907 | } |
|---|
| 1903 | 1908 | |
|---|
| 1904 | 1909 | static int ipoib_ndo_init(struct net_device *ndev) |
|---|
| 1905 | 1910 | { |
|---|
| 1906 | 1911 | struct ipoib_dev_priv *priv = ipoib_priv(ndev); |
|---|
| 1907 | 1912 | int rc; |
|---|
| 1913 | + struct rdma_netdev *rn = netdev_priv(ndev); |
|---|
| 1908 | 1914 | |
|---|
| 1909 | 1915 | if (priv->parent) { |
|---|
| 1910 | 1916 | ipoib_child_init(ndev); |
|---|
| .. | .. |
|---|
| 1917 | 1923 | /* MTU will be reset when mcast join happens */ |
|---|
| 1918 | 1924 | ndev->mtu = IPOIB_UD_MTU(priv->max_ib_mtu); |
|---|
| 1919 | 1925 | priv->mcast_mtu = priv->admin_mtu = ndev->mtu; |
|---|
| 1926 | + rn->mtu = priv->mcast_mtu; |
|---|
| 1920 | 1927 | ndev->max_mtu = IPOIB_CM_MTU; |
|---|
| 1921 | 1928 | |
|---|
| 1922 | 1929 | ndev->neigh_priv_len = sizeof(struct ipoib_neigh); |
|---|
| .. | .. |
|---|
| 2023 | 2030 | return ib_set_vf_guid(priv->ca, vf, priv->port, guid, type); |
|---|
| 2024 | 2031 | } |
|---|
| 2025 | 2032 | |
|---|
| 2033 | +static int ipoib_get_vf_guid(struct net_device *dev, int vf, |
|---|
| 2034 | + struct ifla_vf_guid *node_guid, |
|---|
| 2035 | + struct ifla_vf_guid *port_guid) |
|---|
| 2036 | +{ |
|---|
| 2037 | + struct ipoib_dev_priv *priv = ipoib_priv(dev); |
|---|
| 2038 | + |
|---|
| 2039 | + return ib_get_vf_guid(priv->ca, vf, priv->port, node_guid, port_guid); |
|---|
| 2040 | +} |
|---|
| 2041 | + |
|---|
| 2026 | 2042 | static int ipoib_get_vf_stats(struct net_device *dev, int vf, |
|---|
| 2027 | 2043 | struct ifla_vf_stats *vf_stats) |
|---|
| 2028 | 2044 | { |
|---|
| .. | .. |
|---|
| 2049 | 2065 | .ndo_set_vf_link_state = ipoib_set_vf_link_state, |
|---|
| 2050 | 2066 | .ndo_get_vf_config = ipoib_get_vf_config, |
|---|
| 2051 | 2067 | .ndo_get_vf_stats = ipoib_get_vf_stats, |
|---|
| 2068 | + .ndo_get_vf_guid = ipoib_get_vf_guid, |
|---|
| 2052 | 2069 | .ndo_set_vf_guid = ipoib_set_vf_guid, |
|---|
| 2053 | 2070 | .ndo_set_mac_address = ipoib_set_mac, |
|---|
| 2054 | 2071 | .ndo_get_stats64 = ipoib_get_stats, |
|---|
| .. | .. |
|---|
| 2070 | 2087 | .ndo_do_ioctl = ipoib_ioctl, |
|---|
| 2071 | 2088 | }; |
|---|
| 2072 | 2089 | |
|---|
| 2090 | +static const struct net_device_ops ipoib_netdev_default_pf = { |
|---|
| 2091 | + .ndo_init = ipoib_dev_init_default, |
|---|
| 2092 | + .ndo_uninit = ipoib_dev_uninit_default, |
|---|
| 2093 | + .ndo_open = ipoib_ib_dev_open_default, |
|---|
| 2094 | + .ndo_stop = ipoib_ib_dev_stop_default, |
|---|
| 2095 | +}; |
|---|
| 2096 | + |
|---|
| 2073 | 2097 | void ipoib_setup_common(struct net_device *dev) |
|---|
| 2074 | 2098 | { |
|---|
| 2075 | 2099 | dev->header_ops = &ipoib_header_ops; |
|---|
| 2100 | + dev->netdev_ops = &ipoib_netdev_default_pf; |
|---|
| 2076 | 2101 | |
|---|
| 2077 | 2102 | ipoib_set_ethtool_ops(dev); |
|---|
| 2078 | 2103 | |
|---|
| .. | .. |
|---|
| 2122 | 2147 | INIT_DELAYED_WORK(&priv->neigh_reap_task, ipoib_reap_neigh); |
|---|
| 2123 | 2148 | } |
|---|
| 2124 | 2149 | |
|---|
| 2125 | | -static const struct net_device_ops ipoib_netdev_default_pf = { |
|---|
| 2126 | | - .ndo_init = ipoib_dev_init_default, |
|---|
| 2127 | | - .ndo_uninit = ipoib_dev_uninit_default, |
|---|
| 2128 | | - .ndo_open = ipoib_ib_dev_open_default, |
|---|
| 2129 | | - .ndo_stop = ipoib_ib_dev_stop_default, |
|---|
| 2130 | | -}; |
|---|
| 2131 | | - |
|---|
| 2132 | | -static struct net_device |
|---|
| 2133 | | -*ipoib_create_netdev_default(struct ib_device *hca, |
|---|
| 2134 | | - const char *name, |
|---|
| 2135 | | - unsigned char name_assign_type, |
|---|
| 2136 | | - void (*setup)(struct net_device *)) |
|---|
| 2150 | +static struct net_device *ipoib_alloc_netdev(struct ib_device *hca, u8 port, |
|---|
| 2151 | + const char *name) |
|---|
| 2137 | 2152 | { |
|---|
| 2138 | 2153 | struct net_device *dev; |
|---|
| 2139 | | - struct rdma_netdev *rn; |
|---|
| 2140 | 2154 | |
|---|
| 2141 | | - dev = alloc_netdev((int)sizeof(struct rdma_netdev), |
|---|
| 2142 | | - name, |
|---|
| 2143 | | - name_assign_type, setup); |
|---|
| 2155 | + dev = rdma_alloc_netdev(hca, port, RDMA_NETDEV_IPOIB, name, |
|---|
| 2156 | + NET_NAME_UNKNOWN, ipoib_setup_common); |
|---|
| 2157 | + if (!IS_ERR(dev) || PTR_ERR(dev) != -EOPNOTSUPP) |
|---|
| 2158 | + return dev; |
|---|
| 2159 | + |
|---|
| 2160 | + dev = alloc_netdev(sizeof(struct rdma_netdev), name, NET_NAME_UNKNOWN, |
|---|
| 2161 | + ipoib_setup_common); |
|---|
| 2144 | 2162 | if (!dev) |
|---|
| 2145 | | - return NULL; |
|---|
| 2146 | | - |
|---|
| 2147 | | - rn = netdev_priv(dev); |
|---|
| 2148 | | - |
|---|
| 2149 | | - rn->send = ipoib_send; |
|---|
| 2150 | | - rn->attach_mcast = ipoib_mcast_attach; |
|---|
| 2151 | | - rn->detach_mcast = ipoib_mcast_detach; |
|---|
| 2152 | | - rn->hca = hca; |
|---|
| 2153 | | - dev->netdev_ops = &ipoib_netdev_default_pf; |
|---|
| 2154 | | - |
|---|
| 2163 | + return ERR_PTR(-ENOMEM); |
|---|
| 2155 | 2164 | return dev; |
|---|
| 2156 | 2165 | } |
|---|
| 2157 | 2166 | |
|---|
| 2158 | | -static struct net_device *ipoib_get_netdev(struct ib_device *hca, u8 port, |
|---|
| 2159 | | - const char *name) |
|---|
| 2167 | +int ipoib_intf_init(struct ib_device *hca, u8 port, const char *name, |
|---|
| 2168 | + struct net_device *dev) |
|---|
| 2160 | 2169 | { |
|---|
| 2161 | | - struct net_device *dev; |
|---|
| 2162 | | - |
|---|
| 2163 | | - if (hca->alloc_rdma_netdev) { |
|---|
| 2164 | | - dev = hca->alloc_rdma_netdev(hca, port, |
|---|
| 2165 | | - RDMA_NETDEV_IPOIB, name, |
|---|
| 2166 | | - NET_NAME_UNKNOWN, |
|---|
| 2167 | | - ipoib_setup_common); |
|---|
| 2168 | | - if (IS_ERR_OR_NULL(dev) && PTR_ERR(dev) != -EOPNOTSUPP) |
|---|
| 2169 | | - return NULL; |
|---|
| 2170 | | - } |
|---|
| 2171 | | - |
|---|
| 2172 | | - if (!hca->alloc_rdma_netdev || PTR_ERR(dev) == -EOPNOTSUPP) |
|---|
| 2173 | | - dev = ipoib_create_netdev_default(hca, name, NET_NAME_UNKNOWN, |
|---|
| 2174 | | - ipoib_setup_common); |
|---|
| 2175 | | - |
|---|
| 2176 | | - return dev; |
|---|
| 2177 | | -} |
|---|
| 2178 | | - |
|---|
| 2179 | | -struct ipoib_dev_priv *ipoib_intf_alloc(struct ib_device *hca, u8 port, |
|---|
| 2180 | | - const char *name) |
|---|
| 2181 | | -{ |
|---|
| 2182 | | - struct net_device *dev; |
|---|
| 2170 | + struct rdma_netdev *rn = netdev_priv(dev); |
|---|
| 2183 | 2171 | struct ipoib_dev_priv *priv; |
|---|
| 2184 | | - struct rdma_netdev *rn; |
|---|
| 2172 | + int rc; |
|---|
| 2185 | 2173 | |
|---|
| 2186 | 2174 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
|---|
| 2187 | 2175 | if (!priv) |
|---|
| 2188 | | - return NULL; |
|---|
| 2176 | + return -ENOMEM; |
|---|
| 2189 | 2177 | |
|---|
| 2190 | 2178 | priv->ca = hca; |
|---|
| 2191 | 2179 | priv->port = port; |
|---|
| 2192 | 2180 | |
|---|
| 2193 | | - dev = ipoib_get_netdev(hca, port, name); |
|---|
| 2194 | | - if (!dev) |
|---|
| 2195 | | - goto free_priv; |
|---|
| 2181 | + rc = rdma_init_netdev(hca, port, RDMA_NETDEV_IPOIB, name, |
|---|
| 2182 | + NET_NAME_UNKNOWN, ipoib_setup_common, dev); |
|---|
| 2183 | + if (rc) { |
|---|
| 2184 | + if (rc != -EOPNOTSUPP) |
|---|
| 2185 | + goto out; |
|---|
| 2186 | + |
|---|
| 2187 | + rn->send = ipoib_send; |
|---|
| 2188 | + rn->attach_mcast = ipoib_mcast_attach; |
|---|
| 2189 | + rn->detach_mcast = ipoib_mcast_detach; |
|---|
| 2190 | + rn->hca = hca; |
|---|
| 2191 | + |
|---|
| 2192 | + rc = netif_set_real_num_tx_queues(dev, 1); |
|---|
| 2193 | + if (rc) |
|---|
| 2194 | + goto out; |
|---|
| 2195 | + |
|---|
| 2196 | + rc = netif_set_real_num_rx_queues(dev, 1); |
|---|
| 2197 | + if (rc) |
|---|
| 2198 | + goto out; |
|---|
| 2199 | + } |
|---|
| 2196 | 2200 | |
|---|
| 2197 | 2201 | priv->rn_ops = dev->netdev_ops; |
|---|
| 2198 | 2202 | |
|---|
| 2199 | | - /* fixme : should be after the query_cap */ |
|---|
| 2200 | | - if (priv->hca_caps & IB_DEVICE_VIRTUAL_FUNCTION) |
|---|
| 2203 | + if (hca->attrs.device_cap_flags & IB_DEVICE_VIRTUAL_FUNCTION) |
|---|
| 2201 | 2204 | dev->netdev_ops = &ipoib_netdev_ops_vf; |
|---|
| 2202 | 2205 | else |
|---|
| 2203 | 2206 | dev->netdev_ops = &ipoib_netdev_ops_pf; |
|---|
| 2204 | 2207 | |
|---|
| 2205 | | - rn = netdev_priv(dev); |
|---|
| 2206 | 2208 | rn->clnt_priv = priv; |
|---|
| 2207 | | - |
|---|
| 2208 | 2209 | /* |
|---|
| 2209 | 2210 | * Only the child register_netdev flows can handle priv_destructor |
|---|
| 2210 | 2211 | * being set, so we force it to NULL here and handle manually until it |
|---|
| .. | .. |
|---|
| 2215 | 2216 | |
|---|
| 2216 | 2217 | ipoib_build_priv(dev); |
|---|
| 2217 | 2218 | |
|---|
| 2218 | | - return priv; |
|---|
| 2219 | | -free_priv: |
|---|
| 2219 | + return 0; |
|---|
| 2220 | + |
|---|
| 2221 | +out: |
|---|
| 2220 | 2222 | kfree(priv); |
|---|
| 2221 | | - return NULL; |
|---|
| 2223 | + return rc; |
|---|
| 2224 | +} |
|---|
| 2225 | + |
|---|
| 2226 | +struct net_device *ipoib_intf_alloc(struct ib_device *hca, u8 port, |
|---|
| 2227 | + const char *name) |
|---|
| 2228 | +{ |
|---|
| 2229 | + struct net_device *dev; |
|---|
| 2230 | + int rc; |
|---|
| 2231 | + |
|---|
| 2232 | + dev = ipoib_alloc_netdev(hca, port, name); |
|---|
| 2233 | + if (IS_ERR(dev)) |
|---|
| 2234 | + return dev; |
|---|
| 2235 | + |
|---|
| 2236 | + rc = ipoib_intf_init(hca, port, name, dev); |
|---|
| 2237 | + if (rc) { |
|---|
| 2238 | + free_netdev(dev); |
|---|
| 2239 | + return ERR_PTR(rc); |
|---|
| 2240 | + } |
|---|
| 2241 | + |
|---|
| 2242 | + /* |
|---|
| 2243 | + * Upon success the caller must ensure ipoib_intf_free is called or |
|---|
| 2244 | + * register_netdevice succeed'd and priv_destructor is set to |
|---|
| 2245 | + * ipoib_intf_free. |
|---|
| 2246 | + */ |
|---|
| 2247 | + return dev; |
|---|
| 2222 | 2248 | } |
|---|
| 2223 | 2249 | |
|---|
| 2224 | 2250 | void ipoib_intf_free(struct net_device *dev) |
|---|
| .. | .. |
|---|
| 2398 | 2424 | return device_create_file(&dev->dev, &dev_attr_pkey); |
|---|
| 2399 | 2425 | } |
|---|
| 2400 | 2426 | |
|---|
| 2427 | +/* |
|---|
| 2428 | + * We erroneously exposed the iface's port number in the dev_id |
|---|
| 2429 | + * sysfs field long after dev_port was introduced for that purpose[1], |
|---|
| 2430 | + * and we need to stop everyone from relying on that. |
|---|
| 2431 | + * Let's overload the shower routine for the dev_id file here |
|---|
| 2432 | + * to gently bring the issue up. |
|---|
| 2433 | + * |
|---|
| 2434 | + * [1] https://www.spinics.net/lists/netdev/msg272123.html |
|---|
| 2435 | + */ |
|---|
| 2436 | +static ssize_t dev_id_show(struct device *dev, |
|---|
| 2437 | + struct device_attribute *attr, char *buf) |
|---|
| 2438 | +{ |
|---|
| 2439 | + struct net_device *ndev = to_net_dev(dev); |
|---|
| 2440 | + |
|---|
| 2441 | + /* |
|---|
| 2442 | + * ndev->dev_port will be equal to 0 in old kernel prior to commit |
|---|
| 2443 | + * 9b8b2a323008 ("IB/ipoib: Use dev_port to expose network interface |
|---|
| 2444 | + * port numbers") Zero was chosen as special case for user space |
|---|
| 2445 | + * applications to fallback and query dev_id to check if it has |
|---|
| 2446 | + * different value or not. |
|---|
| 2447 | + * |
|---|
| 2448 | + * Don't print warning in such scenario. |
|---|
| 2449 | + * |
|---|
| 2450 | + * https://github.com/systemd/systemd/blob/master/src/udev/udev-builtin-net_id.c#L358 |
|---|
| 2451 | + */ |
|---|
| 2452 | + if (ndev->dev_port && ndev->dev_id == ndev->dev_port) |
|---|
| 2453 | + netdev_info_once(ndev, |
|---|
| 2454 | + "\"%s\" wants to know my dev_id. Should it look at dev_port instead? See Documentation/ABI/testing/sysfs-class-net for more info.\n", |
|---|
| 2455 | + current->comm); |
|---|
| 2456 | + |
|---|
| 2457 | + return sprintf(buf, "%#x\n", ndev->dev_id); |
|---|
| 2458 | +} |
|---|
| 2459 | +static DEVICE_ATTR_RO(dev_id); |
|---|
| 2460 | + |
|---|
| 2461 | +static int ipoib_intercept_dev_id_attr(struct net_device *dev) |
|---|
| 2462 | +{ |
|---|
| 2463 | + device_remove_file(&dev->dev, &dev_attr_dev_id); |
|---|
| 2464 | + return device_create_file(&dev->dev, &dev_attr_dev_id); |
|---|
| 2465 | +} |
|---|
| 2466 | + |
|---|
| 2401 | 2467 | static struct net_device *ipoib_add_port(const char *format, |
|---|
| 2402 | 2468 | struct ib_device *hca, u8 port) |
|---|
| 2403 | 2469 | { |
|---|
| 2470 | + struct rtnl_link_ops *ops = ipoib_get_link_ops(); |
|---|
| 2471 | + struct rdma_netdev_alloc_params params; |
|---|
| 2404 | 2472 | struct ipoib_dev_priv *priv; |
|---|
| 2405 | 2473 | struct net_device *ndev; |
|---|
| 2406 | 2474 | int result; |
|---|
| 2407 | 2475 | |
|---|
| 2408 | | - priv = ipoib_intf_alloc(hca, port, format); |
|---|
| 2409 | | - if (!priv) { |
|---|
| 2410 | | - pr_warn("%s, %d: ipoib_intf_alloc failed\n", hca->name, port); |
|---|
| 2411 | | - return ERR_PTR(-ENOMEM); |
|---|
| 2476 | + ndev = ipoib_intf_alloc(hca, port, format); |
|---|
| 2477 | + if (IS_ERR(ndev)) { |
|---|
| 2478 | + pr_warn("%s, %d: ipoib_intf_alloc failed %ld\n", hca->name, port, |
|---|
| 2479 | + PTR_ERR(ndev)); |
|---|
| 2480 | + return ndev; |
|---|
| 2412 | 2481 | } |
|---|
| 2413 | | - ndev = priv->dev; |
|---|
| 2482 | + priv = ipoib_priv(ndev); |
|---|
| 2414 | 2483 | |
|---|
| 2415 | 2484 | INIT_IB_EVENT_HANDLER(&priv->event_handler, |
|---|
| 2416 | 2485 | priv->ca, ipoib_event); |
|---|
| .. | .. |
|---|
| 2418 | 2487 | |
|---|
| 2419 | 2488 | /* call event handler to ensure pkey in sync */ |
|---|
| 2420 | 2489 | queue_work(ipoib_workqueue, &priv->flush_heavy); |
|---|
| 2490 | + |
|---|
| 2491 | + ndev->rtnl_link_ops = ipoib_get_link_ops(); |
|---|
| 2421 | 2492 | |
|---|
| 2422 | 2493 | result = register_netdev(ndev); |
|---|
| 2423 | 2494 | if (result) { |
|---|
| .. | .. |
|---|
| 2431 | 2502 | return ERR_PTR(result); |
|---|
| 2432 | 2503 | } |
|---|
| 2433 | 2504 | |
|---|
| 2505 | + if (hca->ops.rdma_netdev_get_params) { |
|---|
| 2506 | + int rc = hca->ops.rdma_netdev_get_params(hca, port, |
|---|
| 2507 | + RDMA_NETDEV_IPOIB, |
|---|
| 2508 | + ¶ms); |
|---|
| 2509 | + |
|---|
| 2510 | + if (!rc && ops->priv_size < params.sizeof_priv) |
|---|
| 2511 | + ops->priv_size = params.sizeof_priv; |
|---|
| 2512 | + } |
|---|
| 2434 | 2513 | /* |
|---|
| 2435 | 2514 | * We cannot set priv_destructor before register_netdev because we |
|---|
| 2436 | 2515 | * need priv to be always valid during the error flow to execute |
|---|
| .. | .. |
|---|
| 2439 | 2518 | */ |
|---|
| 2440 | 2519 | ndev->priv_destructor = ipoib_intf_free; |
|---|
| 2441 | 2520 | |
|---|
| 2521 | + if (ipoib_intercept_dev_id_attr(ndev)) |
|---|
| 2522 | + goto sysfs_failed; |
|---|
| 2442 | 2523 | if (ipoib_cm_add_mode_attr(ndev)) |
|---|
| 2443 | 2524 | goto sysfs_failed; |
|---|
| 2444 | 2525 | if (ipoib_add_pkey_attr(ndev)) |
|---|
| .. | .. |
|---|
| 2458 | 2539 | return ERR_PTR(-ENOMEM); |
|---|
| 2459 | 2540 | } |
|---|
| 2460 | 2541 | |
|---|
| 2461 | | -static void ipoib_add_one(struct ib_device *device) |
|---|
| 2542 | +static int ipoib_add_one(struct ib_device *device) |
|---|
| 2462 | 2543 | { |
|---|
| 2463 | 2544 | struct list_head *dev_list; |
|---|
| 2464 | 2545 | struct net_device *dev; |
|---|
| 2465 | 2546 | struct ipoib_dev_priv *priv; |
|---|
| 2466 | | - int p; |
|---|
| 2547 | + unsigned int p; |
|---|
| 2467 | 2548 | int count = 0; |
|---|
| 2468 | 2549 | |
|---|
| 2469 | 2550 | dev_list = kmalloc(sizeof(*dev_list), GFP_KERNEL); |
|---|
| 2470 | 2551 | if (!dev_list) |
|---|
| 2471 | | - return; |
|---|
| 2552 | + return -ENOMEM; |
|---|
| 2472 | 2553 | |
|---|
| 2473 | 2554 | INIT_LIST_HEAD(dev_list); |
|---|
| 2474 | 2555 | |
|---|
| 2475 | | - for (p = rdma_start_port(device); p <= rdma_end_port(device); ++p) { |
|---|
| 2556 | + rdma_for_each_port (device, p) { |
|---|
| 2476 | 2557 | if (!rdma_protocol_ib(device, p)) |
|---|
| 2477 | 2558 | continue; |
|---|
| 2478 | 2559 | dev = ipoib_add_port("ib%d", device, p); |
|---|
| .. | .. |
|---|
| 2485 | 2566 | |
|---|
| 2486 | 2567 | if (!count) { |
|---|
| 2487 | 2568 | kfree(dev_list); |
|---|
| 2488 | | - return; |
|---|
| 2569 | + return -EOPNOTSUPP; |
|---|
| 2489 | 2570 | } |
|---|
| 2490 | 2571 | |
|---|
| 2491 | 2572 | ib_set_client_data(device, &ipoib_client, dev_list); |
|---|
| 2573 | + return 0; |
|---|
| 2492 | 2574 | } |
|---|
| 2493 | 2575 | |
|---|
| 2494 | 2576 | static void ipoib_remove_one(struct ib_device *device, void *client_data) |
|---|
| 2495 | 2577 | { |
|---|
| 2496 | 2578 | struct ipoib_dev_priv *priv, *tmp, *cpriv, *tcpriv; |
|---|
| 2497 | 2579 | struct list_head *dev_list = client_data; |
|---|
| 2498 | | - |
|---|
| 2499 | | - if (!dev_list) |
|---|
| 2500 | | - return; |
|---|
| 2501 | 2580 | |
|---|
| 2502 | 2581 | list_for_each_entry_safe(priv, tmp, dev_list, list) { |
|---|
| 2503 | 2582 | LIST_HEAD(head); |
|---|
| .. | .. |
|---|
| 2545 | 2624 | */ |
|---|
| 2546 | 2625 | BUILD_BUG_ON(IPOIB_CM_COPYBREAK > IPOIB_CM_HEAD_SIZE); |
|---|
| 2547 | 2626 | |
|---|
| 2548 | | - ret = ipoib_register_debugfs(); |
|---|
| 2549 | | - if (ret) |
|---|
| 2550 | | - return ret; |
|---|
| 2627 | + ipoib_register_debugfs(); |
|---|
| 2551 | 2628 | |
|---|
| 2552 | 2629 | /* |
|---|
| 2553 | 2630 | * We create a global workqueue here that is used for all flush |
|---|