67 lines
2.6 KiB
Diff
67 lines
2.6 KiB
Diff
|
From 6033eeec2b029d99d4c0e46065f311fbbb2a1f1b Mon Sep 17 00:00:00 2001
|
|||
|
From: Lijian Zhang <Lijian.Zhang@arm.com>
|
|||
|
Date: Wed, 18 Mar 2020 17:21:08 +0800
|
|||
|
Subject: [PATCH] ixgbe: fix false link down timing issue
|
|||
|
MIME-Version: 1.0
|
|||
|
Content-Type: text/plain; charset=UTF-8
|
|||
|
Content-Transfer-Encoding: 8bit
|
|||
|
|
|||
|
This issue is observed with X520-2 NICs on FD.io Taishan server. After
|
|||
|
VPP booting up and bringing up the interfaces with command ‘set
|
|||
|
interface state <interface> up’, it still shows link down status from
|
|||
|
the command ‘show hardware-interfaces’. However, the hardware link
|
|||
|
status is actually up. dpdk_process() cannot get the hardware link
|
|||
|
status correctly via rte_eth_link_get_nowait().
|
|||
|
|
|||
|
In ixgbe_dev_link_update_share(), if the media type is fiber and the
|
|||
|
link is down, a flag (IXGBE_FLAG_NEED_LINK_CONFIG) is set. A callback to
|
|||
|
ixgbe_dev_setup_link_alarm_handler() is scheduled trying to set up the
|
|||
|
link and clear the flag afterwards.
|
|||
|
|
|||
|
If the device is started or stopped before the flag is cleared, the
|
|||
|
scheduled callback is canceled. This causes the flag to remain set and
|
|||
|
subsequent calls to ixgbe_dev_link_update_share() return without trying
|
|||
|
to retrieve the link state because the flag is set.
|
|||
|
|
|||
|
When the callback is canceled by either interface start or stop
|
|||
|
operation, in ixgbe_dev_cancel_link_thread(), after cancelling the
|
|||
|
callback/thread, unset the flag on the device to avoid this condition.
|
|||
|
|
|||
|
Signed-off-by: Lijian Zhang <Lijian.Zhang@arm.com>
|
|||
|
---
|
|||
|
drivers/net/ixgbe/ixgbe_ethdev.c | 5 ++++-
|
|||
|
1 file changed, 4 insertions(+), 1 deletion(-)
|
|||
|
|
|||
|
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
|
|||
|
index 23b3f5b0c..aa882cb8b 100644
|
|||
|
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
|
|||
|
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
|
|||
|
@@ -4147,11 +4147,14 @@ static void
|
|||
|
ixgbe_dev_cancel_link_thread(struct rte_eth_dev *dev)
|
|||
|
{
|
|||
|
struct ixgbe_adapter *ad = dev->data->dev_private;
|
|||
|
+ struct ixgbe_interrupt *intr =
|
|||
|
+ IXGBE_DEV_PRIVATE_TO_INTR(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);
|
|||
|
+ intr->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
|
|||
|
rte_atomic32_clear(&ad->link_thread_running);
|
|||
|
}
|
|||
|
}
|
|||
|
@@ -4262,8 +4265,8 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
|
|||
|
|
|||
|
if (link_up == 0) {
|
|||
|
if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {
|
|||
|
- intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
|
|||
|
if (rte_atomic32_test_and_set(&ad->link_thread_running)) {
|
|||
|
+ intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
|
|||
|
if (rte_ctrl_thread_create(&ad->link_thread_tid,
|
|||
|
"ixgbe-link-handler",
|
|||
|
NULL,
|
|||
|
--
|
|||
|
2.17.1
|
|||
|
|