Page MenuHomeFreeBSD

D59808.id.diff
No OneTemporary

D59808.id.diff

Index: sys/dev/iavf/iavf_iflib.h
===================================================================
--- sys/dev/iavf/iavf_iflib.h
+++ sys/dev/iavf/iavf_iflib.h
@@ -376,6 +376,13 @@
struct virtchnl_vf_resource *vf_res;
struct virtchnl_vsi_resource *vsi_res;
+ /* RSS query snapshot and outstanding requests, protected by vc_mtx. */
+ u8 rss_key[RSS_KEYSIZE];
+ u16 rss_key_size;
+ u64 rss_hena;
+ u32 rss_pending;
+ u32 rss_configured;
+
/* Misc stats maintained by the driver */
u64 admin_irq;
@@ -417,4 +424,5 @@
void iavf_enable_intr(struct iavf_vsi *);
void iavf_disable_intr(struct iavf_vsi *);
+void iavf_invalidate_rss(struct iavf_sc *);
#endif /* _IAVF_IFLIB_H_ */
Index: sys/dev/iavf/iavf_lib.c
===================================================================
--- sys/dev/iavf/iavf_lib.c
+++ sys/dev/iavf/iavf_lib.c
@@ -1097,6 +1097,11 @@
u32 rss_seed[IAVF_RSS_KEY_SIZE_REG] = {0};
u32 rss_hash_config;
+ IAVF_VC_LOCK_ASSERT(sc);
+ sc->rss_hena = 0;
+ sc->rss_key_size = 0;
+ sc->rss_configured = IAVF_FLAG_AQ_CONFIG_RSS_KEY |
+ IAVF_FLAG_AQ_SET_RSS_HENA;
/* Don't set up RSS if using a single queue */
if (IAVF_NRXQS(vsi) == 1) {
wr32(hw, IAVF_VFQF_HENA(0), 0);
@@ -1111,6 +1116,12 @@
/* Fill out hash function seed */
for (i = 0; i < IAVF_RSS_KEY_SIZE_REG; i++)
wr32(hw, IAVF_VFQF_HKEY(i), rss_seed[i]);
+ /* Report the register byte order, not the host's u32 representation. */
+ _Static_assert(sizeof(rss_seed) >= sizeof(sc->rss_key),
+ "RSS register key too small");
+ for (i = 0; i < RSS_KEYSIZE / sizeof(u32); i++)
+ le32enc(sc->rss_key + i * sizeof(u32), rss_seed[i]);
+ sc->rss_key_size = sizeof(sc->rss_key);
/* Enable PCTYPES for RSS: */
rss_hash_config = rss_gethashconfig();
@@ -1133,6 +1144,7 @@
hena |= set_hena;
wr32(hw, IAVF_VFQF_HENA(0), (u32)hena);
wr32(hw, IAVF_VFQF_HENA(1), (u32)(hena >> 32));
+ sc->rss_hena = hena;
/* Populate the LUT with max no. of queues in round robin fashion */
for (i = 0, j = 0; i < IAVF_RSS_VSI_LUT_SIZE; i++, j++) {
@@ -1191,7 +1203,9 @@
{
if (sc->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_REG) {
iavf_dbg_info(sc, "Setting up RSS using VF registers...\n");
+ IAVF_VC_LOCK(sc);
iavf_config_rss_reg(sc);
+ IAVF_VC_UNLOCK(sc);
} else if (sc->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
iavf_dbg_info(sc, "Setting up RSS using messages to PF...\n");
iavf_config_rss_pf(sc);
@@ -1199,6 +1213,17 @@
device_printf(sc->dev, "VF does not support RSS capability sent by PF.\n");
}
+/* Discard RSS query state when leaving the current running instance. */
+void
+iavf_invalidate_rss(struct iavf_sc *sc)
+{
+
+ IAVF_VC_LOCK(sc);
+ sc->rss_pending = 0;
+ sc->rss_configured = 0;
+ IAVF_VC_UNLOCK(sc);
+}
+
/**
* iavf_config_promisc - setup promiscuous mode
* @sc: device private softc
Index: sys/dev/iavf/iavf_vc_common.c
===================================================================
--- sys/dev/iavf/iavf_vc_common.c
+++ sys/dev/iavf/iavf_vc_common.c
@@ -799,9 +799,11 @@
iavf_config_rss_key(struct iavf_sc *sc)
{
struct virtchnl_rss_key *rss_key_msg;
- int msg_len, key_length;
+ int error, msg_len, key_length;
u32 rss_seed[IAVF_RSS_KEY_SIZE_REG] = {0};
+ mtx_assert(&sc->vc_mtx, MA_NOTOWNED);
+
/* Fetch the configured RSS key */
rss_getkey((uint8_t *) &rss_seed);
@@ -822,11 +824,21 @@
iavf_dbg_vc(sc, "%s: vsi_id %d, key_len %d\n", __func__,
rss_key_msg->vsi_id, rss_key_msg->key_len);
- iavf_send_pf_msg(sc, VIRTCHNL_OP_CONFIG_RSS_KEY,
+ IAVF_VC_LOCK(sc);
+ sc->rss_configured &= ~IAVF_FLAG_AQ_CONFIG_RSS_KEY;
+ sc->rss_pending |= IAVF_FLAG_AQ_CONFIG_RSS_KEY;
+ /* Standard IPv4/IPv6 tuples use the first 40 bytes of the 52-byte key. */
+ sc->rss_key_size = MIN(key_length, sizeof(sc->rss_key));
+ bzero(sc->rss_key, sizeof(sc->rss_key));
+ memcpy(sc->rss_key, rss_seed, sc->rss_key_size);
+ error = iavf_send_pf_msg(sc, VIRTCHNL_OP_CONFIG_RSS_KEY,
(u8 *)rss_key_msg, msg_len);
+ if (error != 0)
+ sc->rss_pending &= ~IAVF_FLAG_AQ_CONFIG_RSS_KEY;
+ IAVF_VC_UNLOCK(sc);
free(rss_key_msg, M_IAVF);
- return (0);
+ return (error);
}
/**
@@ -837,13 +849,16 @@
*
* @remark the reply from the PF is not checked by this function.
*
- * @returns zero
+ * @returns zero on success, or an error code on failure.
*/
int
iavf_set_rss_hena(struct iavf_sc *sc)
{
struct virtchnl_rss_hena hena;
struct iavf_hw *hw = &sc->hw;
+ int error;
+
+ mtx_assert(&sc->vc_mtx, MA_NOTOWNED);
if (hw->mac.type == IAVF_MAC_VF)
hena.hena = IAVF_DEFAULT_RSS_HENA_AVF;
@@ -852,9 +867,16 @@
else
hena.hena = IAVF_DEFAULT_RSS_HENA_BASE;
- iavf_send_pf_msg(sc, VIRTCHNL_OP_SET_RSS_HENA,
+ IAVF_VC_LOCK(sc);
+ sc->rss_configured &= ~IAVF_FLAG_AQ_SET_RSS_HENA;
+ sc->rss_pending |= IAVF_FLAG_AQ_SET_RSS_HENA;
+ sc->rss_hena = hena.hena;
+ error = iavf_send_pf_msg(sc, VIRTCHNL_OP_SET_RSS_HENA,
(u8 *)&hena, sizeof(hena));
- return (0);
+ if (error != 0)
+ sc->rss_pending &= ~IAVF_FLAG_AQ_SET_RSS_HENA;
+ IAVF_VC_UNLOCK(sc);
+ return (error);
}
/**
@@ -1283,6 +1305,9 @@
enum virtchnl_status_code v_retval, u8 *msg, u16 msglen __unused)
{
device_t dev = sc->dev;
+ u32 rss_op;
+
+ IAVF_VC_LOCK_ASSERT(sc);
if (v_opcode != VIRTCHNL_OP_GET_STATS)
iavf_dbg_vc(sc, "%s: opcode %s\n", __func__,
@@ -1299,6 +1324,8 @@
case VIRTCHNL_EVENT_RESET_IMPENDING:
device_printf(dev, "PF initiated reset!\n");
iavf_set_state(&sc->state, IAVF_STATE_RESET_PENDING);
+ sc->rss_pending = 0;
+ sc->rss_configured = 0;
break;
default:
iavf_dbg_vc(sc, "Unknown event %d from AQ\n",
@@ -1313,6 +1340,17 @@
v_opcode == VIRTCHNL_OP_DEL_VLAN)
iavf_vlan_completion(sc, v_opcode, v_retval);
+ rss_op = 0;
+ if (v_opcode == VIRTCHNL_OP_CONFIG_RSS_KEY)
+ rss_op = IAVF_FLAG_AQ_CONFIG_RSS_KEY;
+ else if (v_opcode == VIRTCHNL_OP_SET_RSS_HENA)
+ rss_op = IAVF_FLAG_AQ_SET_RSS_HENA;
+ if (sc->rss_pending & rss_op) {
+ sc->rss_pending &= ~rss_op;
+ if (v_retval == VIRTCHNL_STATUS_SUCCESS)
+ sc->rss_configured |= rss_op;
+ }
+
/* Catch-all error response */
if (v_retval) {
bool print_error = true;
Index: sys/dev/iavf/if_iavf_iflib.c
===================================================================
--- sys/dev/iavf/if_iavf_iflib.c
+++ sys/dev/iavf/if_iavf_iflib.c
@@ -87,6 +87,8 @@
static void iavf_if_vlan_register(if_ctx_t ctx, u16 vtag);
static void iavf_if_vlan_unregister(if_ctx_t ctx, u16 vtag);
static uint64_t iavf_if_get_counter(if_ctx_t ctx, ift_counter cnt);
+static int iavf_if_get_rss_key(if_ctx_t, struct ifrsskey *);
+static int iavf_if_get_rss_hash(if_ctx_t, struct ifrsshash *);
static void iavf_if_init(if_ctx_t ctx);
static void iavf_if_stop(if_ctx_t ctx);
static bool iavf_if_needs_restart(if_ctx_t, enum iflib_restart_event);
@@ -203,6 +205,8 @@
DEVMETHOD(ifdi_vlan_register, iavf_if_vlan_register),
DEVMETHOD(ifdi_vlan_unregister, iavf_if_vlan_unregister),
DEVMETHOD(ifdi_get_counter, iavf_if_get_counter),
+ DEVMETHOD(ifdi_get_rss_key, iavf_if_get_rss_key),
+ DEVMETHOD(ifdi_get_rss_hash, iavf_if_get_rss_hash),
DEVMETHOD(ifdi_needs_restart, iavf_if_needs_restart),
DEVMETHOD_END
};
@@ -1095,6 +1099,7 @@
atomic_store_rel_32(&sc->vc_reinit_required, 1);
if (atomic_readandclear_32(&sc->mbx_ready) == 0)
return;
+ iavf_invalidate_rss(sc);
vsi = &sc->vsi;
iavf_clear_state(&sc->state, IAVF_STATE_RUNNING);
sc->link_up = false;
@@ -1260,6 +1265,7 @@
INIT_DBG_IF(ifp, "begin");
sx_assert(iflib_ctx_lock_get(ctx), SA_XLOCKED);
+ iavf_invalidate_rss(sc);
iavf_mbx_retry_prepare(sc);
if (iavf_test_state(&sc->state, IAVF_STATE_DMA_FENCED)) {
if (iavf_mbx_log_allowed(sc))
@@ -1367,6 +1373,84 @@
iavf_mbx_retry_failed(ctx);
}
+/* Query only a complete configuration from the current running instance. */
+static int
+iavf_rss_query_status(struct iavf_sc *sc)
+{
+
+ sx_assert(iflib_ctx_lock_get(sc->vsi.ctx), SA_XLOCKED);
+ IAVF_VC_LOCK_ASSERT(sc);
+ if (sc->vf_res == NULL)
+ return (ENXIO);
+ if ((sc->vf_res->vf_cap_flags & (VIRTCHNL_VF_OFFLOAD_RSS_REG |
+ VIRTCHNL_VF_OFFLOAD_RSS_PF)) == 0)
+ return (EOPNOTSUPP);
+ if (!iavf_test_state(&sc->state, IAVF_STATE_RUNNING) ||
+ iavf_test_state(&sc->state, IAVF_STATE_RESET_PENDING) ||
+ iavf_test_state(&sc->state, IAVF_STATE_RESET_REQUIRED) ||
+ iavf_test_state(&sc->state, IAVF_STATE_RESET_RECOVERY) ||
+ atomic_load_acq_32(&sc->mbx_ready) == 0 ||
+ atomic_load_acq_32(&sc->vc_reinit_required) != 0 ||
+ sc->rss_configured != (IAVF_FLAG_AQ_CONFIG_RSS_KEY |
+ IAVF_FLAG_AQ_SET_RSS_HENA))
+ return (ENXIO);
+ return (0);
+}
+
+static int
+iavf_if_get_rss_key(if_ctx_t ctx, struct ifrsskey *ifrk)
+{
+ struct iavf_sc *sc = iavf_sc_from_ctx(ctx);
+ int error;
+
+ IAVF_VC_LOCK(sc);
+ error = iavf_rss_query_status(sc);
+ if (error == 0) {
+ ifrk->ifrk_func = sc->rss_hena == 0 ? RSS_FUNC_NONE :
+ RSS_FUNC_TOEPLITZ;
+ ifrk->ifrk_keylen = sc->rss_hena == 0 ? 0 : sc->rss_key_size;
+ _Static_assert(sizeof(ifrk->ifrk_key) >= sizeof(sc->rss_key),
+ "RSS query buffer too small");
+ bzero(ifrk->ifrk_key, sizeof(ifrk->ifrk_key));
+ memcpy(ifrk->ifrk_key, sc->rss_key, ifrk->ifrk_keylen);
+ }
+ IAVF_VC_UNLOCK(sc);
+ return (error);
+}
+
+static int
+iavf_if_get_rss_hash(if_ctx_t ctx, struct ifrsshash *ifrh)
+{
+ struct iavf_sc *sc = iavf_sc_from_ctx(ctx);
+ u64 hena;
+ int error;
+
+ IAVF_VC_LOCK(sc);
+ error = iavf_rss_query_status(sc);
+ if (error == 0) {
+ hena = sc->rss_hena;
+ ifrh->ifrh_func = hena == 0 ? RSS_FUNC_NONE : RSS_FUNC_TOEPLITZ;
+ ifrh->ifrh_types = 0;
+ /* Fragment PCTYPEs are not IPv6 extension-header selections. */
+ if (hena & (BIT_ULL(IAVF_FILTER_PCTYPE_NONF_IPV4_OTHER) |
+ BIT_ULL(IAVF_FILTER_PCTYPE_FRAG_IPV4)))
+ ifrh->ifrh_types |= RSS_TYPE_IPV4;
+ if (hena & BIT_ULL(IAVF_FILTER_PCTYPE_NONF_IPV4_TCP))
+ ifrh->ifrh_types |= RSS_TYPE_TCP_IPV4;
+ if (hena & BIT_ULL(IAVF_FILTER_PCTYPE_NONF_IPV4_UDP))
+ ifrh->ifrh_types |= RSS_TYPE_UDP_IPV4;
+ if (hena & (BIT_ULL(IAVF_FILTER_PCTYPE_NONF_IPV6_OTHER) |
+ BIT_ULL(IAVF_FILTER_PCTYPE_FRAG_IPV6)))
+ ifrh->ifrh_types |= RSS_TYPE_IPV6;
+ if (hena & BIT_ULL(IAVF_FILTER_PCTYPE_NONF_IPV6_TCP))
+ ifrh->ifrh_types |= RSS_TYPE_TCP_IPV6;
+ if (hena & BIT_ULL(IAVF_FILTER_PCTYPE_NONF_IPV6_UDP))
+ ifrh->ifrh_types |= RSS_TYPE_UDP_IPV6;
+ }
+ IAVF_VC_UNLOCK(sc);
+ return (error);
+}
+
/**
* iavf_if_msix_intr_assign - Assign MSI-X interrupts
* @ctx: the iflib context pointer
@@ -2413,6 +2497,7 @@
vsi = &sc->vsi;
iavf_mbx_retry_stop(sc);
iavf_clear_state(&sc->state, IAVF_STATE_RUNNING);
+ iavf_invalidate_rss(sc);
iavf_disable_intr(vsi);

File Metadata

Mime Type
text/plain
Expires
Sun, Sep 20, 2:43 AM (5 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39219649
Default Alt Text
D59808.id.diff (10 KB)

Event Timeline