net/ice: fix wrong interrupt vector overwritten
Checks
Commit Message
ice_vsi_queues_bind_intr is shared by data rx queue and fdir rx queue's
interrupt binding. while when configure a fdir queue, it is possible that
a data path Rx queue 0's vector number be recorded in intr_handle->intr_vec
be overwritten by the fdir queue's vector number, this may cause interrupt
Rx mode does not work on the Rx queue 0.
Fixes: 84dc7a95a2d3 ("net/ice: enable flow director engine")
Cc: stable@dpdk.org
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
drivers/net/ice/ice_ethdev.c | 33 ++++++++++++++-------------------
drivers/net/ice/ice_ethdev.h | 6 +++++-
drivers/net/ice/ice_fdir_filter.c | 5 ++++-
3 files changed, 23 insertions(+), 21 deletions(-)
@@ -2619,16 +2619,15 @@ __vsi_queues_bind_intr(struct ice_vsi *vsi, uint16_t msix_vect,
}
void
-ice_vsi_queues_bind_intr(struct ice_vsi *vsi)
+ice_vsi_queues_bind_intr(struct ice_vsi *vsi,
+ bool intr_use_misc,
+ int intr_num_max,
+ int *intr_vec)
{
- struct rte_eth_dev *dev = vsi->adapter->eth_dev;
- struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(dev);
- struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct ice_hw *hw = ICE_VSI_TO_HW(vsi);
uint16_t msix_vect = vsi->msix_intr;
- uint16_t nb_msix = RTE_MIN(vsi->nb_msix, intr_handle->nb_efd);
+ uint16_t nb_msix = RTE_MIN(vsi->nb_msix, intr_num_max);
uint16_t queue_idx = 0;
- int record = 0;
int i;
/* clear Rx/Tx queue interrupt */
@@ -2637,15 +2636,9 @@ ice_vsi_queues_bind_intr(struct ice_vsi *vsi)
ICE_WRITE_REG(hw, QINT_RQCTL(vsi->base_queue + i), 0);
}
- /* PF bind interrupt */
- if (rte_intr_dp_is_en(intr_handle)) {
- queue_idx = 0;
- record = 1;
- }
-
for (i = 0; i < vsi->nb_used_qps; i++) {
if (nb_msix <= 1) {
- if (!rte_intr_allow_others(intr_handle))
+ if (intr_use_misc)
msix_vect = ICE_MISC_VEC_ID;
/* uio mapping all queue to one msix_vect */
@@ -2653,9 +2646,8 @@ ice_vsi_queues_bind_intr(struct ice_vsi *vsi)
vsi->base_queue + i,
vsi->nb_used_qps - i);
- for (; !!record && i < vsi->nb_used_qps; i++)
- intr_handle->intr_vec[queue_idx + i] =
- msix_vect;
+ for (; intr_vec && i < vsi->nb_used_qps; i++)
+ intr_vec[queue_idx + i] = msix_vect;
break;
}
@@ -2663,8 +2655,8 @@ ice_vsi_queues_bind_intr(struct ice_vsi *vsi)
__vsi_queues_bind_intr(vsi, msix_vect,
vsi->base_queue + i, 1);
- if (!!record)
- intr_handle->intr_vec[queue_idx + i] = msix_vect;
+ if (intr_vec)
+ intr_vec[queue_idx + i] = msix_vect;
msix_vect++;
nb_msix--;
@@ -2736,7 +2728,10 @@ ice_rxq_intr_setup(struct rte_eth_dev *dev)
/* Map queues with MSIX interrupt */
vsi->nb_used_qps = dev->data->nb_rx_queues;
- ice_vsi_queues_bind_intr(vsi);
+ ice_vsi_queues_bind_intr(vsi,
+ !rte_intr_allow_others(intr_handle),
+ intr_handle->nb_efd,
+ intr_handle->intr_vec);
/* Enable interrupts for all the queues */
ice_vsi_enable_queues_intr(vsi);
@@ -8,6 +8,7 @@
#include <rte_kvargs.h>
#include <rte_ethdev_driver.h>
+#include <rte_ethdev_pci.h>
#include "base/ice_common.h"
#include "base/ice_adminq_cmd.h"
@@ -463,7 +464,10 @@ int
ice_release_vsi(struct ice_vsi *vsi);
void ice_vsi_enable_queues_intr(struct ice_vsi *vsi);
void ice_vsi_disable_queues_intr(struct ice_vsi *vsi);
-void ice_vsi_queues_bind_intr(struct ice_vsi *vsi);
+void ice_vsi_queues_bind_intr(struct ice_vsi *vsi,
+ bool intr_use_misc,
+ int intr_num_max,
+ int *intr_vec);
static inline int
ice_align_floor(int n)
@@ -433,6 +433,8 @@ ice_fdir_setup(struct ice_pf *pf)
{
struct rte_eth_dev *eth_dev = pf->adapter->eth_dev;
struct ice_hw *hw = ICE_PF_TO_HW(pf);
+ struct rte_pci_device *pci_dev = ICE_DEV_TO_PCI(eth_dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
const struct rte_memzone *mz = NULL;
char z_name[RTE_MEMZONE_NAMESIZE];
struct ice_vsi *vsi;
@@ -501,7 +503,8 @@ ice_fdir_setup(struct ice_pf *pf)
/* Enable FDIR MSIX interrupt */
vsi->nb_used_qps = 1;
- ice_vsi_queues_bind_intr(vsi);
+ ice_vsi_queues_bind_intr(vsi, !rte_intr_allow_others(intr_handle),
+ 1, NULL);
ice_vsi_enable_queues_intr(vsi);
/* reserve memory for the fdir programming packet */