Page MenuHomeFreeBSD

D58908.id184296.diff
No OneTemporary

D58908.id184296.diff

diff --git a/sys/dev/ice/ice_iov.c b/sys/dev/ice/ice_iov.c
--- a/sys/dev/ice/ice_iov.c
+++ b/sys/dev/ice/ice_iov.c
@@ -237,7 +237,7 @@
int i;
vf = ice_iov_get_vf(sc, vfnum);
- vf->vf_flags = VF_FLAG_ENABLED;
+ vf->vf_flags = 0;
/* This VF needs at least one VSI */
vsi = ice_alloc_vsi(sc, ICE_VSI_VF);
@@ -395,6 +395,7 @@
goto release_imap;
}
+ atomic_set_32(&vf->vf_flags, VF_FLAG_ENABLED);
ice_iov_ready_vf(sc, vf);
return (0);
@@ -418,8 +419,12 @@
free(vsi->tx_queues, M_ICE);
vsi->tx_queues = NULL;
release_vsi:
- ice_release_vsi(vsi);
+ if (vsi->hw_vsi_created)
+ ice_release_vsi(vsi);
+ else
+ ice_release_vsi_resources(vsi);
vf->vsi = NULL;
+ atomic_store_rel_32(&vf->vf_flags, 0);
return (error);
}
@@ -522,10 +527,13 @@
/* Release per-VF resources */
for (int i = 0; i < sc->num_vfs; i++) {
vf = &sc->vfs[i];
+ atomic_store_rel_32(&vf->vf_flags, 0);
vsi = vf->vsi;
/* Free VF interrupt reservation */
if (vf->vf_imap) {
+ ice_resmgr_release_map(&sc->dev_imgr, vf->vf_imap,
+ vf->num_irq_vectors);
free(vf->vf_imap, M_ICE);
vf->vf_imap = NULL;
}
@@ -553,7 +561,10 @@
vsi->rx_queues = NULL;
}
- ice_release_vsi(vsi);
+ if (vsi->hw_vsi_created)
+ ice_release_vsi(vsi);
+ else
+ ice_release_vsi_resources(vsi);
vf->vsi = NULL;
}
@@ -585,8 +596,17 @@
reg_idx = (hw->func_caps.vf_base_id + vf->vf_num) / 32;
bit_idx = (hw->func_caps.vf_base_id + vf->vf_num) % 32;
reg = rd32(hw, GLGEN_VFLRSTAT(reg_idx));
- if (reg & BIT(bit_idx))
+ if ((reg & BIT(bit_idx)) == 0)
+ continue;
+ if ((atomic_load_acq_32(&vf->vf_flags) &
+ VF_FLAG_ENABLED) != 0 && vf->vsi != NULL) {
ice_reset_vf(sc, vf, false);
+ continue;
+ }
+
+ /* Consume reset events for inactive or incompletely added VFs. */
+ wr32(hw, GLGEN_VFLRSTAT(reg_idx), BIT(bit_idx));
+ ice_flush(hw);
}
}
diff --git a/sys/dev/ice/ice_lib.h b/sys/dev/ice/ice_lib.h
--- a/sys/dev/ice/ice_lib.h
+++ b/sys/dev/ice/ice_lib.h
@@ -558,6 +558,7 @@
struct ice_softc *sc;
bool dynamic; /* if true, dynamically allocated */
+ bool hw_vsi_created; /* firmware owns a VSI for this handle */
enum ice_vsi_type type; /* type of this VSI */
u16 idx; /* software index to sc->all_vsi[] */
@@ -933,6 +934,7 @@
void ice_free_bar(device_t dev, struct ice_bar_info *bar);
void ice_set_ctrlq_len(struct ice_hw *hw);
void ice_release_vsi(struct ice_vsi *vsi);
+void ice_release_vsi_resources(struct ice_vsi *vsi);
struct ice_vsi *ice_alloc_vsi(struct ice_softc *sc, enum ice_vsi_type type);
void ice_alloc_vsi_qmap(struct ice_vsi *vsi, const int max_tx_queues,
const int max_rx_queues);
diff --git a/sys/dev/ice/ice_lib.c b/sys/dev/ice/ice_lib.c
--- a/sys/dev/ice/ice_lib.c
+++ b/sys/dev/ice/ice_lib.c
@@ -777,6 +777,7 @@
ice_aq_str(hw->adminq.sq_last_status));
return (EIO);
}
+ vsi->hw_vsi_created = true;
vsi->info = ctx.info;
/* Initialize VSI with just 1 TC to start */
@@ -816,6 +817,8 @@
/* Assert that the VSI pointer matches in the list */
MPASS(vsi == sc->all_vsi[vsi->idx]);
+ if (!vsi->hw_vsi_created)
+ return;
ctx.info = vsi->info;
@@ -837,9 +840,32 @@
"Free VSI %u AQ call failed, err %s aq_err %s\n",
vsi->idx, ice_status_str(status),
ice_aq_str(hw->adminq.sq_last_status));
+ } else {
+ vsi->hw_vsi_created = false;
}
}
+/*
+ * Release the queue maps and storage owned by a VSI. Callers must remove
+ * the VSI sysctl context before reaching this helper.
+ */
+static void
+ice_free_vsi_resources(struct ice_vsi *vsi)
+{
+ struct ice_softc *sc = vsi->sc;
+ int idx = vsi->idx;
+
+ /* Assert that the VSI pointer matches in the list */
+ MPASS(vsi == sc->all_vsi[idx]);
+
+ ice_free_vsi_qmaps(vsi);
+
+ if (vsi->dynamic)
+ free(sc->all_vsi[idx], M_ICE);
+
+ sc->all_vsi[idx] = NULL;
+}
+
/**
* ice_release_vsi - Release resources associated with a VSI
* @vsi: the VSI to release
@@ -851,16 +877,13 @@
void
ice_release_vsi(struct ice_vsi *vsi)
{
- struct ice_softc *sc = vsi->sc;
- int idx = vsi->idx;
-
- /* Assert that the VSI pointer matches in the list */
- MPASS(vsi == sc->all_vsi[idx]);
+ MPASS(vsi == vsi->sc->all_vsi[vsi->idx]);
/* Cleanup RSS configuration */
- if (ice_is_bit_set(sc->feat_en, ICE_FEATURE_RSS))
+ if (ice_is_bit_set(vsi->sc->feat_en, ICE_FEATURE_RSS))
ice_clean_vsi_rss_cfg(vsi);
+ /* Drain sysctl handlers before invalidating the hardware VSI. */
ice_del_vsi_sysctl_ctx(vsi);
/* Remove the configured mirror rule, if it exists */
@@ -870,16 +893,28 @@
* If we unload the driver after a reset fails, we do not need to do
* this step.
*/
- if (!ice_test_state(&sc->state, ICE_STATE_RESET_FAILED))
+ if (vsi->hw_vsi_created &&
+ !ice_test_state(&vsi->sc->state, ICE_STATE_RESET_FAILED)) {
+ ice_remove_vsi_fltr(&vsi->sc->hw, vsi->idx);
ice_deinit_vsi(vsi);
-
- ice_free_vsi_qmaps(vsi);
-
- if (vsi->dynamic) {
- free(sc->all_vsi[idx], M_ICE);
}
- sc->all_vsi[idx] = NULL;
+ ice_free_vsi_resources(vsi);
+}
+
+/**
+ * ice_release_vsi_resources - Release software resources for a VSI
+ * @vsi: the VSI to release
+ *
+ * Release resources allocated by ice_alloc_vsi() without issuing firmware
+ * commands. This is used when setup fails before ice_initialize_vsi() has
+ * attempted to create the VSI in hardware.
+ */
+void
+ice_release_vsi_resources(struct ice_vsi *vsi)
+{
+ ice_del_vsi_sysctl_ctx(vsi);
+ ice_free_vsi_resources(vsi);
}
/**
diff --git a/sys/dev/ice/if_ice_iflib.c b/sys/dev/ice/if_ice_iflib.c
--- a/sys/dev/ice/if_ice_iflib.c
+++ b/sys/dev/ice/if_ice_iflib.c
@@ -2669,11 +2669,17 @@
enum ice_ddp_state pkg_state;
int status;
int err;
+ int i;
sc->rebuild_ticks = ticks;
/* If we're rebuilding, then a reset has succeeded. */
ice_clear_state(&sc->state, ICE_STATE_RESET_FAILED);
+ /* The reset discarded every firmware VSI before reconstruction. */
+ for (i = 0; i < sc->num_available_vsi; i++) {
+ if (sc->all_vsi[i] != NULL)
+ sc->all_vsi[i]->hw_vsi_created = false;
+ }
/*
* If the firmware is in recovery mode, only restore the limited

File Metadata

Mime Type
text/plain
Expires
Thu, Sep 3, 8:04 PM (14 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37725332
Default Alt Text
D58908.id184296.diff (5 KB)

Event Timeline