ixgbe: fix VF start with PF stopped
authorCunming Liang <cunming.liang@intel.com>
Wed, 4 Nov 2015 08:45:35 +0000 (16:45 +0800)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Wed, 4 Nov 2015 14:27:42 +0000 (15:27 +0100)
When ixgbe runs as a PF, mbox interrupt is prerequisite to make VF
start normally.
And PF sometimes won't 'dev_start', so the mbox interrupt register
during 'dev_init' is required.
The patch rolls back the interrupt register for mbox,lsc to the 'dev_init'.
As UIO doesn't support multiple vector, mbox has to occupy the only one.
It adds condition check on 'dev_start', rxq interrupt is not allowed
when PF running in IOV mode via UIO.

Signed-off-by: Cunming Liang <cunming.liang@intel.com>
doc/guides/rel_notes/release_2_2.rst
drivers/net/ixgbe/ixgbe_ethdev.c

index 4ad9287..80ccd85 100644 (file)
@@ -128,6 +128,10 @@ Drivers
 
   Fixed issue where a burst size less than 32 didn't receive anything.
 
 
   Fixed issue where a burst size less than 32 didn't receive anything.
 
+* **ixgbe: Fixed VF start with PF stopped.**
+
+  VF needs the PF interrupt support initialized even if not started.
+
 * **i40e: Fixed base driver allocation when not using first numa node.**
 
   Fixed i40e issue that occurred when a DPDK application didn't initialize
 * **i40e: Fixed base driver allocation when not using first numa node.**
 
   Fixed i40e issue that occurred when a DPDK application didn't initialize
@@ -162,6 +166,7 @@ Drivers
   hardware transactional memory support, thread scaling did not work,
   due to the global ring that is shared by all cores.
 
   hardware transactional memory support, thread scaling did not work,
   due to the global ring that is shared by all cores.
 
+
 Libraries
 ~~~~~~~~~
 
 Libraries
 ~~~~~~~~~
 
index f1a738c..c322168 100644 (file)
@@ -1126,6 +1126,13 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
                        eth_dev->data->port_id, pci_dev->id.vendor_id,
                        pci_dev->id.device_id);
 
                        eth_dev->data->port_id, pci_dev->id.vendor_id,
                        pci_dev->id.device_id);
 
+       rte_intr_callback_register(&pci_dev->intr_handle,
+                                  ixgbe_dev_interrupt_handler,
+                                  (void *)eth_dev);
+
+       /* enable uio/vfio intr/eventfd mapping */
+       rte_intr_enable(&pci_dev->intr_handle);
+
        /* enable support intr */
        ixgbe_enable_intr(eth_dev);
 
        /* enable support intr */
        ixgbe_enable_intr(eth_dev);
 
@@ -1975,7 +1982,9 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        ixgbe_pf_host_configure(dev);
 
        /* check and configure queue intr-vector mapping */
        ixgbe_pf_host_configure(dev);
 
        /* check and configure queue intr-vector mapping */
-       if (dev->data->dev_conf.intr_conf.rxq != 0) {
+       if ((rte_intr_cap_multiple(intr_handle) ||
+            !RTE_ETH_DEV_SRIOV(dev).active) &&
+           dev->data->dev_conf.intr_conf.rxq != 0) {
                intr_vector = dev->data->nb_rx_queues;
                if (rte_intr_efd_enable(intr_handle, intr_vector))
                        return -1;
                intr_vector = dev->data->nb_rx_queues;
                if (rte_intr_efd_enable(intr_handle, intr_vector))
                        return -1;
@@ -1984,8 +1993,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) {
                intr_handle->intr_vec =
                        rte_zmalloc("intr_vec",
        if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) {
                intr_handle->intr_vec =
                        rte_zmalloc("intr_vec",
-                                   dev->data->nb_rx_queues * sizeof(int),
-                                   0);
+                                   dev->data->nb_rx_queues * sizeof(int), 0);
                if (intr_handle->intr_vec == NULL) {
                        PMD_INIT_LOG(ERR, "Failed to allocate %d rx_queues"
                                     " intr_vec\n", dev->data->nb_rx_queues);
                if (intr_handle->intr_vec == NULL) {
                        PMD_INIT_LOG(ERR, "Failed to allocate %d rx_queues"
                                     " intr_vec\n", dev->data->nb_rx_queues);
@@ -2072,20 +2080,22 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
 
 skip_link_setup:
 
 
 skip_link_setup:
 
-       /* check if lsc interrupt is enabled */
-       if (dev->data->dev_conf.intr_conf.lsc != 0) {
-               if (rte_intr_allow_others(intr_handle)) {
-                       rte_intr_callback_register(intr_handle,
-                                                  ixgbe_dev_interrupt_handler,
-                                                  (void *)dev);
+       if (rte_intr_allow_others(intr_handle)) {
+               /* check if lsc interrupt is enabled */
+               if (dev->data->dev_conf.intr_conf.lsc != 0)
                        ixgbe_dev_lsc_interrupt_setup(dev);
                        ixgbe_dev_lsc_interrupt_setup(dev);
-               } else
+       } else {
+               rte_intr_callback_unregister(intr_handle,
+                                            ixgbe_dev_interrupt_handler,
+                                            (void *)dev);
+               if (dev->data->dev_conf.intr_conf.lsc != 0)
                        PMD_INIT_LOG(INFO, "lsc won't enable because of"
                                     " no intr multiplex\n");
        }
 
        /* check if rxq interrupt is enabled */
                        PMD_INIT_LOG(INFO, "lsc won't enable because of"
                                     " no intr multiplex\n");
        }
 
        /* check if rxq interrupt is enabled */
-       if (dev->data->dev_conf.intr_conf.rxq != 0)
+       if (dev->data->dev_conf.intr_conf.rxq != 0 &&
+           rte_intr_dp_is_en(intr_handle))
                ixgbe_dev_rxq_interrupt_setup(dev);
 
        /* enable uio/vfio intr/eventfd mapping */
                ixgbe_dev_rxq_interrupt_setup(dev);
 
        /* enable uio/vfio intr/eventfd mapping */
@@ -2197,6 +2207,12 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
        memset(filter_info->fivetuple_mask, 0,
                sizeof(uint32_t) * IXGBE_5TUPLE_ARRAY_SIZE);
 
        memset(filter_info->fivetuple_mask, 0,
                sizeof(uint32_t) * IXGBE_5TUPLE_ARRAY_SIZE);
 
+       if (!rte_intr_allow_others(intr_handle))
+               /* resume to the default handler */
+               rte_intr_callback_register(intr_handle,
+                                          ixgbe_dev_interrupt_handler,
+                                          (void *)dev);
+
        /* Clean datapath event and queue/vec mapping */
        rte_intr_efd_disable(intr_handle);
        if (intr_handle->intr_vec != NULL) {
        /* Clean datapath event and queue/vec mapping */
        rte_intr_efd_disable(intr_handle);
        if (intr_handle->intr_vec != NULL) {