Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F172536033
D59808.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D59808.id.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D59808: iavf: Report the programmed VF RSS configuration
Attached
Detach File
Event Timeline
Log In to Comment