mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-16 13:34:30 +00:00
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>
This commit is contained in:
parent
eb6603246a
commit
71ab55a9af
@ -125,12 +125,14 @@ static struct net_device *mlx4_ib_get_netdev(struct ib_device *device,
|
||||
u32 port_num)
|
||||
{
|
||||
struct mlx4_ib_dev *ibdev = to_mdev(device);
|
||||
struct net_device *dev;
|
||||
struct net_device *dev, *ret = NULL;
|
||||
|
||||
rcu_read_lock();
|
||||
dev = mlx4_get_protocol_dev(ibdev->dev, MLX4_PROT_ETH, port_num);
|
||||
for_each_netdev_rcu(&init_net, dev) {
|
||||
if (dev->dev.parent != ibdev->ib_dev.dev.parent ||
|
||||
dev->dev_port + 1 != port_num)
|
||||
continue;
|
||||
|
||||
if (dev) {
|
||||
if (mlx4_is_bonded(ibdev->dev)) {
|
||||
struct net_device *upper = NULL;
|
||||
|
||||
@ -143,11 +145,14 @@ static struct net_device *mlx4_ib_get_netdev(struct ib_device *device,
|
||||
dev = active;
|
||||
}
|
||||
}
|
||||
|
||||
dev_hold(dev);
|
||||
ret = dev;
|
||||
break;
|
||||
}
|
||||
dev_hold(dev);
|
||||
|
||||
rcu_read_unlock();
|
||||
return dev;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mlx4_ib_update_gids_v1(struct gid_entry *gids,
|
||||
@ -2319,61 +2324,53 @@ unlock:
|
||||
mutex_unlock(&ibdev->qp1_proxy_lock[port - 1]);
|
||||
}
|
||||
|
||||
static void mlx4_ib_scan_netdevs(struct mlx4_ib_dev *ibdev,
|
||||
struct net_device *dev,
|
||||
unsigned long event)
|
||||
static void mlx4_ib_scan_netdev(struct mlx4_ib_dev *ibdev,
|
||||
struct net_device *dev,
|
||||
unsigned long event)
|
||||
|
||||
{
|
||||
struct mlx4_ib_iboe *iboe;
|
||||
int update_qps_port = -1;
|
||||
int port;
|
||||
struct mlx4_ib_iboe *iboe = &ibdev->iboe;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
iboe = &ibdev->iboe;
|
||||
if (dev->dev.parent != ibdev->ib_dev.dev.parent)
|
||||
return;
|
||||
|
||||
spin_lock_bh(&iboe->lock);
|
||||
mlx4_foreach_ib_transport_port(port, ibdev->dev) {
|
||||
|
||||
iboe->netdevs[port - 1] =
|
||||
mlx4_get_protocol_dev(ibdev->dev, MLX4_PROT_ETH, port);
|
||||
iboe->netdevs[dev->dev_port] = event != NETDEV_UNREGISTER ? dev : NULL;
|
||||
|
||||
if (dev == iboe->netdevs[port - 1] &&
|
||||
(event == NETDEV_CHANGEADDR || event == NETDEV_REGISTER ||
|
||||
event == NETDEV_UP || event == NETDEV_CHANGE))
|
||||
update_qps_port = port;
|
||||
if (event == NETDEV_UP || event == NETDEV_DOWN) {
|
||||
enum ib_port_state port_state;
|
||||
struct ib_event ibev = { };
|
||||
|
||||
if (dev == iboe->netdevs[port - 1] &&
|
||||
(event == NETDEV_UP || event == NETDEV_DOWN)) {
|
||||
enum ib_port_state port_state;
|
||||
struct ib_event ibev = { };
|
||||
if (ib_get_cached_port_state(&ibdev->ib_dev, dev->dev_port + 1,
|
||||
&port_state))
|
||||
goto iboe_out;
|
||||
|
||||
if (ib_get_cached_port_state(&ibdev->ib_dev, port,
|
||||
&port_state))
|
||||
continue;
|
||||
|
||||
if (event == NETDEV_UP &&
|
||||
(port_state != IB_PORT_ACTIVE ||
|
||||
iboe->last_port_state[port - 1] != IB_PORT_DOWN))
|
||||
continue;
|
||||
if (event == NETDEV_DOWN &&
|
||||
(port_state != IB_PORT_DOWN ||
|
||||
iboe->last_port_state[port - 1] != IB_PORT_ACTIVE))
|
||||
continue;
|
||||
iboe->last_port_state[port - 1] = port_state;
|
||||
|
||||
ibev.device = &ibdev->ib_dev;
|
||||
ibev.element.port_num = port;
|
||||
ibev.event = event == NETDEV_UP ? IB_EVENT_PORT_ACTIVE :
|
||||
IB_EVENT_PORT_ERR;
|
||||
ib_dispatch_event(&ibev);
|
||||
}
|
||||
if (event == NETDEV_UP &&
|
||||
(port_state != IB_PORT_ACTIVE ||
|
||||
iboe->last_port_state[dev->dev_port] != IB_PORT_DOWN))
|
||||
goto iboe_out;
|
||||
if (event == NETDEV_DOWN &&
|
||||
(port_state != IB_PORT_DOWN ||
|
||||
iboe->last_port_state[dev->dev_port] != IB_PORT_ACTIVE))
|
||||
goto iboe_out;
|
||||
iboe->last_port_state[dev->dev_port] = port_state;
|
||||
|
||||
ibev.device = &ibdev->ib_dev;
|
||||
ibev.element.port_num = dev->dev_port + 1;
|
||||
ibev.event = event == NETDEV_UP ? IB_EVENT_PORT_ACTIVE :
|
||||
IB_EVENT_PORT_ERR;
|
||||
ib_dispatch_event(&ibev);
|
||||
}
|
||||
|
||||
iboe_out:
|
||||
spin_unlock_bh(&iboe->lock);
|
||||
|
||||
if (update_qps_port > 0)
|
||||
mlx4_ib_update_qps(ibdev, dev, update_qps_port);
|
||||
if (event == NETDEV_CHANGEADDR || event == NETDEV_REGISTER ||
|
||||
event == NETDEV_UP || event == NETDEV_CHANGE)
|
||||
mlx4_ib_update_qps(ibdev, dev, dev->dev_port + 1);
|
||||
}
|
||||
|
||||
static int mlx4_ib_netdev_event(struct notifier_block *this,
|
||||
@ -2386,7 +2383,7 @@ static int mlx4_ib_netdev_event(struct notifier_block *this,
|
||||
return NOTIFY_DONE;
|
||||
|
||||
ibdev = container_of(this, struct mlx4_ib_dev, iboe.nb);
|
||||
mlx4_ib_scan_netdevs(ibdev, dev, event);
|
||||
mlx4_ib_scan_netdev(ibdev, dev, event);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
@ -183,13 +183,6 @@ static void mlx4_en_get_profile(struct mlx4_en_dev *mdev)
|
||||
}
|
||||
}
|
||||
|
||||
static void *mlx4_en_get_netdev(struct mlx4_dev *dev, void *ctx, u8 port)
|
||||
{
|
||||
struct mlx4_en_dev *endev = ctx;
|
||||
|
||||
return endev->pndev[port];
|
||||
}
|
||||
|
||||
static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr,
|
||||
enum mlx4_dev_event event, unsigned long port)
|
||||
{
|
||||
@ -354,7 +347,6 @@ static struct mlx4_interface mlx4_en_interface = {
|
||||
.add = mlx4_en_add,
|
||||
.remove = mlx4_en_remove,
|
||||
.event = mlx4_en_event,
|
||||
.get_dev = mlx4_en_get_netdev,
|
||||
.protocol = MLX4_PROT_ETH,
|
||||
.activate = mlx4_en_activate,
|
||||
};
|
||||
|
@ -245,27 +245,6 @@ void mlx4_unregister_device(struct mlx4_dev *dev)
|
||||
mutex_unlock(&intf_mutex);
|
||||
}
|
||||
|
||||
void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int port)
|
||||
{
|
||||
struct mlx4_priv *priv = mlx4_priv(dev);
|
||||
struct mlx4_device_context *dev_ctx;
|
||||
unsigned long flags;
|
||||
void *result = NULL;
|
||||
|
||||
spin_lock_irqsave(&priv->ctx_lock, flags);
|
||||
|
||||
list_for_each_entry(dev_ctx, &priv->ctx_list, list)
|
||||
if (dev_ctx->intf->protocol == proto && dev_ctx->intf->get_dev) {
|
||||
result = dev_ctx->intf->get_dev(dev, dev_ctx->context, port);
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->ctx_lock, flags);
|
||||
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx4_get_protocol_dev);
|
||||
|
||||
struct devlink_port *mlx4_get_devlink_port(struct mlx4_dev *dev, int port)
|
||||
{
|
||||
struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
|
||||
|
@ -59,7 +59,6 @@ struct mlx4_interface {
|
||||
void (*remove)(struct mlx4_dev *dev, void *context);
|
||||
void (*event) (struct mlx4_dev *dev, void *context,
|
||||
enum mlx4_dev_event event, unsigned long param);
|
||||
void * (*get_dev)(struct mlx4_dev *dev, void *context, u8 port);
|
||||
void (*activate)(struct mlx4_dev *dev, void *context);
|
||||
struct list_head list;
|
||||
enum mlx4_protocol protocol;
|
||||
@ -88,8 +87,6 @@ struct mlx4_port_map {
|
||||
|
||||
int mlx4_port_map_set(struct mlx4_dev *dev, struct mlx4_port_map *v2p);
|
||||
|
||||
void *mlx4_get_protocol_dev(struct mlx4_dev *dev, enum mlx4_protocol proto, int port);
|
||||
|
||||
struct devlink_port *mlx4_get_devlink_port(struct mlx4_dev *dev, int port);
|
||||
|
||||
#endif /* MLX4_DRIVER_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user