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);