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

Configure Feed

Select the types of activity you want to include in your feed.

mlx4: Get rid of the mlx4_interface.get_dev callback

Simplify the mlx4 driver interface by removing mlx4_get_protocol_dev()
and the associated mlx4_interface.get_dev callbacks. This is done in
preparation to use an auxiliary bus to model the mlx4 driver structure.

The change is motivated by the following situation:
* The mlx4_en interface is being initialized by mlx4_en_add() and
mlx4_en_activate().
* The latter activate function calls mlx4_en_init_netdev() ->
register_netdev() to register a new net_device.
* A netdev event NETDEV_REGISTER is raised for the device.
* The netdev notififier mlx4_ib_netdev_event() is called and it invokes
mlx4_ib_scan_netdevs() -> mlx4_get_protocol_dev() ->
mlx4_en_get_netdev() [via mlx4_interface.get_dev].

This chain creates a problem when mlx4_en gets switched to be an
auxiliary driver. It contains two device calls which would both need to
take a respective device lock.

Avoid this situation by updating mlx4_ib_scan_netdevs() to no longer
call mlx4_get_protocol_dev() but instead to utilize the information
passed in net_device.parent and net_device.dev_port. This data is
sufficient to determine that an updated port is one that the mlx4_ib
driver should take care of and to keep mlx4_ib_dev.iboe.netdevs up to
date.

Following that, update mlx4_ib_get_netdev() to also not call
mlx4_get_protocol_dev() and instead scan all current netdevs to find
find a matching one. Note that mlx4_ib_get_netdev() is called early from
ib_register_device() and cannot use data tracked in
mlx4_ib_dev.iboe.netdevs which is not at that point yet set.

Finally, remove function mlx4_get_protocol_dev() and the
mlx4_interface.get_dev callbacks (only mlx4_en_get_netdev()) as they
became unused.

Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Tested-by: Leon Romanovsky <leonro@nvidia.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Acked-by: Tariq Toukan <tariqt@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Petr Pavlu and committed by
David S. Miller
71ab55a9 eb660324

+43 -78
+43 -46
drivers/infiniband/hw/mlx4/main.c
··· 125 125 u32 port_num) 126 126 { 127 127 struct mlx4_ib_dev *ibdev = to_mdev(device); 128 - struct net_device *dev; 128 + struct net_device *dev, *ret = NULL; 129 129 130 130 rcu_read_lock(); 131 - dev = mlx4_get_protocol_dev(ibdev->dev, MLX4_PROT_ETH, port_num); 131 + for_each_netdev_rcu(&init_net, dev) { 132 + if (dev->dev.parent != ibdev->ib_dev.dev.parent || 133 + dev->dev_port + 1 != port_num) 134 + continue; 132 135 133 - if (dev) { 134 136 if (mlx4_is_bonded(ibdev->dev)) { 135 137 struct net_device *upper = NULL; 136 138 ··· 145 143 dev = active; 146 144 } 147 145 } 146 + 147 + dev_hold(dev); 148 + ret = dev; 149 + break; 148 150 } 149 - dev_hold(dev); 150 151 151 152 rcu_read_unlock(); 152 - return dev; 153 + return ret; 153 154 } 154 155 155 156 static int mlx4_ib_update_gids_v1(struct gid_entry *gids, ··· 2324 2319 mutex_unlock(&ibdev->qp1_proxy_lock[port - 1]); 2325 2320 } 2326 2321 2327 - static void mlx4_ib_scan_netdevs(struct mlx4_ib_dev *ibdev, 2328 - struct net_device *dev, 2329 - unsigned long event) 2322 + static void mlx4_ib_scan_netdev(struct mlx4_ib_dev *ibdev, 2323 + struct net_device *dev, 2324 + unsigned long event) 2330 2325 2331 2326 { 2332 - struct mlx4_ib_iboe *iboe; 2333 - int update_qps_port = -1; 2334 - int port; 2327 + struct mlx4_ib_iboe *iboe = &ibdev->iboe; 2335 2328 2336 2329 ASSERT_RTNL(); 2337 2330 2338 - iboe = &ibdev->iboe; 2331 + if (dev->dev.parent != ibdev->ib_dev.dev.parent) 2332 + return; 2339 2333 2340 2334 spin_lock_bh(&iboe->lock); 2341 - mlx4_foreach_ib_transport_port(port, ibdev->dev) { 2342 2335 2343 - iboe->netdevs[port - 1] = 2344 - mlx4_get_protocol_dev(ibdev->dev, MLX4_PROT_ETH, port); 2336 + iboe->netdevs[dev->dev_port] = event != NETDEV_UNREGISTER ? dev : NULL; 2345 2337 2346 - if (dev == iboe->netdevs[port - 1] && 2347 - (event == NETDEV_CHANGEADDR || event == NETDEV_REGISTER || 2348 - event == NETDEV_UP || event == NETDEV_CHANGE)) 2349 - update_qps_port = port; 2338 + if (event == NETDEV_UP || event == NETDEV_DOWN) { 2339 + enum ib_port_state port_state; 2340 + struct ib_event ibev = { }; 2350 2341 2351 - if (dev == iboe->netdevs[port - 1] && 2352 - (event == NETDEV_UP || event == NETDEV_DOWN)) { 2353 - enum ib_port_state port_state; 2354 - struct ib_event ibev = { }; 2342 + if (ib_get_cached_port_state(&ibdev->ib_dev, dev->dev_port + 1, 2343 + &port_state)) 2344 + goto iboe_out; 2355 2345 2356 - if (ib_get_cached_port_state(&ibdev->ib_dev, port, 2357 - &port_state)) 2358 - continue; 2346 + if (event == NETDEV_UP && 2347 + (port_state != IB_PORT_ACTIVE || 2348 + iboe->last_port_state[dev->dev_port] != IB_PORT_DOWN)) 2349 + goto iboe_out; 2350 + if (event == NETDEV_DOWN && 2351 + (port_state != IB_PORT_DOWN || 2352 + iboe->last_port_state[dev->dev_port] != IB_PORT_ACTIVE)) 2353 + goto iboe_out; 2354 + iboe->last_port_state[dev->dev_port] = port_state; 2359 2355 2360 - if (event == NETDEV_UP && 2361 - (port_state != IB_PORT_ACTIVE || 2362 - iboe->last_port_state[port - 1] != IB_PORT_DOWN)) 2363 - continue; 2364 - if (event == NETDEV_DOWN && 2365 - (port_state != IB_PORT_DOWN || 2366 - iboe->last_port_state[port - 1] != IB_PORT_ACTIVE)) 2367 - continue; 2368 - iboe->last_port_state[port - 1] = port_state; 2369 - 2370 - ibev.device = &ibdev->ib_dev; 2371 - ibev.element.port_num = port; 2372 - ibev.event = event == NETDEV_UP ? IB_EVENT_PORT_ACTIVE : 2373 - IB_EVENT_PORT_ERR; 2374 - ib_dispatch_event(&ibev); 2375 - } 2376 - 2356 + ibev.device = &ibdev->ib_dev; 2357 + ibev.element.port_num = dev->dev_port + 1; 2358 + ibev.event = event == NETDEV_UP ? IB_EVENT_PORT_ACTIVE : 2359 + IB_EVENT_PORT_ERR; 2360 + ib_dispatch_event(&ibev); 2377 2361 } 2362 + 2363 + iboe_out: 2378 2364 spin_unlock_bh(&iboe->lock); 2379 2365 2380 - if (update_qps_port > 0) 2381 - mlx4_ib_update_qps(ibdev, dev, update_qps_port); 2366 + if (event == NETDEV_CHANGEADDR || event == NETDEV_REGISTER || 2367 + event == NETDEV_UP || event == NETDEV_CHANGE) 2368 + mlx4_ib_update_qps(ibdev, dev, dev->dev_port + 1); 2382 2369 } 2383 2370 2384 2371 static int mlx4_ib_netdev_event(struct notifier_block *this, ··· 2383 2386 return NOTIFY_DONE; 2384 2387 2385 2388 ibdev = container_of(this, struct mlx4_ib_dev, iboe.nb); 2386 - mlx4_ib_scan_netdevs(ibdev, dev, event); 2389 + mlx4_ib_scan_netdev(ibdev, dev, event); 2387 2390 2388 2391 return NOTIFY_DONE; 2389 2392 }
-8
drivers/net/ethernet/mellanox/mlx4/en_main.c
··· 183 183 } 184 184 } 185 185 186 - static void *mlx4_en_get_netdev(struct mlx4_dev *dev, void *ctx, u8 port) 187 - { 188 - struct mlx4_en_dev *endev = ctx; 189 - 190 - return endev->pndev[port]; 191 - } 192 - 193 186 static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr, 194 187 enum mlx4_dev_event event, unsigned long port) 195 188 { ··· 347 354 .add = mlx4_en_add, 348 355 .remove = mlx4_en_remove, 349 356 .event = mlx4_en_event, 350 - .get_dev = mlx4_en_get_netdev, 351 357 .protocol = MLX4_PROT_ETH, 352 358 .activate = mlx4_en_activate, 353 359 };
-21
drivers/net/ethernet/mellanox/mlx4/intf.c
··· 245 245 mutex_unlock(&intf_mutex); 246 246 } 247 247 248 - void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int port) 249 - { 250 - struct mlx4_priv *priv = mlx4_priv(dev); 251 - struct mlx4_device_context *dev_ctx; 252 - unsigned long flags; 253 - void *result = NULL; 254 - 255 - spin_lock_irqsave(&priv->ctx_lock, flags); 256 - 257 - list_for_each_entry(dev_ctx, &priv->ctx_list, list) 258 - if (dev_ctx->intf->protocol == proto && dev_ctx->intf->get_dev) { 259 - result = dev_ctx->intf->get_dev(dev, dev_ctx->context, port); 260 - break; 261 - } 262 - 263 - spin_unlock_irqrestore(&priv->ctx_lock, flags); 264 - 265 - return result; 266 - } 267 - EXPORT_SYMBOL_GPL(mlx4_get_protocol_dev); 268 - 269 248 struct devlink_port *mlx4_get_devlink_port(struct mlx4_dev *dev, int port) 270 249 { 271 250 struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
-3
include/linux/mlx4/driver.h
··· 59 59 void (*remove)(struct mlx4_dev *dev, void *context); 60 60 void (*event) (struct mlx4_dev *dev, void *context, 61 61 enum mlx4_dev_event event, unsigned long param); 62 - void * (*get_dev)(struct mlx4_dev *dev, void *context, u8 port); 63 62 void (*activate)(struct mlx4_dev *dev, void *context); 64 63 struct list_head list; 65 64 enum mlx4_protocol protocol; ··· 86 87 }; 87 88 88 89 int mlx4_port_map_set(struct mlx4_dev *dev, struct mlx4_port_map *v2p); 89 - 90 - void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int port); 91 90 92 91 struct devlink_port *mlx4_get_devlink_port(struct mlx4_dev *dev, int port); 93 92