Adding support for lsc interrupt from bonded device to link
bonding library with supporting unit tests in the test application.

Signed-off-by: Declan Doherty <declan.doherty at intel.com>
---
 app/test/test_link_bonding.c           | 213 +++++++++++++++++++++++++++------
 lib/librte_pmd_bond/rte_eth_bond_api.c |   4 +
 lib/librte_pmd_bond/rte_eth_bond_pmd.c |   6 +
 3 files changed, 189 insertions(+), 34 deletions(-)

diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c
index db5b180..cce32ed 100644
--- a/app/test/test_link_bonding.c
+++ b/app/test/test_link_bonding.c
@@ -39,6 +39,7 @@
 #include <inttypes.h>
 #include <errno.h>
 #include <sys/queue.h>
+#include <sys/time.h>

 #include <rte_byteorder.h>
 #include <rte_common.h>
@@ -224,10 +225,15 @@ static struct rte_eth_txconf tx_conf_default = {
 };

 static int
-configure_ethdev(uint8_t port_id, uint8_t start)
+configure_ethdev(uint8_t port_id, uint8_t start, uint8_t en_isr)
 {
        int q_id;

+       if (en_isr)
+               default_pmd_conf.intr_conf.lsc = 1;
+       else
+               default_pmd_conf.intr_conf.lsc = 0;
+
        if (rte_eth_dev_configure(port_id, test_params->nb_rx_q,
                        test_params->nb_tx_q, &default_pmd_conf) != 0) {
                goto error;
@@ -312,7 +318,7 @@ test_setup(void)

                        printf("Created virtual ethdev %s\n", pmd_name);

-                       retval = 
configure_ethdev(test_params->slave_port_ids[i], 1);
+                       retval = 
configure_ethdev(test_params->slave_port_ids[i], 1, 0);
                        if (retval != 0) {
                                printf("Failed to configure virtual ethdev 
%s\n", pmd_name);
                                return -1;
@@ -341,7 +347,7 @@ test_create_bonded_device(void)
                TEST_ASSERT(test_params->bonded_port_id >= 0,
                                "Failed to create bonded ethdev %s", 
BONDED_DEV_NAME);

-               
TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0),
+               
TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0, 0),
                                "Failed to configure bonded ethdev %s", 
BONDED_DEV_NAME);
        }

@@ -1078,12 +1084,12 @@ test_set_explicit_bonded_mac(void)


 static int
-initialize_bonded_device_with_slaves(uint8_t bonding_mode,
+initialize_bonded_device_with_slaves(uint8_t bonding_mode, uint8_t bond_en_isr,
                uint8_t number_of_slaves, uint8_t enable_slave)
 {
        /* configure bonded device */
-       TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0),
-                       "Failed to configure bonding port (%d) in mode %d "
+       TEST_ASSERT_SUCCESS(configure_ethdev(test_params->bonded_port_id, 0,
+                       bond_en_isr), "Failed to configure bonding port (%d) in 
mode %d "
                        "with (%d) slaves.", test_params->bonded_port_id, 
bonding_mode,
                        number_of_slaves);

@@ -1116,8 +1122,8 @@ test_adding_slave_after_bonded_device_started(void)
 {
        int i;

-       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 
0) !=
-                       0)
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 
4, 0)
+                       != 0)
                return -1;

        /* Enabled slave devices */
@@ -1141,6 +1147,144 @@ test_adding_slave_after_bonded_device_started(void)
        return remove_slaves_and_stop_bonded_device();
 }

+#define TEST_STATUS_INTERRUPT_SLAVE_COUNT      4
+#define TEST_LSC_WAIT_TIMEOUT_MS       500
+
+int test_lsc_interupt_count;
+
+static pthread_mutex_t mutex;
+static pthread_cond_t cvar;
+
+static void
+test_bonding_lsc_event_callback(uint8_t port_id __rte_unused,
+               enum rte_eth_event_type type  __rte_unused, void *param 
__rte_unused)
+{
+       pthread_mutex_lock(&mutex);
+       test_lsc_interupt_count++;
+
+       pthread_cond_signal(&cvar);
+       pthread_mutex_unlock(&mutex);
+}
+
+static inline int
+lsc_timeout(int wait_us)
+{
+       int retval = 0;
+
+       struct timespec ts;
+       struct timeval tp;
+
+       gettimeofday(&tp, NULL);
+
+       /* Convert from timeval to timespec */
+       ts.tv_sec  = tp.tv_sec;
+       ts.tv_nsec = tp.tv_usec * 1000;
+       ts.tv_nsec += wait_us * 1000;
+
+       pthread_mutex_lock(&mutex);
+       if (test_lsc_interupt_count < 1)
+               retval = pthread_cond_timedwait(&cvar, &mutex, &ts);
+
+       pthread_mutex_unlock(&mutex);
+
+       return retval;
+}
+
+static int
+test_status_interrupt(void)
+{
+       int slave_count;
+       uint8_t slaves[RTE_MAX_ETHPORTS];
+
+       pthread_mutex_init(&mutex, NULL);
+       pthread_cond_init(&cvar, NULL);
+
+       /* initialized bonding device with T slaves */
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 1,
+                       TEST_STATUS_INTERRUPT_SLAVE_COUNT, 1) != 0)
+               return -1;
+
+       test_lsc_interupt_count = 0;
+
+       /* register link status change interrupt callback */
+       rte_eth_dev_callback_register(test_params->bonded_port_id,
+                       RTE_ETH_EVENT_INTR_LSC, test_bonding_lsc_event_callback,
+                       &test_params->bonded_port_id);
+
+       slave_count = 
rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
+                       slaves, RTE_MAX_ETHPORTS);
+
+       TEST_ASSERT_EQUAL(slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT,
+                       "Number of active slaves (%d) is not as expected (%d)",
+                       slave_count, TEST_STATUS_INTERRUPT_SLAVE_COUNT);
+
+       /* Bring all 4 slaves link status to down and test that we have 
received a
+        * lsc interrupts */
+       virtual_ethdev_simulate_link_status_interrupt(
+                       test_params->slave_port_ids[0], 0);
+       virtual_ethdev_simulate_link_status_interrupt(
+                       test_params->slave_port_ids[1], 0);
+       virtual_ethdev_simulate_link_status_interrupt(
+                       test_params->slave_port_ids[2], 0);
+
+       TEST_ASSERT_EQUAL(test_lsc_interupt_count, 0,
+                       "Received a link status change interrupt unexpectedly");
+
+       virtual_ethdev_simulate_link_status_interrupt(
+                       test_params->slave_port_ids[3], 0);
+
+       TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
+                       "timed out waiting for interrupt");
+
+       TEST_ASSERT(test_lsc_interupt_count > 0,
+                       "Did not receive link status change interrupt");
+
+       slave_count = 
rte_eth_bond_active_slaves_get(test_params->bonded_port_id,
+                       slaves, RTE_MAX_ETHPORTS);
+
+       TEST_ASSERT_EQUAL(slave_count, 0,
+                       "Number of active slaves (%d) is not as expected (%d)",
+                       slave_count, 0);
+
+       /* bring one slave port up so link status will change */
+       test_lsc_interupt_count = 0;
+
+       virtual_ethdev_simulate_link_status_interrupt(
+                       test_params->slave_port_ids[0], 1);
+
+       TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) == 0,
+                       "timed out waiting for interrupt");
+
+       /* test that we have received another lsc interrupt */
+       TEST_ASSERT(test_lsc_interupt_count > 0,
+                       "Did not receive link status change interrupt");
+
+       /* Verify that calling the same slave lsc interrupt doesn't cause 
another
+        * lsc interrupt from bonded device */
+       test_lsc_interupt_count = 0;
+
+       virtual_ethdev_simulate_link_status_interrupt(
+                       test_params->slave_port_ids[0], 1);
+
+       TEST_ASSERT(lsc_timeout(TEST_LSC_WAIT_TIMEOUT_MS) != 0,
+                       "received unexpected interrupt");
+
+       TEST_ASSERT_EQUAL(test_lsc_interupt_count, 0,
+                       "Did not receive link status change interrupt");
+
+
+       /* unregister lsc callback before exiting */
+       rte_eth_dev_callback_unregister(test_params->bonded_port_id,
+                               RTE_ETH_EVENT_INTR_LSC, 
test_bonding_lsc_event_callback,
+                               &test_params->bonded_port_id);
+
+       pthread_mutex_destroy(&mutex);
+       pthread_cond_destroy(&cvar);
+
+       /* Clean up and remove slaves from bonded device */
+       return remove_slaves_and_stop_bonded_device();
+}
+
 static int
 generate_test_burst(struct rte_mbuf **pkts_burst, uint16_t burst_size,
                uint8_t vlan, uint8_t ipv4, uint8_t toggle_dst_mac,
@@ -1209,7 +1353,7 @@ test_roundrobin_tx_burst(void)
        struct rte_mbuf *pkt_burst[MAX_PKT_BURST];
        struct rte_eth_stats port_stats;

-       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 2, 1)
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 
2, 1)
                        != 0)
                return -1;

@@ -1279,7 +1423,7 @@ test_roundrobin_rx_burst_on_single_slave(void)
        int i, j, nb_rx, burst_size = 25;

        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 
1) !=
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 
4, 1) !=
                        0)
                return -1;

@@ -1369,7 +1513,7 @@ test_roundrobin_rx_burst_on_multiple_slaves(void)


        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 
1) !=
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 
4, 1) !=
                        0)
                return -1;

@@ -1461,7 +1605,7 @@ test_roundrobin_verify_mac_assignment(void)
        rte_eth_macaddr_get(test_params->slave_port_ids[2], 
&expected_mac_addr_2);

        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 1)
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 
4, 1)
                        != 0)
                return -1;

@@ -1552,7 +1696,7 @@ test_roundrobin_verify_promiscuous_enable_disable(void)
        int i, promiscuous_en;

        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 4, 
1) !=
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0, 
4, 1) !=
                        0)
                return -1;

@@ -1616,7 +1760,7 @@ 
test_roundrobin_verify_slave_link_status_change_behaviour(void)

        /* Initialize bonded device with TEST_RR_LINK_STATUS_SLAVE_COUNT slaves
         * in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN,
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_ROUND_ROBIN, 0,
                        TEST_RR_LINK_STATUS_SLAVE_COUNT, 1) != 0)
                return -1;

@@ -1757,7 +1901,7 @@ test_activebackup_tx_burst(void)
        struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
        struct rte_eth_stats port_stats;

-       retval = 
initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 2, 1);
+       retval = 
initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0, 2, 1);
        if (retval != 0) {
                printf("Failed to initialize_bonded_device_with_slaves.\n");
                return -1;
@@ -1854,7 +1998,7 @@ test_activebackup_rx_burst(void)
        int i, j, nb_rx, burst_size = 17;

        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP,
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0,
                        TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1)
                        != 0)
                return -1;
@@ -1948,7 +2092,7 @@ test_activebackup_verify_promiscuous_enable_disable(void)
        int i, primary_port, promiscuous_en;

        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 4, 
1)
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0, 
4, 1)
                        != 0)
                return -1;

@@ -2018,7 +2162,7 @@ test_activebackup_verify_mac_assignment(void)
        rte_eth_macaddr_get(test_params->slave_port_ids[1], 
&expected_mac_addr_1);

        /* Initialize bonded device with 2 slaves in active backup mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 2, 
1)
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0, 
2, 1)
                        != 0)
                return -1;

@@ -2157,7 +2301,7 @@ 
test_activebackup_verify_slave_link_status_change_failover(void)
        }

        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP,
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0,
                        TEST_ACTIVE_BACKUP_RX_BURST_SLAVE_COUNT, 1)
                        != 0)
                return -1;
@@ -2328,7 +2472,7 @@ test_balance_xmit_policy_configuration(void)
 {
        int retval;

-       retval = 
initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP,
+       retval = 
initialize_bonded_device_with_slaves(BONDING_MODE_ACTIVE_BACKUP, 0,
                        2, 1);
        if (retval != 0) {
                printf("Failed to initialize_bonded_device_with_slaves.\n");
@@ -2408,7 +2552,7 @@ test_balance_l2_tx_burst(void)
        int retval, i;
        struct rte_eth_stats port_stats;

-       retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE,
+       retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0,
                        TEST_BALANCE_L2_TX_BURST_SLAVE_COUNT, 1);
        if (retval != 0) {
                printf("Failed to initialize_bonded_device_with_slaves.\n");
@@ -2506,7 +2650,7 @@ balance_l23_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,

        struct rte_eth_stats port_stats;

-       retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 2, 
1);
+       retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 
2, 1);
        if (retval != 0) {
                printf("Failed to initialize_bonded_device_with_slaves.\n");
                return -1;
@@ -2634,7 +2778,7 @@ balance_l34_tx_burst(uint8_t vlan_enabled, uint8_t ipv4,

        struct rte_eth_stats port_stats;

-       retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 2, 
1);
+       retval = initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 
2, 1);
        if (retval != 0) {
                printf("Failed to initialize_bonded_device_with_slaves.\n");
                return -1;
@@ -2772,7 +2916,7 @@ test_balance_rx_burst(void)
        memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));

        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 3, 1)
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 3, 1)
                        != 0)
                return -1;

@@ -2861,7 +3005,7 @@ test_balance_verify_promiscuous_enable_disable(void)
        int i, promiscuous_en;

        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 4, 1) != 
0)
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 4, 1) 
!= 0)
                return -1;

        rte_eth_promiscuous_enable(test_params->bonded_port_id);
@@ -2915,7 +3059,7 @@ test_balance_verify_mac_assignment(void)
        rte_eth_macaddr_get(test_params->slave_port_ids[1], 
&expected_mac_addr_1);

        /* Initialize bonded device with 2 slaves in active backup mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 2, 1) != 
0)
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 2, 1) 
!= 0)
                return -1;

        /* Verify that bonded MACs is that of first slave and that the other 
slave
@@ -3045,7 +3189,7 @@ 
test_balance_verify_slave_link_status_change_behaviour(void)
        memset(pkt_burst, 0, sizeof(pkt_burst));

        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE,
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0,
                        TEST_BALANCE_LINK_STATUS_SLAVE_COUNT, 1) != 0)
                return -1;

@@ -3237,7 +3381,7 @@ test_broadcast_tx_burst(void)

        struct rte_eth_stats port_stats;

-       retval = initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 
2, 1);
+       retval = initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 
0, 2, 1);
        if (retval != 0) {
                printf("Failed to initialize_bonded_device_with_slaves.\n");
                return -1;
@@ -3327,7 +3471,7 @@ test_broadcast_rx_burst(void)
        memset(gen_pkt_burst, 0, sizeof(gen_pkt_burst));

        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 3, 1) 
!= 0)
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0, 3, 
1) != 0)
                return -1;


@@ -3419,7 +3563,7 @@ test_broadcast_verify_promiscuous_enable_disable(void)
        int i, promiscuous_en;

        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 4, 1) != 
0)
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_BALANCE, 0, 4, 1) 
!= 0)
                return -1;

        rte_eth_promiscuous_enable(test_params->bonded_port_id);
@@ -3475,7 +3619,7 @@ test_broadcast_verify_mac_assignment(void)
        rte_eth_macaddr_get(test_params->slave_port_ids[2], 
&expected_mac_addr_1);

        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 4, 1) 
!= 0)
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0, 4, 
1) != 0)
                return -1;

        /* Verify that all MACs are the same as first slave added to bonded
@@ -3575,7 +3719,7 @@ 
test_broadcast_verify_slave_link_status_change_behaviour(void)
        memset(pkt_burst, 0, sizeof(pkt_burst));

        /* Initialize bonded device with 4 slaves in round robin mode */
-       if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST,
+       if (initialize_bonded_device_with_slaves(BONDING_MODE_BROADCAST, 0,
                        BROADCAST_LINK_STATUS_NUM_OF_SLAVES, 1) != 0)
                return -1;

@@ -3711,7 +3855,7 @@ test_reconfigure_bonded_device(void)
        test_params->nb_rx_q = 4;
        test_params->nb_tx_q = 4;

-       if (configure_ethdev(test_params->bonded_port_id, 0)  != 0) {
+       if (configure_ethdev(test_params->bonded_port_id, 0, 0)  != 0) {
                printf("failed to reconfigure bonded device");
                return -1;
        }
@@ -3720,7 +3864,7 @@ test_reconfigure_bonded_device(void)
        test_params->nb_rx_q = 2;
        test_params->nb_tx_q = 2;

-       if (configure_ethdev(test_params->bonded_port_id, 0)  != 0) {
+       if (configure_ethdev(test_params->bonded_port_id, 0, 0)  != 0) {
                printf("failed to reconfigure bonded device with less rx/tx 
queues");
                return -1;
        }
@@ -3768,6 +3912,7 @@ static struct unit_test_suite link_bonding_test_suite  = {
                TEST_CASE(test_set_bonding_mode),
                TEST_CASE(test_set_primary_slave),
                TEST_CASE(test_set_explicit_bonded_mac),
+               TEST_CASE(test_status_interrupt),
                TEST_CASE(test_adding_slave_after_bonded_device_started),
                TEST_CASE(test_roundrobin_tx_burst),
                TEST_CASE(test_roundrobin_rx_burst_on_single_slave),
diff --git a/lib/librte_pmd_bond/rte_eth_bond_api.c 
b/lib/librte_pmd_bond/rte_eth_bond_api.c
index 75f5694..dd33119 100644
--- a/lib/librte_pmd_bond/rte_eth_bond_api.c
+++ b/lib/librte_pmd_bond/rte_eth_bond_api.c
@@ -177,6 +177,8 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t 
socket_id)
        pci_drv->id_table->vendor_id = PCI_ANY_ID;
        pci_drv->id_table->subsystem_vendor_id = PCI_ANY_ID;

+       pci_drv->drv_flags = RTE_PCI_DRV_INTR_LSC;
+
        internals = rte_zmalloc_socket(name, sizeof(*internals), 0, socket_id);
        if (internals == NULL) {
                RTE_LOG(ERR, PMD, "Unable to malloc internals on socket\n");
@@ -200,6 +202,8 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t 
socket_id)
        eth_dev->data->nb_rx_queues = (uint16_t)1;
        eth_dev->data->nb_tx_queues = (uint16_t)1;

+       TAILQ_INIT(&(eth_dev->callbacks));
+
        eth_dev->data->dev_link.link_status = 0;

        eth_dev->data->mac_addrs = rte_zmalloc_socket(name, ETHER_ADDR_LEN, 0,
diff --git a/lib/librte_pmd_bond/rte_eth_bond_pmd.c 
b/lib/librte_pmd_bond/rte_eth_bond_pmd.c
index 08d3b5f..aca2dcf 100644
--- a/lib/librte_pmd_bond/rte_eth_bond_pmd.c
+++ b/lib/librte_pmd_bond/rte_eth_bond_pmd.c
@@ -918,6 +918,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum 
rte_eth_event_type type,
        struct rte_eth_link link;

        int i, valid_slave = 0, active_pos = -1;
+       uint8_t lsc_flag = 0;

        if (type != RTE_ETH_EVENT_INTR_LSC || param == NULL)
                return;
@@ -963,6 +964,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum 
rte_eth_event_type type,
                        /* If first active slave, then change link status */
                        bonded_eth_dev->data->dev_link.link_status = 1;
                        internals->current_primary_port = port_id;
+                       lsc_flag = 1;

                        /* Inherit eth dev link properties from first active 
slave */
                        link_properties_set(bonded_eth_dev,
@@ -987,6 +989,7 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum 
rte_eth_event_type type,
                /* No active slaves, change link status to down and reset other
                 * link properties */
                if (internals->active_slave_count < 1) {
+                       lsc_flag = 1;
                        bonded_eth_dev->data->dev_link.link_status = 0;

                        link_properties_reset(bonded_eth_dev);
@@ -1002,6 +1005,9 @@ bond_ethdev_lsc_event_callback(uint8_t port_id, enum 
rte_eth_event_type type,
                                internals->current_primary_port = 
internals->primary_port;
                }
        }
+
+       if (lsc_flag)
+               _rte_eth_dev_callback_process(bonded_eth_dev, 
RTE_ETH_EVENT_INTR_LSC);
 }

 struct eth_dev_ops default_dev_ops = {
-- 
1.7.12.2

Reply via email to