The branch main has been updated by imp:
URL:
https://cgit.FreeBSD.org/src/commit/?id=430f1acc451c7084d1d5aa7df7e7ecccea1a8b51
commit 430f1acc451c7084d1d5aa7df7e7ecccea1a8b51
Author: Eric Joyner <eric.joy...@intel.com>
AuthorDate: 2024-10-17 22:19:09 +0000
Commit: Warner Losh <i...@freebsd.org>
CommitDate: 2025-07-18 19:16:17 +0000
ice(4): Add MAC filter and VLAN resource limits to VFs
Adds two new parameters to iovctl config for VLAN filter limits
and MAC
filter limits and gives them defaults of 64 and 16,
respectively.
These are intended to limit the number of resources that a VF
can
consume so that any one VF cannot starve an other VFs or the PF
of
filters.
Signed-off-by: Eric Joyner <eric.joy...@intel.com>
Signed-off-by: Krzysztof Galazka <krzysztof.gala...@intel.com>
Reviewed by: imp
Pull Request: https://github.com/freebsd/freebsd-src/pull/1573
---
sys/dev/ice/ice_iov.c | 45
++++++++++++++++++++++++++++++++++++++++++---
sys/dev/ice/ice_iov.h | 8 ++++++++
2 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/sys/dev/ice/ice_iov.c b/sys/dev/ice/ice_iov.c
index fc37a0e7679c..e06c7eb56f7a 100644
--- a/sys/dev/ice/ice_iov.c
+++ b/sys/dev/ice/ice_iov.c
@@ -117,6 +117,10 @@ ice_iov_attach(struct ice_softc *sc)
IOV_SCHEMA_HASDEFAULT, ICE_DEFAULT_VF_QUEUES);
pci_iov_schema_add_uint16(vf_schema, "mirror-src-vsi",
IOV_SCHEMA_HASDEFAULT, ICE_INVALID_MIRROR_VSI);
+ pci_iov_schema_add_uint16(vf_schema, "max-vlan-allowed",
+ IOV_SCHEMA_HASDEFAULT, ICE_DEFAULT_VF_VLAN_LIMIT);
+ pci_iov_schema_add_uint16(vf_schema, "max-mac-filters",
+ IOV_SCHEMA_HASDEFAULT, ICE_DEFAULT_VF_FILTER_LIMIT);
error = pci_iov_attach(dev, pf_schema, vf_schema);
if (error != 0) {
@@ -360,6 +364,9 @@ ice_iov_add_vf(struct ice_softc *sc, uint16_t
vfnum, const nvlist_t *params)
vsi->mirror_src_vsi = nvlist_get_number(params,
"mirror-src-vsi");
+ vf->vlan_limit = nvlist_get_number(params,
"max-vlan-allowed");
+ vf->mac_filter_limit = nvlist_get_number(params,
"max-mac-filters");
+
vf->vf_flags |= VF_FLAG_VLAN_CAP;
/* Create and setup VSI in HW */
@@ -735,10 +742,17 @@ ice_vc_add_eth_addr_msg(struct ice_softc *sc,
struct ice_vf *vf, u8 *msg_buf)
enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
struct virtchnl_ether_addr_list *addr_list;
struct ice_hw *hw = &sc->hw;
+ u16 added_addr_cnt = 0;
int error = 0;
addr_list = (struct virtchnl_ether_addr_list *)msg_buf;
+ if (addr_list->num_elements >
+ (vf->mac_filter_limit - vf->mac_filter_cnt)) {
+ v_status = VIRTCHNL_STATUS_ERR_NO_MEMORY;
+ goto done;
+ }
+
for (int i = 0; i < addr_list->num_elements; i++) {
u8 *addr = addr_list->list[i].addr;
@@ -767,10 +781,15 @@ ice_vc_add_eth_addr_msg(struct ice_softc *sc,
struct ice_vf *vf, u8 *msg_buf)
"%s: VF-%d: Error adding MAC addr for VSI
%d\n",
__func__, vf->vf_num, vf->vsi->idx);
v_status = VIRTCHNL_STATUS_ERR_PARAM;
- goto done;
+ continue;
}
+ /* Don't count VF's MAC against its MAC filter limit
*/
+ if (memcmp(addr, vf->mac, ETHER_ADDR_LEN))
+ added_addr_cnt++;
}
+ vf->mac_filter_cnt += added_addr_cnt;
+
done:
ice_aq_send_msg_to_vf(hw, vf->vf_num,
VIRTCHNL_OP_ADD_ETH_ADDR,
v_status, NULL, 0, NULL);
@@ -791,6 +810,7 @@ ice_vc_del_eth_addr_msg(struct ice_softc *sc,
struct ice_vf *vf, u8 *msg_buf)
enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
struct virtchnl_ether_addr_list *addr_list;
struct ice_hw *hw = &sc->hw;
+ u16 deleted_addr_cnt = 0;
int error = 0;
addr_list = (struct virtchnl_ether_addr_list *)msg_buf;
@@ -802,11 +822,18 @@ ice_vc_del_eth_addr_msg(struct ice_softc *sc,
struct ice_vf *vf, u8 *msg_buf)
"%s: VF-%d: Error removing MAC addr for
VSI %d\n",
__func__, vf->vf_num, vf->vsi->idx);
v_status = VIRTCHNL_STATUS_ERR_PARAM;
- goto done;
+ continue;
}
+ /* Don't count VF's MAC against its MAC filter limit
*/
+ if (memcmp(addr_list->list[i].addr, vf->mac,
ETHER_ADDR_LEN))
+ deleted_addr_cnt++;
}
-done:
+ if (deleted_addr_cnt >= vf->mac_filter_cnt)
+ vf->mac_filter_cnt = 0;
+ else
+ vf->mac_filter_cnt -= deleted_addr_cnt;
+
ice_aq_send_msg_to_vf(hw, vf->vf_num,
VIRTCHNL_OP_DEL_ETH_ADDR,
v_status, NULL, 0, NULL);
}
@@ -838,6 +865,11 @@ ice_vc_add_vlan_msg(struct ice_softc *sc,
struct ice_vf *vf, u8 *msg_buf)
goto done;
}
+ if (vlan_list->num_elements > (vf->vlan_limit - vf->vlan_cnt))
{
+ v_status = VIRTCHNL_STATUS_ERR_NO_MEMORY;
+ goto done;
+ }
+
status = ice_add_vlan_hw_filters(vsi, vlan_list->vlan_id,
vlan_list->num_elements);
if (status) {
@@ -849,6 +881,8 @@ ice_vc_add_vlan_msg(struct ice_softc *sc, struct
ice_vf *vf, u8 *msg_buf)
goto done;
}
+ vf->vlan_cnt += vlan_list->num_elements;
+
done:
ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_ADD_VLAN,
v_status, NULL, 0, NULL);
@@ -892,6 +926,11 @@ ice_vc_del_vlan_msg(struct ice_softc *sc,
struct ice_vf *vf, u8 *msg_buf)
goto done;
}
+ if (vlan_list->num_elements >= vf->vlan_cnt)
+ vf->vlan_cnt = 0;
+ else
+ vf->vlan_cnt -= vlan_list->num_elements;
+
done:
ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_DEL_VLAN,
v_status, NULL, 0, NULL);
diff --git a/sys/dev/ice/ice_iov.h b/sys/dev/ice/ice_iov.h
index c2ac5fcd5c94..c4fb3e932e3f 100644
--- a/sys/dev/ice/ice_iov.h
+++ b/sys/dev/ice/ice_iov.h
@@ -85,6 +85,11 @@ struct ice_vf {
u16 vf_num;
struct virtchnl_version_info version;
+ u16 mac_filter_limit;
+ u16 mac_filter_cnt;
+ u16 vlan_limit;
+ u16 vlan_cnt;
+
u16 num_irq_vectors;
u16 *vf_imap;
struct ice_irq_vector *tx_irqvs;
@@ -101,6 +106,9 @@ struct ice_vf {
#define ICE_VIRTCHNL_VALID_PROMISC_FLAGS
(FLAG_VF_UNICAST_PROMISC | \
FLAG_VF_MULTICAST_PROMISC)
+#define ICE_DEFAULT_VF_VLAN_LIMIT 64
+#define ICE_DEFAULT_VF_FILTER_LIMIT 16
+
int ice_iov_attach(struct ice_softc *sc);
int ice_iov_detach(struct ice_softc *sc);