net/bonding: fix slave activation simultaneously
[dpdk.git] / drivers / net / bonding / rte_eth_bond_pmd.c
index d0941c8..02d94b1 100644 (file)
@@ -2653,14 +2653,21 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
        if (!valid_slave)
                return rc;
 
+       /* Synchronize lsc callback parallel calls either by real link event
+        * from the slaves PMDs or by the bonding PMD itself.
+        */
+       rte_spinlock_lock(&internals->lsc_lock);
+
        /* Search for port in active port list */
        active_pos = find_slave_by_id(internals->active_slaves,
                        internals->active_slave_count, port_id);
 
        rte_eth_link_get_nowait(port_id, &link);
        if (link.link_status) {
-               if (active_pos < internals->active_slave_count)
+               if (active_pos < internals->active_slave_count) {
+                       rte_spinlock_unlock(&internals->lsc_lock);
                        return rc;
+               }
 
                /* if no active slave ports then set this port to be primary port */
                if (internals->active_slave_count < 1) {
@@ -2679,8 +2686,10 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
                                internals->primary_port == port_id)
                        bond_ethdev_primary_set(internals, port_id);
        } else {
-               if (active_pos == internals->active_slave_count)
+               if (active_pos == internals->active_slave_count) {
+                       rte_spinlock_unlock(&internals->lsc_lock);
                        return rc;
+               }
 
                /* Remove from active slave list */
                deactivate_slave(bonded_eth_dev, port_id);
@@ -2733,6 +2742,9 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type,
                                                NULL);
                }
        }
+
+       rte_spinlock_unlock(&internals->lsc_lock);
+
        return 0;
 }
 
@@ -2953,6 +2965,7 @@ bond_alloc(struct rte_vdev_device *dev, uint8_t mode)
        eth_dev->data->dev_flags = RTE_ETH_DEV_INTR_LSC;
 
        rte_spinlock_init(&internals->lock);
+       rte_spinlock_init(&internals->lsc_lock);
 
        internals->port_id = eth_dev->data->port_id;
        internals->mode = BONDING_MODE_INVALID;