blob: 6e0627b0338a2b2d64358c383db05e3186348534 [file] [log] [blame]
Lijian.Zhang1690dcb2020-03-19 10:22:52 +08001From 6033eeec2b029d99d4c0e46065f311fbbb2a1f1b Mon Sep 17 00:00:00 2001
2From: Lijian Zhang <Lijian.Zhang@arm.com>
3Date: Wed, 18 Mar 2020 17:21:08 +0800
4Subject: [PATCH] ixgbe: fix false link down timing issue
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9This issue is observed with X520-2 NICs on FD.io Taishan server. After
10VPP booting up and bringing up the interfaces with command set
11interface state <interface> up’, it still shows link down status from
12the command show hardware-interfaces’. However, the hardware link
13status is actually up. dpdk_process() cannot get the hardware link
14status correctly via rte_eth_link_get_nowait().
15
16In ixgbe_dev_link_update_share(), if the media type is fiber and the
17link is down, a flag (IXGBE_FLAG_NEED_LINK_CONFIG) is set. A callback to
18ixgbe_dev_setup_link_alarm_handler() is scheduled trying to set up the
19link and clear the flag afterwards.
20
21If the device is started or stopped before the flag is cleared, the
22scheduled callback is canceled. This causes the flag to remain set and
23subsequent calls to ixgbe_dev_link_update_share() return without trying
24to retrieve the link state because the flag is set.
25
26When the callback is canceled by either interface start or stop
27operation, in ixgbe_dev_cancel_link_thread(), after cancelling the
28callback/thread, unset the flag on the device to avoid this condition.
29
30Signed-off-by: Lijian Zhang <Lijian.Zhang@arm.com>
31---
32 drivers/net/ixgbe/ixgbe_ethdev.c | 5 ++++-
33 1 file changed, 4 insertions(+), 1 deletion(-)
34
35diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
36index 23b3f5b0c..aa882cb8b 100644
37--- a/drivers/net/ixgbe/ixgbe_ethdev.c
38+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
39@@ -4147,11 +4147,14 @@ static void
40 ixgbe_dev_cancel_link_thread(struct rte_eth_dev *dev)
41 {
42 struct ixgbe_adapter *ad = dev->data->dev_private;
43+ struct ixgbe_interrupt *intr =
44+ IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
45 void *retval;
46
47 if (rte_atomic32_read(&ad->link_thread_running)) {
48 pthread_cancel(ad->link_thread_tid);
49 pthread_join(ad->link_thread_tid, &retval);
50+ intr->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
51 rte_atomic32_clear(&ad->link_thread_running);
52 }
53 }
54@@ -4262,8 +4265,8 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
55
56 if (link_up == 0) {
57 if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {
58- intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
59 if (rte_atomic32_test_and_set(&ad->link_thread_running)) {
60+ intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
61 if (rte_ctrl_thread_create(&ad->link_thread_tid,
62 "ixgbe-link-handler",
63 NULL,
64--
652.17.1
66