mirror of https://gitee.com/openkylin/linux.git
net/mlx4_en: Fix ethtool rules leftovers after module unloaded
As part of the driver unload flow, all steering rules must be deleted, make sure to remove the rules that were set through ethtool. Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com> Signed-off-by: Amir Vadai <amirv@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
280fce1e3e
commit
0d256c0e93
|
@ -915,6 +915,7 @@ static int mlx4_en_flow_replace(struct net_device *dev,
|
||||||
loc_rule->id = 0;
|
loc_rule->id = 0;
|
||||||
memset(&loc_rule->flow_spec, 0,
|
memset(&loc_rule->flow_spec, 0,
|
||||||
sizeof(struct ethtool_rx_flow_spec));
|
sizeof(struct ethtool_rx_flow_spec));
|
||||||
|
list_del(&loc_rule->list);
|
||||||
}
|
}
|
||||||
err = mlx4_flow_attach(priv->mdev->dev, &rule, ®_id);
|
err = mlx4_flow_attach(priv->mdev->dev, &rule, ®_id);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -925,6 +926,7 @@ static int mlx4_en_flow_replace(struct net_device *dev,
|
||||||
loc_rule->id = reg_id;
|
loc_rule->id = reg_id;
|
||||||
memcpy(&loc_rule->flow_spec, &cmd->fs,
|
memcpy(&loc_rule->flow_spec, &cmd->fs,
|
||||||
sizeof(struct ethtool_rx_flow_spec));
|
sizeof(struct ethtool_rx_flow_spec));
|
||||||
|
list_add_tail(&loc_rule->list, &priv->ethtool_list);
|
||||||
|
|
||||||
out_free_list:
|
out_free_list:
|
||||||
list_for_each_entry_safe(spec, tmp_spec, &rule.list, list) {
|
list_for_each_entry_safe(spec, tmp_spec, &rule.list, list) {
|
||||||
|
@ -958,6 +960,7 @@ static int mlx4_en_flow_detach(struct net_device *dev,
|
||||||
}
|
}
|
||||||
rule->id = 0;
|
rule->id = 0;
|
||||||
memset(&rule->flow_spec, 0, sizeof(struct ethtool_rx_flow_spec));
|
memset(&rule->flow_spec, 0, sizeof(struct ethtool_rx_flow_spec));
|
||||||
|
list_del(&rule->list);
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
|
@ -1039,6 +1039,9 @@ int mlx4_en_start_port(struct net_device *dev)
|
||||||
|
|
||||||
INIT_LIST_HEAD(&priv->mc_list);
|
INIT_LIST_HEAD(&priv->mc_list);
|
||||||
INIT_LIST_HEAD(&priv->curr_list);
|
INIT_LIST_HEAD(&priv->curr_list);
|
||||||
|
INIT_LIST_HEAD(&priv->ethtool_list);
|
||||||
|
memset(&priv->ethtool_rules[0], 0,
|
||||||
|
sizeof(struct ethtool_flow_id) * MAX_NUM_OF_FS_RULES);
|
||||||
|
|
||||||
/* Calculate Rx buf size */
|
/* Calculate Rx buf size */
|
||||||
dev->mtu = min(dev->mtu, priv->max_mtu);
|
dev->mtu = min(dev->mtu, priv->max_mtu);
|
||||||
|
@ -1202,6 +1205,7 @@ void mlx4_en_stop_port(struct net_device *dev)
|
||||||
struct mlx4_en_priv *priv = netdev_priv(dev);
|
struct mlx4_en_priv *priv = netdev_priv(dev);
|
||||||
struct mlx4_en_dev *mdev = priv->mdev;
|
struct mlx4_en_dev *mdev = priv->mdev;
|
||||||
struct mlx4_en_mc_list *mclist, *tmp;
|
struct mlx4_en_mc_list *mclist, *tmp;
|
||||||
|
struct ethtool_flow_id *flow, *tmp_flow;
|
||||||
int i;
|
int i;
|
||||||
u8 mc_list[16] = {0};
|
u8 mc_list[16] = {0};
|
||||||
|
|
||||||
|
@ -1283,6 +1287,17 @@ void mlx4_en_stop_port(struct net_device *dev)
|
||||||
mlx4_put_eth_qp(mdev->dev, priv->port, priv->mac, priv->base_qpn);
|
mlx4_put_eth_qp(mdev->dev, priv->port, priv->mac, priv->base_qpn);
|
||||||
mdev->mac_removed[priv->port] = 1;
|
mdev->mac_removed[priv->port] = 1;
|
||||||
|
|
||||||
|
/* Remove flow steering rules for the port*/
|
||||||
|
if (mdev->dev->caps.steering_mode ==
|
||||||
|
MLX4_STEERING_MODE_DEVICE_MANAGED) {
|
||||||
|
ASSERT_RTNL();
|
||||||
|
list_for_each_entry_safe(flow, tmp_flow,
|
||||||
|
&priv->ethtool_list, list) {
|
||||||
|
mlx4_flow_detach(mdev->dev, flow->id);
|
||||||
|
list_del(&flow->list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Free RX Rings */
|
/* Free RX Rings */
|
||||||
for (i = 0; i < priv->rx_ring_num; i++) {
|
for (i = 0; i < priv->rx_ring_num; i++) {
|
||||||
mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
|
mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
|
||||||
|
|
|
@ -427,6 +427,7 @@ struct mlx4_en_frag_info {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct ethtool_flow_id {
|
struct ethtool_flow_id {
|
||||||
|
struct list_head list;
|
||||||
struct ethtool_rx_flow_spec flow_spec;
|
struct ethtool_rx_flow_spec flow_spec;
|
||||||
u64 id;
|
u64 id;
|
||||||
};
|
};
|
||||||
|
@ -441,6 +442,8 @@ struct mlx4_en_priv {
|
||||||
struct mlx4_en_port_state port_state;
|
struct mlx4_en_port_state port_state;
|
||||||
spinlock_t stats_lock;
|
spinlock_t stats_lock;
|
||||||
struct ethtool_flow_id ethtool_rules[MAX_NUM_OF_FS_RULES];
|
struct ethtool_flow_id ethtool_rules[MAX_NUM_OF_FS_RULES];
|
||||||
|
/* To allow rules removal while port is going down */
|
||||||
|
struct list_head ethtool_list;
|
||||||
|
|
||||||
unsigned long last_moder_packets[MAX_RX_RINGS];
|
unsigned long last_moder_packets[MAX_RX_RINGS];
|
||||||
unsigned long last_moder_tx_packets;
|
unsigned long last_moder_tx_packets;
|
||||||
|
|
Loading…
Reference in New Issue