static int ixgbe_dev_interrupt_action(struct rte_eth_dev *dev);
static void ixgbe_dev_interrupt_handler(void *param);
static void ixgbe_dev_interrupt_delayed_handler(void *param);
-static void ixgbe_dev_setup_link_alarm_handler(void *param);
+static void *ixgbe_dev_setup_link_thread_handler(void *param);
+static void ixgbe_dev_cancel_link_thread(struct rte_eth_dev *dev);
static int ixgbe_add_rar(struct rte_eth_dev *dev,
struct rte_ether_addr *mac_addr,
static int
eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
{
+ struct ixgbe_adapter *ad = eth_dev->data->dev_private;
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct ixgbe_hw *hw =
return 0;
}
+ rte_atomic32_clear(&ad->link_thread_running);
rte_eth_copy_pci_info(eth_dev, pci_dev);
/* Vendor and Device ID need to be set before init of shared code */
{
int diag;
uint32_t tc, tcs;
+ struct ixgbe_adapter *ad = eth_dev->data->dev_private;
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
struct ixgbe_hw *hw =
return 0;
}
+ rte_atomic32_clear(&ad->link_thread_running);
ixgbevf_parse_devargs(eth_dev->data->dev_private,
pci_dev->device.devargs);
PMD_INIT_FUNC_TRACE();
/* Stop the link setup handler before resetting the HW. */
- rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev);
+ ixgbe_dev_cancel_link_thread(dev);
/* disable uio/vfio intr/eventfd mapping */
rte_intr_disable(intr_handle);
PMD_INIT_FUNC_TRACE();
- rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev);
+ ixgbe_dev_cancel_link_thread(dev);
/* disable interrupts */
ixgbe_disable_intr(hw);
}
static void
-ixgbe_dev_setup_link_alarm_handler(void *param)
+ixgbe_dev_cancel_link_thread(struct rte_eth_dev *dev)
+{
+ struct ixgbe_adapter *ad = dev->data->dev_private;
+ void *retval;
+
+ if (rte_atomic32_read(&ad->link_thread_running)) {
+ pthread_cancel(ad->link_thread_tid);
+ pthread_join(ad->link_thread_tid, &retval);
+ rte_atomic32_clear(&ad->link_thread_running);
+ }
+}
+
+static void *
+ixgbe_dev_setup_link_thread_handler(void *param)
{
struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+ struct ixgbe_adapter *ad = dev->data->dev_private;
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ixgbe_interrupt *intr =
IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
ixgbe_setup_link(hw, speed, true);
intr->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
+ rte_atomic32_clear(&ad->link_thread_running);
+ return NULL;
}
/*
int wait_to_complete, int vf)
{
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct ixgbe_adapter *ad = dev->data->dev_private;
struct rte_eth_link link;
ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
struct ixgbe_interrupt *intr =
if (link_up == 0) {
if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {
intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
- rte_eal_alarm_set(10,
- ixgbe_dev_setup_link_alarm_handler, dev);
+ if (rte_atomic32_test_and_set(&ad->link_thread_running)) {
+ if (rte_ctrl_thread_create(&ad->link_thread_tid,
+ "ixgbe-link-handler",
+ NULL,
+ ixgbe_dev_setup_link_thread_handler,
+ dev) < 0) {
+ PMD_DRV_LOG(ERR,
+ "Create link thread failed!");
+ rte_atomic32_clear(&ad->link_thread_running);
+ }
+ } else {
+ PMD_DRV_LOG(ERR,
+ "Other link thread is running now!");
+ }
}
return rte_eth_linkstatus_set(dev, &link);
}
PMD_INIT_FUNC_TRACE();
/* Stop the link setup handler before resetting the HW. */
- rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev);
+ ixgbe_dev_cancel_link_thread(dev);
err = hw->mac.ops.reset_hw(hw);
if (err) {
PMD_INIT_FUNC_TRACE();
- rte_eal_alarm_cancel(ixgbe_dev_setup_link_alarm_handler, dev);
+ ixgbe_dev_cancel_link_thread(dev);
ixgbevf_intr_disable(dev);