Commit a0c3aefb authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2025-11-06 (i40, ice, iavf)

Mohammad Heib introduces a new devlink parameter, max_mac_per_vf, for
controlling the maximum number of MAC address filters allowed by a VF. This
allows administrators to control the VF behavior in a more nuanced manner.

Aleksandr and Przemek add support for Receive Side Scaling of GTP to iAVF
for VFs running on E800 series ice hardware. This improves performance and
scalability for virtualized network functions in 5G and LTE deployments.

* '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  iavf: add RSS support for GTP protocol via ethtool
  ice: Extend PTYPE bitmap coverage for GTP encapsulated flows
  ice: improve TCAM priority handling for RSS profiles
  ice: implement GTP RSS context tracking and configuration
  ice: add virtchnl definitions and static data for GTP RSS
  ice: add flow parsing for GTP and new protocol field support
  i40e: support generic devlink param "max_mac_per_vf"
  devlink: Add new "max_mac_per_vf" generic device param
====================

Link: https://patch.msgid.link/20251106225321.1609605-1-anthony.l.nguyen@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 7c463328 3da28eb2
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -151,3 +151,7 @@ own name.
   * - ``num_doorbells``
     - u32
     - Controls the number of doorbells used by the device.
   * - ``max_mac_per_vf``
     - u32
     - Controls the maximum number of MAC address filters that can be assigned
       to a Virtual Function (VF).
+34 −0
Original line number Diff line number Diff line
@@ -7,6 +7,40 @@ i40e devlink support
This document describes the devlink features implemented by the ``i40e``
device driver.

Parameters
==========

.. list-table:: Generic parameters implemented
    :widths: 5 5 90

    * - Name
      - Mode
      - Notes
    * - ``max_mac_per_vf``
      - runtime
      - Controls the maximum number of MAC addresses a VF can use
        on i40e devices.

        By default (``0``), the driver enforces its internally calculated per-VF
        MAC filter limit, which is based on the number of allocated VFS.

        If set to a non-zero value, this parameter acts as a strict cap:
        the driver will use the user-provided value instead of its internal
        calculation.

        **Important notes:**

        - This value **must be set before enabling SR-IOV**.
          Attempting to change it while SR-IOV is enabled will return an error.
        - MAC filters are a **shared hardware resource** across all VFs.
          Setting a high value may cause other VFs to be starved of filters.
        - This value is a **Administrative policy**. The hardware may return
          errors when its absolute limit is reached, regardless of the value
          set here.

        The default value is ``0`` (internal calculation is used).


Info versions
=============

+4 −0
Original line number Diff line number Diff line
@@ -574,6 +574,10 @@ struct i40e_pf {
	struct i40e_vf *vf;
	int num_alloc_vfs;	/* actual number of VFs allocated */
	u32 vf_aq_requests;
	/* If set to non-zero, the device uses this value
	 * as maximum number of MAC filters per VF.
	 */
	u32 max_mac_per_vf;
	u32 arq_overflows;	/* Not fatal, possibly indicative of problems */
	struct ratelimit_state mdd_message_rate_limit;
	/* DCBx/DCBNL capability for PF that indicates
+52 −2
Original line number Diff line number Diff line
@@ -5,6 +5,41 @@
#include "i40e.h"
#include "i40e_devlink.h"

static int i40e_max_mac_per_vf_set(struct devlink *devlink,
				   u32 id,
				   struct devlink_param_gset_ctx *ctx,
				   struct netlink_ext_ack *extack)
{
	struct i40e_pf *pf = devlink_priv(devlink);

	if (pf->num_alloc_vfs > 0) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Cannot change max_mac_per_vf while SR-IOV is enabled");
		return -EBUSY;
	}

	pf->max_mac_per_vf = ctx->val.vu32;
	return 0;
}

static int i40e_max_mac_per_vf_get(struct devlink *devlink,
				   u32 id,
				   struct devlink_param_gset_ctx *ctx)
{
	struct i40e_pf *pf = devlink_priv(devlink);

	ctx->val.vu32 = pf->max_mac_per_vf;
	return 0;
}

static const struct devlink_param i40e_dl_params[] = {
	DEVLINK_PARAM_GENERIC(MAX_MAC_PER_VF,
			      BIT(DEVLINK_PARAM_CMODE_RUNTIME),
			      i40e_max_mac_per_vf_get,
			      i40e_max_mac_per_vf_set,
			      NULL),
};

static void i40e_info_get_dsn(struct i40e_pf *pf, char *buf, size_t len)
{
	u8 dsn[8];
@@ -165,7 +200,18 @@ void i40e_free_pf(struct i40e_pf *pf)
 **/
void i40e_devlink_register(struct i40e_pf *pf)
{
	devlink_register(priv_to_devlink(pf));
	struct devlink *dl = priv_to_devlink(pf);
	struct device *dev = &pf->pdev->dev;
	int err;

	err = devlink_params_register(dl, i40e_dl_params,
				      ARRAY_SIZE(i40e_dl_params));
	if (err)
		dev_err(dev,
			"devlink params register failed with error %d", err);

	devlink_register(dl);

}

/**
@@ -176,7 +222,11 @@ void i40e_devlink_register(struct i40e_pf *pf)
 **/
void i40e_devlink_unregister(struct i40e_pf *pf)
{
	devlink_unregister(priv_to_devlink(pf));
	struct devlink *dl = priv_to_devlink(pf);

	devlink_unregister(dl);
	devlink_params_unregister(dl, i40e_dl_params,
				  ARRAY_SIZE(i40e_dl_params));
}

/**
+23 −8
Original line number Diff line number Diff line
@@ -2935,33 +2935,48 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf,
		if (!f)
			++mac_add_cnt;
	}

	/* If this VF is not privileged, then we can't add more than a limited
	 * number of addresses.
	/* Determine the maximum number of MAC addresses this VF may use.
	 *
	 * - For untrusted VFs: use a fixed small limit.
	 *
	 * If this VF is trusted, it can use more resources than untrusted.
	 * However to ensure that every trusted VF has appropriate number of
	 * resources, divide whole pool of resources per port and then across
	 * all VFs.
	 * - For trusted VFs: limit is calculated by dividing total MAC
	 *  filter pool across all VFs/ports.
	 *
	 * - User can override this by devlink param "max_mac_per_vf".
	 *   If set its value is used as a strict cap for both trusted and
	 *   untrusted VFs.
	 *   Note:
	 *    even when overridden, this is a theoretical maximum; hardware
	 *    may reject additional MACs if the absolute HW limit is reached.
	 */
	if (!vf_trusted)
		mac_add_max = I40E_VC_MAX_MAC_ADDR_PER_VF;
	else
		mac_add_max = I40E_VC_MAX_MACVLAN_PER_TRUSTED_VF(pf->num_alloc_vfs, hw->num_ports);

	if (pf->max_mac_per_vf > 0)
		mac_add_max = pf->max_mac_per_vf;

	/* VF can replace all its filters in one step, in this case mac_add_max
	 * will be added as active and another mac_add_max will be in
	 * a to-be-removed state. Account for that.
	 */
	if ((i40e_count_active_filters(vsi) + mac_add_cnt) > mac_add_max ||
	    (i40e_count_all_filters(vsi) + mac_add_cnt) > 2 * mac_add_max) {
		if (pf->max_mac_per_vf == mac_add_max && mac_add_max > 0) {
			dev_err(&pf->pdev->dev,
				"Cannot add more MAC addresses: VF reached its maximum allowed limit (%d)\n",
				mac_add_max);
				return -EPERM;
		}
		if (!vf_trusted) {
			dev_err(&pf->pdev->dev,
				"Cannot add more MAC addresses, VF is not trusted, switch the VF to trusted to add more functionality\n");
			return -EPERM;
		} else {
			dev_err(&pf->pdev->dev,
				"Cannot add more MAC addresses, trusted VF exhausted it's resources\n");
				"Cannot add more MAC addresses: trusted VF reached its maximum allowed limit (%d)\n",
				mac_add_max);
			return -EPERM;
		}
	}
Loading