提交 490dceca 编写于 作者: J Jakub Kicinski 提交者: Saeed Mahameed

mlx5: count all link events

mlx5 devices were observed generating MLX5_PORT_CHANGE_SUBTYPE_ACTIVE
events without an intervening MLX5_PORT_CHANGE_SUBTYPE_DOWN. This
breaks link flap detection based on Linux carrier state transition
count as netif_carrier_on() does nothing if carrier is already on.
Make sure we count such events.

netif_carrier_event() increments the counters and fires the linkwatch
events. The latter is not necessary for the use case but seems like
the right thing to do.
Signed-off-by: NJakub Kicinski <kuba@kernel.org>
Signed-off-by: NSaeed Mahameed <saeedm@nvidia.com>
上级 270d47dc
...@@ -91,12 +91,16 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv) ...@@ -91,12 +91,16 @@ void mlx5e_update_carrier(struct mlx5e_priv *priv)
{ {
struct mlx5_core_dev *mdev = priv->mdev; struct mlx5_core_dev *mdev = priv->mdev;
u8 port_state; u8 port_state;
bool up;
port_state = mlx5_query_vport_state(mdev, port_state = mlx5_query_vport_state(mdev,
MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT, MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT,
0); 0);
if (port_state == VPORT_STATE_UP) { up = port_state == VPORT_STATE_UP;
if (up == netif_carrier_ok(priv->netdev))
netif_carrier_event(priv->netdev);
if (up) {
netdev_info(priv->netdev, "Link up\n"); netdev_info(priv->netdev, "Link up\n");
netif_carrier_on(priv->netdev); netif_carrier_on(priv->netdev);
} else { } else {
......
...@@ -4187,8 +4187,8 @@ unsigned long dev_trans_start(struct net_device *dev); ...@@ -4187,8 +4187,8 @@ unsigned long dev_trans_start(struct net_device *dev);
void __netdev_watchdog_up(struct net_device *dev); void __netdev_watchdog_up(struct net_device *dev);
void netif_carrier_on(struct net_device *dev); void netif_carrier_on(struct net_device *dev);
void netif_carrier_off(struct net_device *dev); void netif_carrier_off(struct net_device *dev);
void netif_carrier_event(struct net_device *dev);
/** /**
* netif_dormant_on - mark device as dormant. * netif_dormant_on - mark device as dormant.
......
...@@ -540,6 +540,24 @@ void netif_carrier_off(struct net_device *dev) ...@@ -540,6 +540,24 @@ void netif_carrier_off(struct net_device *dev)
} }
EXPORT_SYMBOL(netif_carrier_off); EXPORT_SYMBOL(netif_carrier_off);
/**
* netif_carrier_event - report carrier state event
* @dev: network device
*
* Device has detected a carrier event but the carrier state wasn't changed.
* Use in drivers when querying carrier state asynchronously, to avoid missing
* events (link flaps) if link recovers before it's queried.
*/
void netif_carrier_event(struct net_device *dev)
{
if (dev->reg_state == NETREG_UNINITIALIZED)
return;
atomic_inc(&dev->carrier_up_count);
atomic_inc(&dev->carrier_down_count);
linkwatch_fire_event(dev);
}
EXPORT_SYMBOL_GPL(netif_carrier_event);
/* "NOOP" scheduler: the best scheduler, recommended for all interfaces /* "NOOP" scheduler: the best scheduler, recommended for all interfaces
under all circumstances. It is difficult to invent anything faster or under all circumstances. It is difficult to invent anything faster or
cheaper. cheaper.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
新手
引导
客服 返回
顶部