@@ -104,3 +104,26 @@ Add a rule to enable ipv4-udp RSS:
.. code-block:: console
testpmd> flow create 0 ingress pattern end actions rss types ipv4-udp end / end
+
+Secondary Process Support
+-------------------------
+
+The following ethdev API's are currently not supported for use in secondary processes:
+
+* ``rte_eth_dev_set_link_up``
+* ``rte_eth_dev_set_link_down``
+* ``rte_eth_link_get``
+* ``rte_eth_dev_start``
+* ``rte_eth_dev_stop``
+* ``rte_eth_dev_fw_version_get``
+* ``rte_eth_dev_rx_intr_enable``
+* ``rte_eth_dev_rx_intr_disable``
+* ``rte_eth_dev_led_on``
+* ``rte_eth_dev_led_off``
+* ``rte_eth_dev_default_mac_addr_set``
+* ``rte_eth_dev_mac_addr_add``
+* ``rte_eth_dev_mac_addr_remove``
+* ``rte_eth_dev_set_mc_addr_list``
+* ``rte_eth_dev_flow_ctrl_set``
+* ``rte_eth_timesync_read_rx_timestamp``
+* ``rte_eth_timesync_read_tx_timestamp``
@@ -12,6 +12,7 @@
#include <ethdev_pci.h>
#include <rte_malloc.h>
#include <rte_alarm.h>
+#include <rte_errno.h>
#include "igc_logs.h"
#include "igc_txrx.h"
@@ -393,6 +394,14 @@ eth_igc_set_link_up(struct rte_eth_dev *dev)
{
struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (hw->phy.media_type == igc_media_type_copper)
igc_power_up_phy(hw);
else
@@ -405,6 +414,14 @@ eth_igc_set_link_down(struct rte_eth_dev *dev)
{
struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (hw->phy.media_type == igc_media_type_copper)
igc_power_down_phy(hw);
else
@@ -478,6 +495,14 @@ eth_igc_link_update(struct rte_eth_dev *dev, int wait_to_complete)
struct rte_eth_link link;
int link_check, count;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
link_check = 0;
hw->mac.get_link_status = 1;
@@ -655,6 +680,14 @@ eth_igc_stop(struct rte_eth_dev *dev)
struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
struct rte_eth_link link;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
dev->data->dev_started = 0;
adapter->stopped = 1;
@@ -966,6 +999,14 @@ eth_igc_start(struct rte_eth_dev *dev)
PMD_INIT_FUNC_TRACE();
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
/* disable all MSI-X interrupts */
IGC_WRITE_REG(hw, IGC_EIMC, 0x1f);
IGC_WRITE_FLUSH(hw);
@@ -1549,6 +1590,14 @@ eth_igc_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
struct igc_fw_version fw;
int ret;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
igc_get_fw_version(hw, &fw);
/* if option rom is valid, display its version too */
@@ -1639,6 +1688,14 @@ eth_igc_led_on(struct rte_eth_dev *dev)
{
struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
return igc_led_on(hw) == IGC_SUCCESS ? 0 : -ENOTSUP;
}
@@ -1647,6 +1704,14 @@ eth_igc_led_off(struct rte_eth_dev *dev)
{
struct igc_hw *hw = IGC_DEV_PRIVATE_HW(dev);
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
return igc_led_off(hw) == IGC_SUCCESS ? 0 : -ENOTSUP;
}
@@ -2190,6 +2255,10 @@ eth_igc_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
uint32_t vec = IGC_MISC_VEC_ID;
+ /* device interrupts are only subscribed to in primary processes */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (rte_intr_allow_others(intr_handle))
vec = IGC_RX_VEC_START;
@@ -2209,6 +2278,10 @@ eth_igc_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
uint32_t vec = IGC_MISC_VEC_ID;
+ /* device interrupts are only subscribed to in primary processes */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (rte_intr_allow_others(intr_handle))
vec = IGC_RX_VEC_START;
@@ -2272,6 +2345,14 @@ eth_igc_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
uint32_t rctl;
int err;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
if (fc_conf->autoneg != hw->mac.autoneg)
return -ENOTSUP;
@@ -2773,6 +2854,14 @@ eth_igc_timesync_read_rx_timestamp(__rte_unused struct rte_eth_dev *dev,
struct igc_rx_queue *rxq;
uint64_t rx_timestamp;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
/* Get current link speed. */
eth_igc_link_update(dev, 1);
rte_eth_linkstatus_get(dev, &link);
@@ -2809,6 +2898,14 @@ eth_igc_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
uint64_t tx_timestamp;
int adjust = 0;
+ /*
+ * This function calls into the base driver, which in turn will use
+ * function pointers, which are not guaranteed to be valid in secondary
+ * processes, so avoid using this function in secondary processes.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -E_RTE_SECONDARY;
+
val = IGC_READ_REG(hw, IGC_TSYNCTXCTL);
if (!(val & IGC_TSYNCTXCTL_VALID))
return -EINVAL;