Reviewed-by: Robert Sanford <rsanford at akamai.com>
>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 | 216 >+++++++++++++++++++++++++++----- > lib/librte_pmd_bond/rte_eth_bond_api.c | 4 + > lib/librte_pmd_bond/rte_eth_bond_pmd.c | 6 + > 3 files changed, 192 insertions(+), 34 deletions(-) > >diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c >index 5c1303e..02823b6 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,147 @@ >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); >+ >+ if (test_lsc_interupt_count < 1) >+ return retval; >+ >+ return 0; >+} >+ >+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 +1356,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 +1426,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 +1516,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 +1608,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 +1699,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 +1763,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 +1904,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 +2001,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 +2095,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 +2165,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 +2304,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 +2475,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 +2555,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 +2653,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 +2781,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 +2919,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 +3008,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 +3062,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 +3192,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 +3384,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 +3474,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 +3566,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 +3622,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 +3722,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 +3858,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 +3867,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 +3915,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 d72d6ed..cd3eecf 100644 >--- a/lib/librte_pmd_bond/rte_eth_bond_pmd.c >+++ b/lib/librte_pmd_bond/rte_eth_bond_pmd.c >@@ -921,6 +921,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; >@@ -966,6 +967,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, >@@ -990,6 +992,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); >@@ -1005,6 +1008,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.0.7 >