[PATCH 10/10] net/mlx5: optimize MAC address and VLAN filter handling
Dariusz Sosnowski
dsosnowski at nvidia.com
Thu Oct 17 09:57:38 CEST 2024
This patch:
- Changes MAC address adding/removing handling, so that
only required control rules are added/removed.
As a result, rte_eth_dev_mac_addr_add() or
rte_eth_dev_mac_addr_remove() calls are faster for mlx5 PMD.
- Changes VLAN filtering handling, so that
only required control flow rules are added/removed.
As a result, rte_eth_dev_vlan_filter() call is faster for mlx5 PMD.
Signed-off-by: Dariusz Sosnowski <dsosnowski at nvidia.com>
---
drivers/net/mlx5/mlx5_mac.c | 41 +++++++++++++++++++++++++-----------
drivers/net/mlx5/mlx5_vlan.c | 9 ++++----
2 files changed, 33 insertions(+), 17 deletions(-)
diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c
index 22a756a52b..0e5d2be530 100644
--- a/drivers/net/mlx5/mlx5_mac.c
+++ b/drivers/net/mlx5/mlx5_mac.c
@@ -25,15 +25,25 @@
* Pointer to Ethernet device structure.
* @param index
* MAC address index.
+ * @param addr
+ * If MAC address is actually removed, it will be stored here if pointer is not a NULL.
+ *
+ * @return
+ * True if there was a MAC address under given index.
*/
-static void
-mlx5_internal_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
+static bool
+mlx5_internal_mac_addr_remove(struct rte_eth_dev *dev,
+ uint32_t index,
+ struct rte_ether_addr *addr)
{
MLX5_ASSERT(index < MLX5_MAX_MAC_ADDRESSES);
if (rte_is_zero_ether_addr(&dev->data->mac_addrs[index]))
- return;
+ return false;
mlx5_os_mac_addr_remove(dev, index);
+ if (addr != NULL)
+ *addr = dev->data->mac_addrs[index];
memset(&dev->data->mac_addrs[index], 0, sizeof(struct rte_ether_addr));
+ return true;
}
/**
@@ -91,15 +101,15 @@ mlx5_internal_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
void
mlx5_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
{
+ struct rte_ether_addr addr = { 0 };
int ret;
if (index >= MLX5_MAX_UC_MAC_ADDRESSES)
return;
- mlx5_internal_mac_addr_remove(dev, index);
- if (!dev->data->promiscuous) {
- ret = mlx5_traffic_restart(dev);
+ if (mlx5_internal_mac_addr_remove(dev, index, &addr)) {
+ ret = mlx5_traffic_mac_remove(dev, &addr);
if (ret)
- DRV_LOG(ERR, "port %u cannot restart traffic: %s",
+ DRV_LOG(ERR, "port %u cannot update control flow rules: %s",
dev->data->port_id, strerror(rte_errno));
}
}
@@ -132,9 +142,7 @@ mlx5_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
ret = mlx5_internal_mac_addr_add(dev, mac, index);
if (ret < 0)
return ret;
- if (!dev->data->promiscuous)
- return mlx5_traffic_restart(dev);
- return 0;
+ return mlx5_traffic_mac_add(dev, mac);
}
/**
@@ -154,6 +162,12 @@ mlx5_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
uint16_t port_id;
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_priv *pf_priv;
+ struct rte_ether_addr old_mac_addr = dev->data->mac_addrs[0];
+ int ret;
+
+ /* ethdev does not check if new default address is the same as the old one. */
+ if (rte_is_same_ether_addr(mac_addr, &old_mac_addr))
+ return 0;
/*
* Configuring the VF instead of its representor,
@@ -188,7 +202,10 @@ mlx5_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
DRV_LOG(DEBUG, "port %u setting primary MAC address",
dev->data->port_id);
- return mlx5_mac_addr_add(dev, mac_addr, 0, 0);
+ ret = mlx5_mac_addr_add(dev, mac_addr, 0, 0);
+ if (ret)
+ return ret;
+ return mlx5_traffic_mac_remove(dev, &old_mac_addr);
}
/**
@@ -208,7 +225,7 @@ mlx5_set_mc_addr_list(struct rte_eth_dev *dev,
return -rte_errno;
}
for (i = MLX5_MAX_UC_MAC_ADDRESSES; i != MLX5_MAX_MAC_ADDRESSES; ++i)
- mlx5_internal_mac_addr_remove(dev, i);
+ mlx5_internal_mac_addr_remove(dev, i, NULL);
i = MLX5_MAX_UC_MAC_ADDRESSES;
while (nb_mc_addr--) {
ret = mlx5_internal_mac_addr_add(dev, mc_addr_set++, i++);
diff --git a/drivers/net/mlx5/mlx5_vlan.c b/drivers/net/mlx5/mlx5_vlan.c
index e7161b66fe..43a314a679 100644
--- a/drivers/net/mlx5/mlx5_vlan.c
+++ b/drivers/net/mlx5/mlx5_vlan.c
@@ -54,7 +54,7 @@ mlx5_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
MLX5_ASSERT(priv->vlan_filter_n != 0);
/* Enabling an existing VLAN filter has no effect. */
if (on)
- goto out;
+ goto no_effect;
/* Remove VLAN filter from list. */
--priv->vlan_filter_n;
memmove(&priv->vlan_filter[i],
@@ -66,14 +66,13 @@ mlx5_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
MLX5_ASSERT(i == priv->vlan_filter_n);
/* Disabling an unknown VLAN filter has no effect. */
if (!on)
- goto out;
+ goto no_effect;
/* Add new VLAN filter. */
priv->vlan_filter[priv->vlan_filter_n] = vlan_id;
++priv->vlan_filter_n;
}
-out:
- if (dev->data->dev_started)
- return mlx5_traffic_restart(dev);
+ return on ? mlx5_traffic_vlan_add(dev, vlan_id) : mlx5_traffic_vlan_remove(dev, vlan_id);
+no_effect:
return 0;
}
--
2.39.5
More information about the dev
mailing list