The device alarm skips AdminQ processing when the PF advertises WB_ON_ITR.
However, this capability does not guarantee that interrupt registration
succeeds. FreeBSD nic_uio cannot register device interrupts, so the VF
still needs alarm polling. Without it, commands such as RSS configuration
and statistics queries time out and device configuration fails.
Record whether AdminQ uses alarm polling instead of deriving that choice
from the PF capability. Initialize polling on each device initialization
and disable it only after interrupt registration and enablement succeed.
If enablement fails, unregister the callback before retaining polling.
Keep the shared PHC alarm and unconditional alarm cancellation unchanged.
Validated the backport to 25.11.4 on FreeBSD with an E810 ice PF: the stock
PMD failed configuration in three trials, while the correction passed 45
queue restarts, 42 full device resets and 6,432 exactly received frames.
Fixes: 388f0b348065 ("net/iavf: reuse device alarm for PHC sync")
Cc: [email protected]
Signed-off-by: Kevin Bowling <[email protected]>
---
GitHub review: https://github.com/DPDK/dpdk/pull/125
.mailmap | 1 +
drivers/net/intel/iavf/iavf.h | 1 +
drivers/net/intel/iavf/iavf_ethdev.c | 17 +++++++++++------
3 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/.mailmap b/.mailmap
index 492bb56acb..5c666ba171 100644
--- a/.mailmap
+++ b/.mailmap
@@ -889,6 +889,7 @@ Keith Wiles <[email protected]>
<[email protected]>
Kent Wires <[email protected]>
Kerem Aksu <[email protected]>
Keunhong Lee <[email protected]>
+Kevin Bowling <[email protected]>
Kevin Laatz <[email protected]>
Kevin Lampis <[email protected]>
Kevin Liu <[email protected]>
diff --git a/drivers/net/intel/iavf/iavf.h b/drivers/net/intel/iavf/iavf.h
index 8b826662c6..5550e57c35 100644
--- a/drivers/net/intel/iavf/iavf.h
+++ b/drivers/net/intel/iavf/iavf.h
@@ -399,6 +399,7 @@ struct iavf_adapter {
bool phc_sync_paused;
struct iavf_devargs devargs;
bool mac_primary_set;
+ bool adminq_polling; /* Interrupt setup fell back to alarm polling. */
uint16_t tpid; /* VLAN tag identifier */
};
diff --git a/drivers/net/intel/iavf/iavf_ethdev.c
b/drivers/net/intel/iavf/iavf_ethdev.c
index fd1067c252..47aa6ecb6f 100644
--- a/drivers/net/intel/iavf/iavf_ethdev.c
+++ b/drivers/net/intel/iavf/iavf_ethdev.c
@@ -2924,15 +2924,15 @@ void
iavf_dev_alarm_handler(void *param)
{
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
- struct iavf_info *vf;
+ struct iavf_adapter *adapter;
if (dev == NULL || dev->data == NULL || dev->data->dev_private == NULL)
return;
- vf = IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+ adapter = IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
struct iavf_hw *hw = IAVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t icr0;
- if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR)) {
+ if (adapter->adminq_polling) {
iavf_disable_irq0(hw);
/* read out interrupt causes */
@@ -3107,13 +3107,18 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.addr,
ð_dev->data->mac_addrs[0]);
+ adapter->adminq_polling = true;
if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_WB_ON_ITR &&
/* register callback func to eal lib */
rte_intr_callback_register(pci_dev->intr_handle,
- iavf_dev_interrupt_handler, (void *)eth_dev)
== 0)
-
+ iavf_dev_interrupt_handler, (void *)eth_dev)
== 0) {
/* enable uio intr after callback register */
- rte_intr_enable(pci_dev->intr_handle);
+ if (rte_intr_enable(pci_dev->intr_handle) == 0)
+ adapter->adminq_polling = false;
+ else
+ rte_intr_callback_unregister_sync(pci_dev->intr_handle,
+ iavf_dev_interrupt_handler,
eth_dev);
+ }
rte_eal_alarm_set(IAVF_ALARM_INTERVAL,
iavf_dev_alarm_handler, eth_dev);
base-commit: c981dcfe134e4c641951ee15a76de0b56aafb05a
--
2.56.0