summaryrefslogtreecommitdiffstats
path: root/dpdk/dpdk-2.2.0_patches/0022-bonding-fix-bond-link-detect-in-non-interrupt-mode.patch
blob: 9cb56d2d499e4dc1e1d7be2b4bf3280f772e98c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
commit 65bcf215aae2e0b9935557e237af054ad0860bad
Author: Nelson Escobar <neescoba@cisco.com>
Date:   Tue Mar 22 13:42:08 2016 -0700

    bonding: fix bond link detect in non-interrupt mode
    
    Stopping then re-starting a bond interface containing slaves that
    used polling for link detection caused the bond to think all slave
    links were down and inactive.
    
    Move the start of the polling for link from slave_add() to
    bond_ethdev_start() and in bond_ethdev_stop() make sure we clear
    the last_link_status of the slaves.
    
    Signed-off-by: Nelson Escobar <neescoba@cisco.com>
    Signed-off-by: John Daley <johndale@cisco.com>

diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c
index fb26d35..f0960c6 100644
--- a/drivers/net/bonding/rte_eth_bond_pmd.c
+++ b/drivers/net/bonding/rte_eth_bond_pmd.c
@@ -1454,18 +1454,11 @@ slave_add(struct bond_dev_private *internals,
 	slave_details->port_id = slave_eth_dev->data->port_id;
 	slave_details->last_link_status = 0;
 
-	/* If slave device doesn't support interrupts then we need to enabled
-	 * polling to monitor link status */
+	/* Mark slave devices that don't support interrupts so we can
+	 * compensate when we start the bond
+	 */
 	if (!(slave_eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)) {
 		slave_details->link_status_poll_enabled = 1;
-
-		if (!internals->link_status_polling_enabled) {
-			internals->link_status_polling_enabled = 1;
-
-			rte_eal_alarm_set(internals->link_status_polling_interval_ms * 1000,
-					bond_ethdev_slave_link_status_change_monitor,
-					(void *)&rte_eth_devices[internals->port_id]);
-		}
 	}
 
 	slave_details->link_status_wait_to_complete = 0;
@@ -1550,6 +1543,18 @@ bond_ethdev_start(struct rte_eth_dev *eth_dev)
 					eth_dev->data->port_id, internals->slaves[i].port_id);
 			return -1;
 		}
+		/* We will need to poll for link status if any slave doesn't
+		 * support interrupts
+		 */
+		if (internals->slaves[i].link_status_poll_enabled)
+			internals->link_status_polling_enabled = 1;
+	}
+	/* start polling if needed */
+	if (internals->link_status_polling_enabled) {
+		rte_eal_alarm_set(
+			internals->link_status_polling_interval_ms * 1000,
+			bond_ethdev_slave_link_status_change_monitor,
+			(void *)&rte_eth_devices[internals->port_id]);
 	}
 
 	if (internals->user_defined_primary_port)
@@ -1622,6 +1627,8 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev)
 
 	internals->active_slave_count = 0;
 	internals->link_status_polling_enabled = 0;
+	for (i = 0; i < internals->slave_count; i++)
+		internals->slaves[i].last_link_status = 0;
 
 	eth_dev->data->dev_link.link_status = 0;
 	eth_dev->data->dev_started = 0;