Page MenuHomeFreeBSD

D58909.id184245.diff
No OneTemporary

D58909.id184245.diff

Index: sys/dev/ice/ice_iov.h
===================================================================
--- sys/dev/ice/ice_iov.h
+++ sys/dev/ice/ice_iov.h
@@ -41,6 +41,7 @@
#define _ICE_IOV_H_
#include <sys/types.h>
+#include <sys/bitstring.h>
#include <sys/bus.h>
#include <sys/nv.h>
#include <sys/iov_schema.h>
@@ -91,6 +92,8 @@
u16 mac_filter_cnt;
u16 vlan_limit;
u16 vlan_cnt;
+#define ICE_VF_VLAN_MAP_LEN (EVL_VLID_MASK + 1)
+ bitstr_t bit_decl(vlans_map, ICE_VF_VLAN_MAP_LEN);
u16 num_irq_vectors;
u16 *vf_imap;
Index: sys/dev/ice/ice_iov.c
===================================================================
--- sys/dev/ice/ice_iov.c
+++ sys/dev/ice/ice_iov.c
@@ -89,6 +89,8 @@
u8 *msg_buf);
static void ice_vc_del_vlan_msg(struct ice_softc *sc, struct ice_vf *vf,
u8 *msg_buf);
+static int ice_vc_select_vlans(struct ice_vf *vf, u16 *vids, u16 count,
+ bool add, u16 *selected_count);
static enum virtchnl_status_code ice_iov_err_to_virt_err(int ice_err);
static int ice_vf_validate_mac(struct ice_vf *vf, const uint8_t *addr);
@@ -1032,6 +1034,43 @@
v_status, NULL, 0, NULL);
}
+/**
+ * ice_vc_select_vlans - Compact a VF VLAN request in place
+ * @vf: VF tracking structure
+ * @vids: VLAN IDs supplied by the VF
+ * @count: number of VLAN IDs in the request
+ * @add: select absent VLANs for add, or present VLANs for delete
+ * @selected_count: returned number of VLAN IDs requiring a hardware change
+ *
+ * A VF may replay its entire VLAN configuration after a reset or retry a
+ * request whose reply was lost. Select only unique IDs whose membership
+ * actually changes so those requests remain idempotent and filter accounting
+ * continues to enforce the configured limit.
+ */
+static int
+ice_vc_select_vlans(struct ice_vf *vf, u16 *vids, u16 count, bool add,
+ u16 *selected_count)
+{
+ bitstr_t bit_decl(seen, ICE_VF_VLAN_MAP_LEN);
+ u16 selected, vid;
+
+ bzero(seen, sizeof(seen));
+ selected = 0;
+ for (u16 i = 0; i < count; i++) {
+ vid = vids[i];
+ if (vid > EVL_VLID_MASK)
+ return (EINVAL);
+ if (bit_test(seen, vid))
+ continue;
+ bit_set(seen, vid);
+ if (bit_test(vf->vlans_map, vid) == add)
+ continue;
+ vids[selected++] = vid;
+ }
+ *selected_count = selected;
+ return (0);
+}
+
/**
* ice_vc_add_vlan_msg - Handle VIRTCHNL_OP_ADD_VLAN msg from VF
* @sc: PF's softc structure
@@ -1045,6 +1084,7 @@
{
struct ice_hw *hw = &sc->hw;
struct virtchnl_vlan_filter_list *vlan_list;
+ u16 selected;
int status = 0;
enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
struct ice_vsi *vsi = vf->vsi;
@@ -1059,23 +1099,34 @@
goto done;
}
- if (vlan_list->num_elements > (vf->vlan_limit - vf->vlan_cnt)) {
- v_status = VIRTCHNL_STATUS_ERR_NO_MEMORY;
+ status = ice_vc_select_vlans(vf, vlan_list->vlan_id,
+ vlan_list->num_elements, true, &selected);
+ if (status != 0) {
+ v_status = VIRTCHNL_STATUS_ERR_PARAM;
goto done;
}
- status = ice_add_vlan_hw_filters(vsi, vlan_list->vlan_id,
- vlan_list->num_elements);
- if (status) {
- device_printf(sc->dev,
- "VF-%d: Failure adding VLANs to VSI %d, err %s aq_err %s\n",
- vf->vf_num, vsi->idx, ice_status_str(status),
- ice_aq_str(sc->hw.adminq.sq_last_status));
- v_status = ice_iov_err_to_virt_err(status);
+ if ((u32)vf->vlan_cnt + selected > vf->vlan_limit) {
+ v_status = VIRTCHNL_STATUS_ERR_NO_MEMORY;
goto done;
}
+ if (selected == 0)
+ goto done;
- vf->vlan_cnt += vlan_list->num_elements;
+ for (u16 i = 0; i < selected; i++) {
+ status = ice_add_vlan_hw_filter(vsi, vlan_list->vlan_id[i]);
+ if (status != 0 && status != ICE_ERR_ALREADY_EXISTS) {
+ device_printf(sc->dev,
+ "VF-%d: Failure adding VLAN %d to VSI %d, err %s aq_err %s\n",
+ vf->vf_num, vlan_list->vlan_id[i], vsi->idx,
+ ice_status_str(status),
+ ice_aq_str(sc->hw.adminq.sq_last_status));
+ v_status = ice_iov_err_to_virt_err(status);
+ goto done;
+ }
+ bit_set(vf->vlans_map, vlan_list->vlan_id[i]);
+ vf->vlan_cnt++;
+ }
done:
ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_ADD_VLAN,
@@ -1095,6 +1146,7 @@
{
struct ice_hw *hw = &sc->hw;
struct virtchnl_vlan_filter_list *vlan_list;
+ u16 selected;
int status = 0;
enum virtchnl_status_code v_status = VIRTCHNL_STATUS_SUCCESS;
struct ice_vsi *vsi = vf->vsi;
@@ -1109,21 +1161,30 @@
goto done;
}
- status = ice_remove_vlan_hw_filters(vsi, vlan_list->vlan_id,
- vlan_list->num_elements);
- if (status) {
- device_printf(sc->dev,
- "VF-%d: Failure deleting VLANs from VSI %d, err %s aq_err %s\n",
- vf->vf_num, vsi->idx, ice_status_str(status),
- ice_aq_str(sc->hw.adminq.sq_last_status));
- v_status = ice_iov_err_to_virt_err(status);
+ status = ice_vc_select_vlans(vf, vlan_list->vlan_id,
+ vlan_list->num_elements, false, &selected);
+ if (status != 0) {
+ v_status = VIRTCHNL_STATUS_ERR_PARAM;
goto done;
}
+ if (selected == 0)
+ goto done;
- if (vlan_list->num_elements >= vf->vlan_cnt)
- vf->vlan_cnt = 0;
- else
- vf->vlan_cnt -= vlan_list->num_elements;
+ for (u16 i = 0; i < selected; i++) {
+ status = ice_remove_vlan_hw_filter(vsi, vlan_list->vlan_id[i]);
+ if (status != 0 && status != ICE_ERR_DOES_NOT_EXIST) {
+ device_printf(sc->dev,
+ "VF-%d: Failure deleting VLAN %d from VSI %d, err %s aq_err %s\n",
+ vf->vf_num, vlan_list->vlan_id[i], vsi->idx,
+ ice_status_str(status),
+ ice_aq_str(sc->hw.adminq.sq_last_status));
+ v_status = ice_iov_err_to_virt_err(status);
+ goto done;
+ }
+ bit_clear(vf->vlans_map, vlan_list->vlan_id[i]);
+ MPASS(vf->vlan_cnt > 0);
+ vf->vlan_cnt--;
+ }
done:
ice_aq_send_msg_to_vf(hw, vf->vf_num, VIRTCHNL_OP_DEL_VLAN,
Index: sys/dev/ice/ice_lib.c
===================================================================
--- sys/dev/ice/ice_lib.c
+++ sys/dev/ice/ice_lib.c
@@ -5584,7 +5584,7 @@
}
status = ice_add_vlan(hw, &vlan_list);
- if (!status)
+ if (!status || status == ICE_ERR_ALREADY_EXISTS)
goto done;
device_printf(vsi->sc->dev, "Failed to add VLAN filters:\n");
@@ -5649,7 +5649,7 @@
}
status = ice_remove_vlan(hw, &vlan_list);
- if (!status)
+ if (!status || status == ICE_ERR_DOES_NOT_EXIST)
goto done;
device_printf(vsi->sc->dev, "Failed to remove VLAN filters:\n");

File Metadata

Mime Type
text/plain
Expires
Mon, Aug 24, 5:49 PM (10 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37082589
Default Alt Text
D58909.id184245.diff (6 KB)

Event Timeline