* [PATCH net-next,v2,1/2] devlink: Add new "max_mac_per_vf" generic device param
@ 2025-09-03 19:02 mheib
2025-09-03 19:02 ` [PATCH net-next,v2,2/2] i40e: support generic devlink param "max_mac_per_vf" mheib
2025-09-03 20:11 ` [PATCH net-next,v2,1/2] devlink: Add new "max_mac_per_vf" generic device param Jacob Keller
0 siblings, 2 replies; 5+ messages in thread
From: mheib @ 2025-09-03 19:02 UTC (permalink / raw)
To: intel-wired-lan
Cc: przemyslawx.patynowski, jiri, netdev, horms, jacob.e.keller,
aleksandr.loktionov, anthony.l.nguyen, przemyslaw.kitszel,
Mohammad Heib
From: Mohammad Heib <mheib@redhat.com>
Add a new device generic parameter to controls the maximum
number of MAC filters allowed per VF.
While this parameter is named `max_mac_per_vf`, the exact enforcement
policy may vary between drivers. For example, i40e applies this limit
only to trusted VFs, whereas other drivers may choose to apply it
uniformly across all VFs. The goal is to provide a consistent devlink
interface, while allowing flexibility for driver-specific behavior.
For example, to limit a VF to 3 MAC addresses:
$ devlink dev param set pci/0000:3b:00.0 name max_mac_per_vf \
value 3 \
cmode runtime
Signed-off-by: Mohammad Heib <mheib@redhat.com>
---
Documentation/networking/devlink/devlink-params.rst | 8 ++++++++
include/net/devlink.h | 4 ++++
net/devlink/param.c | 5 +++++
3 files changed, 17 insertions(+)
diff --git a/Documentation/networking/devlink/devlink-params.rst b/Documentation/networking/devlink/devlink-params.rst
index 211b58177e12..2bc9995fd849 100644
--- a/Documentation/networking/devlink/devlink-params.rst
+++ b/Documentation/networking/devlink/devlink-params.rst
@@ -143,3 +143,11 @@ own name.
* - ``clock_id``
- u64
- Clock ID used by the device for registering DPLL devices and pins.
+ * - ``max_mac_per_vf``
+ - u32
+ - Controls the maximum number of MAC address filters that can be assigned
+ to a Virtual Function (VF).
+ The exact enforcement may depend on driver capabilities. For example,
+ some drivers may apply this limit only to *trusted* VFs, while others may
+ apply it to all VFs uniformly. This allows a consistent parameter across
+ devices while leaving flexibility for driver-specific behavior.
diff --git a/include/net/devlink.h b/include/net/devlink.h
index b32c9ceeb81d..dde5dcbca625 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -530,6 +530,7 @@ enum devlink_param_generic_id {
DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
DEVLINK_PARAM_GENERIC_ID_ENABLE_PHC,
DEVLINK_PARAM_GENERIC_ID_CLOCK_ID,
+ DEVLINK_PARAM_GENERIC_ID_MAX_MAC_PER_VF,
/* add new param generic ids above here*/
__DEVLINK_PARAM_GENERIC_ID_MAX,
@@ -594,6 +595,9 @@ enum devlink_param_generic_id {
#define DEVLINK_PARAM_GENERIC_CLOCK_ID_NAME "clock_id"
#define DEVLINK_PARAM_GENERIC_CLOCK_ID_TYPE DEVLINK_PARAM_TYPE_U64
+#define DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_NAME "max_mac_per_vf"
+#define DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_TYPE DEVLINK_PARAM_TYPE_U32
+
#define DEVLINK_PARAM_GENERIC(_id, _cmodes, _get, _set, _validate) \
{ \
.id = DEVLINK_PARAM_GENERIC_ID_##_id, \
diff --git a/net/devlink/param.c b/net/devlink/param.c
index 41dcc86cfd94..62fd789ae01c 100644
--- a/net/devlink/param.c
+++ b/net/devlink/param.c
@@ -102,6 +102,11 @@ static const struct devlink_param devlink_param_generic[] = {
.name = DEVLINK_PARAM_GENERIC_CLOCK_ID_NAME,
.type = DEVLINK_PARAM_GENERIC_CLOCK_ID_TYPE,
},
+ {
+ .id = DEVLINK_PARAM_GENERIC_ID_MAX_MAC_PER_VF,
+ .name = DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_NAME,
+ .type = DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_TYPE,
+ },
};
static int devlink_param_generic_verify(const struct devlink_param *param)
--
2.50.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH net-next,v2,2/2] i40e: support generic devlink param "max_mac_per_vf"
2025-09-03 19:02 [PATCH net-next,v2,1/2] devlink: Add new "max_mac_per_vf" generic device param mheib
@ 2025-09-03 19:02 ` mheib
2025-09-03 20:11 ` [PATCH net-next,v2,1/2] devlink: Add new "max_mac_per_vf" generic device param Jacob Keller
1 sibling, 0 replies; 5+ messages in thread
From: mheib @ 2025-09-03 19:02 UTC (permalink / raw)
To: intel-wired-lan
Cc: przemyslawx.patynowski, jiri, netdev, horms, jacob.e.keller,
aleksandr.loktionov, anthony.l.nguyen, przemyslaw.kitszel,
Mohammad Heib
From: Mohammad Heib <mheib@redhat.com>
Currently the i40e driver enforces its own internally calculated per-VF MAC
filter limit, derived from the number of allocated VFs and available
hardware resources. This limit is not configurable by the administrator,
which makes it difficult to control how many MAC addresses each VF may
use.
This patch adds support for the new generic devlink runtime parameter
"max_mac_per_vf". On i40e, the parameter affects only trusted VFs. It
provides administrators with a way to cap the number of MAC addresses a
VF can use:
- When the parameter is set to 0 (default), the driver continues to use
its internally calculated limit.
- When set to a non-zero value, the driver applies this value as a strict
cap for trusted VFs, overriding the internal calculation.
Important notes:
- The configured value is a theoretical maximum. Hardware limits may
still prevent additional MAC addresses from being added, even if the
parameter allows it.
- Since MAC filters are a shared hardware resource across all VFs,
setting a high value may cause resource contention and starve other
VFs.
- This change gives administrators predictable and flexible control over
VF resource allocation, while still respecting hardware limitations.
- Previous discussion about this change:
https://lore.kernel.org/netdev/20250805134042.2604897-2-dhill@redhat.com
https://lore.kernel.org/netdev/20250823094952.182181-1-mheib@redhat.com
Signed-off-by: Mohammad Heib <mheib@redhat.com>
---
Documentation/networking/devlink/i40e.rst | 35 ++++++++++++++
drivers/net/ethernet/intel/i40e/i40e.h | 4 ++
.../net/ethernet/intel/i40e/i40e_devlink.c | 48 ++++++++++++++++++-
.../ethernet/intel/i40e/i40e_virtchnl_pf.c | 28 +++++++----
4 files changed, 103 insertions(+), 12 deletions(-)
diff --git a/Documentation/networking/devlink/i40e.rst b/Documentation/networking/devlink/i40e.rst
index d3cb5bb5197e..3052f638fdd5 100644
--- a/Documentation/networking/devlink/i40e.rst
+++ b/Documentation/networking/devlink/i40e.rst
@@ -7,6 +7,41 @@ 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 **trusted 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:**
+ - 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 **theoretical maximum**. The hardware may return
+ errors when its absolute limit is reached, regardless of the value
+ set here.
+
+ - Only **trusted VFs** are affected; untrusted VFs use a fixed small
+ limit.
+
+ The default value is ``0`` (internal calculation is used).
+
+
Info versions
=============
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index 801a57a925da..d2d03db2acec 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -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
diff --git a/drivers/net/ethernet/intel/i40e/i40e_devlink.c b/drivers/net/ethernet/intel/i40e/i40e_devlink.c
index cc4e9e2addb7..cd01e35da94e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_devlink.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_devlink.c
@@ -5,6 +5,35 @@
#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);
+
+ 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 +194,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 +216,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));
}
/**
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 081a4526a2f0..e6d90d51221b 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -2935,19 +2935,26 @@ 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.
+ *
+ * - For trusted VFs: limit is calculated by dividing total MAC
+ * filter pool across all VFs/ports.
*
- * 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.
+ * - User can override this by devlink param "max_mac_per_vf".
+ * If set its value is used as a strict cap.
+ * Note:
+ * even when overridden, this is a theoretical maximum; hardware
+ * may reject additional MACs if the absolute HW limit is reached.
*/
- if (!vf_trusted)
+ if (!vf_trusted) {
mac_add_max = I40E_VC_MAX_MAC_ADDR_PER_VF;
- else
+ } 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
@@ -2961,7 +2968,8 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf,
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;
}
}
--
2.50.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net-next,v2,1/2] devlink: Add new "max_mac_per_vf" generic device param
2025-09-03 19:02 [PATCH net-next,v2,1/2] devlink: Add new "max_mac_per_vf" generic device param mheib
2025-09-03 19:02 ` [PATCH net-next,v2,2/2] i40e: support generic devlink param "max_mac_per_vf" mheib
@ 2025-09-03 20:11 ` Jacob Keller
2025-09-03 21:44 ` mohammad heib
1 sibling, 1 reply; 5+ messages in thread
From: Jacob Keller @ 2025-09-03 20:11 UTC (permalink / raw)
To: mheib, intel-wired-lan
Cc: przemyslawx.patynowski, jiri, netdev, horms, aleksandr.loktionov,
anthony.l.nguyen, przemyslaw.kitszel
[-- Attachment #1.1: Type: text/plain, Size: 830 bytes --]
On 9/3/2025 12:02 PM, mheib@redhat.com wrote:
> From: Mohammad Heib <mheib@redhat.com>
>
> Add a new device generic parameter to controls the maximum
> number of MAC filters allowed per VF.
>
> While this parameter is named `max_mac_per_vf`, the exact enforcement
> policy may vary between drivers. For example, i40e applies this limit
> only to trusted VFs, whereas other drivers may choose to apply it
> uniformly across all VFs. The goal is to provide a consistent devlink
> interface, while allowing flexibility for driver-specific behavior.
>
Would it make more sense to apply the limit to all VFs if set, and apply
the default variable behavior for when its unset? This would avoid the
need to have this much flexibility and latitude for each driver.
It seems like that wouldn't be too difficult.
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net-next,v2,1/2] devlink: Add new "max_mac_per_vf" generic device param
2025-09-03 20:11 ` [PATCH net-next,v2,1/2] devlink: Add new "max_mac_per_vf" generic device param Jacob Keller
@ 2025-09-03 21:44 ` mohammad heib
2025-09-04 0:01 ` Jacob Keller
0 siblings, 1 reply; 5+ messages in thread
From: mohammad heib @ 2025-09-03 21:44 UTC (permalink / raw)
To: Jacob Keller, intel-wired-lan
Cc: przemyslawx.patynowski, jiri, netdev, horms, aleksandr.loktionov,
anthony.l.nguyen, przemyslaw.kitszel
Hi Jacob,
Thanks for the review.
It’s indeed an easy change. I’m wondering why untrusted VFs were
originally limited to 16+2 MACs, and if changing this (overwriting that
behavior) could be risky.
Anyway, I applied your suggestions in v3.
On 9/3/25 11:11 PM, Jacob Keller wrote:
>
>
> On 9/3/2025 12:02 PM, mheib@redhat.com wrote:
>> From: Mohammad Heib <mheib@redhat.com>
>>
>> Add a new device generic parameter to controls the maximum
>> number of MAC filters allowed per VF.
>>
>> While this parameter is named `max_mac_per_vf`, the exact enforcement
>> policy may vary between drivers. For example, i40e applies this limit
>> only to trusted VFs, whereas other drivers may choose to apply it
>> uniformly across all VFs. The goal is to provide a consistent devlink
>> interface, while allowing flexibility for driver-specific behavior.
>>
>
> Would it make more sense to apply the limit to all VFs if set, and apply
> the default variable behavior for when its unset? This would avoid the
> need to have this much flexibility and latitude for each driver.
>
> It seems like that wouldn't be too difficult.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net-next,v2,1/2] devlink: Add new "max_mac_per_vf" generic device param
2025-09-03 21:44 ` mohammad heib
@ 2025-09-04 0:01 ` Jacob Keller
0 siblings, 0 replies; 5+ messages in thread
From: Jacob Keller @ 2025-09-04 0:01 UTC (permalink / raw)
To: mohammad heib, intel-wired-lan
Cc: przemyslawx.patynowski, jiri, netdev, horms, aleksandr.loktionov,
anthony.l.nguyen, przemyslaw.kitszel
[-- Attachment #1.1: Type: text/plain, Size: 3139 bytes --]
On 9/3/2025 2:44 PM, mohammad heib wrote:
> Hi Jacob,
>
> Thanks for the review.
>
> It’s indeed an easy change. I’m wondering why untrusted VFs were
> originally limited to 16+2 MACs, and if changing this (overwriting that
> behavior) could be risky.
>
> Anyway, I applied your suggestions in v3.
>
The limit appears to come from 5f527ba962e2 ("i40e: Limit the number of
MAC and VLAN addresses that can be added for VFs") which is from 2016.
The commit message unfortunately does not describe a reason for the
specific limit. Prior to this change, any VF could use any number of
MACs, and thus could cause resource starvation for all VFs. Curiously
this limit was set to 8 originally.
In 2017, this limit was increased by commit 4dbc56613962 ("i40e: Allow
untrusted VFs to have more filters") to 12 filters. It has some
justification:
> Our original filter limit of 8 was based on behavior that we saw from
> Linux VMs. Now we're running Other Operating Systems under KVM and we
> see that they commonly use more MAC filters. Since it seems weird to
> require people to enable trusted VFs just to boot their OS, bump the
> number of filters allowed by default.
In 2019 the limit was further increased to 18 via commit 06b6e2a2333e
("i40e: Able to add up to 16 MAC filters on an untrusted VF") which
increased the limit to up to 16 MAC filters (16 + 1 for broadcast and 1
for the default unicast address). Little to no justification is provided
as to why 16 was chosen.
I tried looking through internal change logs on the out-of-tree releases
we have for i40e, and it also has a limit of 18 (16 + 2). It looks this
change possibly came as part of a request from customers, which I cannot
find any publicly sharable information on.
Given all this, as far as I can tell the only thing that an untrusted VF
could do is consume more MAC filter resources that otherwise would go to
the PF or another VF. By allowing the system administrator to tune this
to any value, I think it gives more flexibility to all customers, and
will prevent us from needing to further continue to raise this limit to
one that matches their environment. There is an absolute upper bound of
MAC filters available in hardware, but each system may have many or few
VFs and can better use that limit with a control knob to limit untrusted
VFs to the appropriate maximum that is suitable within their constraints.
Going with resources (eventually) would allow even more flexibility by
not requiring the same limit on all VFs, and by providing clear limits
on the hardware upper bound to the userspace. However, I think that can
be handled separately, and this simple knob is a much needed step in the
right direction. Its clear we (Intel) have had to change this value *3*
times already just for i40e. (from 0 to 8, to 12, to 18).
I suspect ice also has the exact same limitation, and we can and should
generate a patch to enable the same behavior in ice. I have no problem
with doing that as a follow-up after this merges. No need to add more
work to your plate here.
Thanks,
Jake
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 236 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-09-04 0:01 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-03 19:02 [PATCH net-next,v2,1/2] devlink: Add new "max_mac_per_vf" generic device param mheib
2025-09-03 19:02 ` [PATCH net-next,v2,2/2] i40e: support generic devlink param "max_mac_per_vf" mheib
2025-09-03 20:11 ` [PATCH net-next,v2,1/2] devlink: Add new "max_mac_per_vf" generic device param Jacob Keller
2025-09-03 21:44 ` mohammad heib
2025-09-04 0:01 ` Jacob Keller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).