Skip to content

Commit 2c031d4

Browse files
mohammadheibanguy11
authored andcommitted
i40e: support generic devlink param "max_mac_per_vf"
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" which 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 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/[email protected] https://lore.kernel.org/netdev/[email protected] Signed-off-by: Mohammad Heib <[email protected]> Reviewed-by: Jacob Keller <[email protected]> Reviewed-by: Aleksandr Loktionov <[email protected]> Reviewed-by: Simon Horman <[email protected]> Tested-by: Rafal Romanowski <[email protected]> Signed-off-by: Jacob Keller <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 9352d40 commit 2c031d4

File tree

4 files changed

+113
-10
lines changed

4 files changed

+113
-10
lines changed

Documentation/networking/devlink/i40e.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,40 @@ i40e devlink support
77
This document describes the devlink features implemented by the ``i40e``
88
device driver.
99

10+
Parameters
11+
==========
12+
13+
.. list-table:: Generic parameters implemented
14+
:widths: 5 5 90
15+
16+
* - Name
17+
- Mode
18+
- Notes
19+
* - ``max_mac_per_vf``
20+
- runtime
21+
- Controls the maximum number of MAC addresses a VF can use
22+
on i40e devices.
23+
24+
By default (``0``), the driver enforces its internally calculated per-VF
25+
MAC filter limit, which is based on the number of allocated VFS.
26+
27+
If set to a non-zero value, this parameter acts as a strict cap:
28+
the driver will use the user-provided value instead of its internal
29+
calculation.
30+
31+
**Important notes:**
32+
33+
- This value **must be set before enabling SR-IOV**.
34+
Attempting to change it while SR-IOV is enabled will return an error.
35+
- MAC filters are a **shared hardware resource** across all VFs.
36+
Setting a high value may cause other VFs to be starved of filters.
37+
- This value is a **Administrative policy**. The hardware may return
38+
errors when its absolute limit is reached, regardless of the value
39+
set here.
40+
41+
The default value is ``0`` (internal calculation is used).
42+
43+
1044
Info versions
1145
=============
1246

drivers/net/ethernet/intel/i40e/i40e.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,10 @@ struct i40e_pf {
574574
struct i40e_vf *vf;
575575
int num_alloc_vfs; /* actual number of VFs allocated */
576576
u32 vf_aq_requests;
577+
/* If set to non-zero, the device uses this value
578+
* as maximum number of MAC filters per VF.
579+
*/
580+
u32 max_mac_per_vf;
577581
u32 arq_overflows; /* Not fatal, possibly indicative of problems */
578582
struct ratelimit_state mdd_message_rate_limit;
579583
/* DCBx/DCBNL capability for PF that indicates

drivers/net/ethernet/intel/i40e/i40e_devlink.c

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,41 @@
55
#include "i40e.h"
66
#include "i40e_devlink.h"
77

8+
static int i40e_max_mac_per_vf_set(struct devlink *devlink,
9+
u32 id,
10+
struct devlink_param_gset_ctx *ctx,
11+
struct netlink_ext_ack *extack)
12+
{
13+
struct i40e_pf *pf = devlink_priv(devlink);
14+
15+
if (pf->num_alloc_vfs > 0) {
16+
NL_SET_ERR_MSG_MOD(extack,
17+
"Cannot change max_mac_per_vf while SR-IOV is enabled");
18+
return -EBUSY;
19+
}
20+
21+
pf->max_mac_per_vf = ctx->val.vu32;
22+
return 0;
23+
}
24+
25+
static int i40e_max_mac_per_vf_get(struct devlink *devlink,
26+
u32 id,
27+
struct devlink_param_gset_ctx *ctx)
28+
{
29+
struct i40e_pf *pf = devlink_priv(devlink);
30+
31+
ctx->val.vu32 = pf->max_mac_per_vf;
32+
return 0;
33+
}
34+
35+
static const struct devlink_param i40e_dl_params[] = {
36+
DEVLINK_PARAM_GENERIC(MAX_MAC_PER_VF,
37+
BIT(DEVLINK_PARAM_CMODE_RUNTIME),
38+
i40e_max_mac_per_vf_get,
39+
i40e_max_mac_per_vf_set,
40+
NULL),
41+
};
42+
843
static void i40e_info_get_dsn(struct i40e_pf *pf, char *buf, size_t len)
944
{
1045
u8 dsn[8];
@@ -165,7 +200,18 @@ void i40e_free_pf(struct i40e_pf *pf)
165200
**/
166201
void i40e_devlink_register(struct i40e_pf *pf)
167202
{
168-
devlink_register(priv_to_devlink(pf));
203+
struct devlink *dl = priv_to_devlink(pf);
204+
struct device *dev = &pf->pdev->dev;
205+
int err;
206+
207+
err = devlink_params_register(dl, i40e_dl_params,
208+
ARRAY_SIZE(i40e_dl_params));
209+
if (err)
210+
dev_err(dev,
211+
"devlink params register failed with error %d", err);
212+
213+
devlink_register(dl);
214+
169215
}
170216

171217
/**
@@ -176,7 +222,11 @@ void i40e_devlink_register(struct i40e_pf *pf)
176222
**/
177223
void i40e_devlink_unregister(struct i40e_pf *pf)
178224
{
179-
devlink_unregister(priv_to_devlink(pf));
225+
struct devlink *dl = priv_to_devlink(pf);
226+
227+
devlink_unregister(dl);
228+
devlink_params_unregister(dl, i40e_dl_params,
229+
ARRAY_SIZE(i40e_dl_params));
180230
}
181231

182232
/**

drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2935,33 +2935,48 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf,
29352935
if (!f)
29362936
++mac_add_cnt;
29372937
}
2938-
2939-
/* If this VF is not privileged, then we can't add more than a limited
2940-
* number of addresses.
2938+
/* Determine the maximum number of MAC addresses this VF may use.
2939+
*
2940+
* - For untrusted VFs: use a fixed small limit.
2941+
*
2942+
* - For trusted VFs: limit is calculated by dividing total MAC
2943+
* filter pool across all VFs/ports.
29412944
*
2942-
* If this VF is trusted, it can use more resources than untrusted.
2943-
* However to ensure that every trusted VF has appropriate number of
2944-
* resources, divide whole pool of resources per port and then across
2945-
* all VFs.
2945+
* - User can override this by devlink param "max_mac_per_vf".
2946+
* If set its value is used as a strict cap for both trusted and
2947+
* untrusted VFs.
2948+
* Note:
2949+
* even when overridden, this is a theoretical maximum; hardware
2950+
* may reject additional MACs if the absolute HW limit is reached.
29462951
*/
29472952
if (!vf_trusted)
29482953
mac_add_max = I40E_VC_MAX_MAC_ADDR_PER_VF;
29492954
else
29502955
mac_add_max = I40E_VC_MAX_MACVLAN_PER_TRUSTED_VF(pf->num_alloc_vfs, hw->num_ports);
29512956

2957+
if (pf->max_mac_per_vf > 0)
2958+
mac_add_max = pf->max_mac_per_vf;
2959+
29522960
/* VF can replace all its filters in one step, in this case mac_add_max
29532961
* will be added as active and another mac_add_max will be in
29542962
* a to-be-removed state. Account for that.
29552963
*/
29562964
if ((i40e_count_active_filters(vsi) + mac_add_cnt) > mac_add_max ||
29572965
(i40e_count_all_filters(vsi) + mac_add_cnt) > 2 * mac_add_max) {
2966+
if (pf->max_mac_per_vf == mac_add_max && mac_add_max > 0) {
2967+
dev_err(&pf->pdev->dev,
2968+
"Cannot add more MAC addresses: VF reached its maximum allowed limit (%d)\n",
2969+
mac_add_max);
2970+
return -EPERM;
2971+
}
29582972
if (!vf_trusted) {
29592973
dev_err(&pf->pdev->dev,
29602974
"Cannot add more MAC addresses, VF is not trusted, switch the VF to trusted to add more functionality\n");
29612975
return -EPERM;
29622976
} else {
29632977
dev_err(&pf->pdev->dev,
2964-
"Cannot add more MAC addresses, trusted VF exhausted it's resources\n");
2978+
"Cannot add more MAC addresses: trusted VF reached its maximum allowed limit (%d)\n",
2979+
mac_add_max);
29652980
return -EPERM;
29662981
}
29672982
}

0 commit comments

Comments
 (0)