On SP230 the Rx MSI-X vector is asserted on every aggregation, even when
the application did not ask for Rx queue interrupts. With no eventfd to
acknowledge it, an unarmed vector keeps interrupting a core at the
aggregation rate.

Set up the per-queue vectors on SP230 even when Rx interrupts are
disabled, provided the interrupt backend supports multiple vectors: vfio
masks a vector after it fires and only user space can re-arm it, which
keeps the assertions off the CPUs. On igb_uio and uio_pci_generic the
vectors cannot be armed this way, so only the coalescing and resend
parameters are programmed and dev_start keeps working there.

Signed-off-by: Jiacheng Ye <[email protected]>
---
 drivers/net/hinic3/hinic3_ethdev.c | 43 ++++++++++++++++++++++++++++--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/net/hinic3/hinic3_ethdev.c 
b/drivers/net/hinic3/hinic3_ethdev.c
index 391967dbe4..2eb5909fff 100644
--- a/drivers/net/hinic3/hinic3_ethdev.c
+++ b/drivers/net/hinic3/hinic3_ethdev.c
@@ -1508,6 +1508,9 @@ hinic3_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, 
uint16_t queue_id)
        if (!rte_intr_dp_is_en(intr_handle) || !intr_handle->intr_vec)
                return 0;
 
+       if (HINIC3_IS_SP230_NIC(nic_dev) && !dev->data->dev_conf.intr_conf.rxq)
+               return 0;
+
        msix_intr = (uint16_t)intr_handle->intr_vec[queue_id];
        hinic3_set_msix_auto_mask_state(nic_dev->hwdev, msix_intr,
                                        HINIC3_SET_MSIX_AUTO_MASK);
@@ -1788,6 +1791,25 @@ hinic3_deinit_rxq_intr(struct rte_eth_dev *dev)
        }
 }
 
+static int
+hinic3_sp230_init_rxq_coalesce(struct rte_eth_dev *dev)
+{
+       struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
+       uint16_t msix_intr;
+       uint32_t i;
+       int err;
+
+       for (i = 0; i < dev->data->nb_rx_queues; i++) {
+               msix_intr = (uint16_t)(i + HINIC3_RX_VEC_START);
+
+               err = hinic3_init_rxq_msix_attr(nic_dev->hwdev, msix_intr);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
 /**
  * Initialize RX queue interrupts by enabling MSI-X, allocate interrupt 
vectors,
  * and configure interrupt attributes for each RX queue.
@@ -1812,8 +1834,25 @@ hinic3_init_rxq_intr(struct rte_eth_dev *dev)
 
        intr_handle = dev->intr_handle;
        nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
-       if (!dev->data->dev_conf.intr_conf.rxq)
-               return 0;
+
+       if (!dev->data->dev_conf.intr_conf.rxq) {
+               /*
+                * SP230 asserts the Rx MSI-X vector on every aggregation and
+                * nothing acknowledges it when Rx interrupts are disabled. On
+                * MSI-X capable setups set the per-queue vectors up anyway:
+                * vfio masks a vector after it fires and only user space can
+                * re-arm it, which keeps the assertions off the CPUs. Other
+                * interrupt backends (igb_uio, uio_pci_generic) cannot do
+                * that, so only program the coalescing parameters there.
+                */
+               if (!HINIC3_IS_SP230_NIC(nic_dev))
+                       return 0;
+
+               if (!rte_intr_cap_multiple(intr_handle))
+                       return hinic3_sp230_init_rxq_coalesce(dev);
+
+               /* Fall through to the per-queue MSI-X setup. */
+       }
 
        if (!rte_intr_cap_multiple(intr_handle)) {
                PMD_DRV_LOG(ERR, "Rx queue interrupts require MSI-X interrupts 
(vfio-pci driver)");
-- 
2.33.0

Reply via email to