X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbonding%2Frte_eth_bond_pmd.c;h=1c404b2edd6eec57586509db9bbf37172e52c660;hb=952ebacce4f2;hp=627d8de63efb1c4b2daaa1dd59438d3fa1d68baa;hpb=4633c3b2ebf2fbbb8b6d4f7e411133a941106044;p=dpdk.git diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c index 627d8de63e..1c404b2edd 100644 --- a/drivers/net/bonding/rte_eth_bond_pmd.c +++ b/drivers/net/bonding/rte_eth_bond_pmd.c @@ -21,8 +21,8 @@ #include #include "rte_eth_bond.h" -#include "rte_eth_bond_private.h" -#include "rte_eth_bond_8023ad_private.h" +#include "eth_bond_private.h" +#include "eth_bond_8023ad_private.h" #define REORDER_PERIOD_MS 10 #define DEFAULT_POLLING_INTERVAL_10_MS (10) @@ -69,7 +69,7 @@ bond_ethdev_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) struct bond_rx_queue *bd_rx_q = (struct bond_rx_queue *)queue; internals = bd_rx_q->dev_private; slave_count = internals->active_slave_count; - active_slave = internals->active_slave; + active_slave = bd_rx_q->active_slave; for (i = 0; i < slave_count && nb_pkts; i++) { uint16_t num_rx_slave; @@ -86,8 +86,8 @@ bond_ethdev_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) active_slave = 0; } - if (++internals->active_slave >= slave_count) - internals->active_slave = 0; + if (++bd_rx_q->active_slave >= slave_count) + bd_rx_q->active_slave = 0; return num_rx_total; } @@ -303,9 +303,9 @@ rx_burst_8023ad(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts, memcpy(slaves, internals->active_slaves, sizeof(internals->active_slaves[0]) * slave_count); - idx = internals->active_slave; + idx = bd_rx_q->active_slave; if (idx >= slave_count) { - internals->active_slave = 0; + bd_rx_q->active_slave = 0; idx = 0; } for (i = 0; i < slave_count && num_rx_total < nb_pkts; i++) { @@ -367,8 +367,8 @@ rx_burst_8023ad(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts, idx = 0; } - if (++internals->active_slave >= slave_count) - internals->active_slave = 0; + if (++bd_rx_q->active_slave >= slave_count) + bd_rx_q->active_slave = 0; return num_rx_total; } @@ -489,9 +489,9 @@ update_client_stats(uint32_t addr, uint16_t port, uint32_t *TXorRXindicator) #endif static void -mode6_debug(const char __attribute__((unused)) *info, +mode6_debug(const char __rte_unused *info, struct rte_ether_hdr *eth_h, uint16_t port, - uint32_t __attribute__((unused)) *burstnumber) + uint32_t __rte_unused *burstnumber) { struct rte_ipv4_hdr *ipv4_h; #ifdef RTE_LIBRTE_BOND_DEBUG_ALB @@ -534,8 +534,8 @@ mode6_debug(const char __attribute__((unused)) *info, static uint16_t bond_ethdev_rx_burst_alb(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) { - struct bond_tx_queue *bd_tx_q = (struct bond_tx_queue *)queue; - struct bond_dev_private *internals = bd_tx_q->dev_private; + struct bond_rx_queue *bd_rx_q = (struct bond_rx_queue *)queue; + struct bond_dev_private *internals = bd_rx_q->dev_private; struct rte_ether_hdr *eth_h; uint16_t ether_type, offset; uint16_t nb_recv_pkts; @@ -846,8 +846,14 @@ bandwidth_left(uint16_t port_id, uint64_t load, uint8_t update_idx, struct bwg_slave *bwg_slave) { struct rte_eth_link link_status; + int ret; - rte_eth_link_get_nowait(port_id, &link_status); + ret = rte_eth_link_get_nowait(port_id, &link_status); + if (ret < 0) { + RTE_BOND_LOG(ERR, "Slave (port %u) link get failed: %s", + port_id, rte_strerror(-ret)); + return; + } uint64_t link_bwg = link_status.link_speed * 1000000ULL / 8; if (link_bwg == 0) return; @@ -1496,6 +1502,7 @@ int mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev) { struct bond_dev_private *internals = bonded_eth_dev->data->dev_private; + bool set; int i; /* Update slave devices MAC addresses */ @@ -1523,15 +1530,16 @@ mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev) case BONDING_MODE_TLB: case BONDING_MODE_ALB: default: + set = true; for (i = 0; i < internals->slave_count; i++) { if (internals->slaves[i].port_id == internals->current_primary_port) { if (rte_eth_dev_default_mac_addr_set( - internals->primary_port, + internals->current_primary_port, bonded_eth_dev->data->mac_addrs)) { RTE_BOND_LOG(ERR, "Failed to update port Id %d MAC address", internals->current_primary_port); - return -1; + set = false; } } else { if (rte_eth_dev_default_mac_addr_set( @@ -1539,10 +1547,11 @@ mac_address_slaves_update(struct rte_eth_dev *bonded_eth_dev) &internals->slaves[i].persisted_mac_addr)) { RTE_BOND_LOG(ERR, "Failed to update port Id %d MAC address", internals->slaves[i].port_id); - return -1; } } } + if (!set) + return -1; } return 0; @@ -1870,7 +1879,7 @@ slave_remove(struct bond_dev_private *internals, internals->slave_count--; /* force reconfiguration of slave interfaces */ - _rte_eth_dev_reset(slave_eth_dev); + rte_eth_dev_internal_reset(slave_eth_dev); } static void @@ -2086,7 +2095,7 @@ bond_ethdev_stop(struct rte_eth_dev *eth_dev) } } -void +int bond_ethdev_close(struct rte_eth_dev *dev) { struct bond_dev_private *internals = dev->data->dev_private; @@ -2094,6 +2103,9 @@ bond_ethdev_close(struct rte_eth_dev *dev) int skipped = 0; struct rte_flow_error ferror; + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; + RTE_BOND_LOG(INFO, "Closing bonded device %s", dev->device->name); while (internals->slave_count != skipped) { uint16_t port_id = internals->slaves[skipped].port_id; @@ -2110,6 +2122,19 @@ bond_ethdev_close(struct rte_eth_dev *dev) bond_flow_ops.flush(dev, &ferror); bond_ethdev_free_queues(dev); rte_bitmap_reset(internals->vlan_filter_bmp); + rte_bitmap_free(internals->vlan_filter_bmp); + rte_free(internals->vlan_filter_bmpmem); + + /* Try to release mempool used in mode6. If the bond + * device is not mode6, free the NULL is not problem. + */ + rte_mempool_free(internals->mode6.mempool); + + dev->dev_ops = NULL; + dev->rx_pkt_burst = NULL; + dev->tx_pkt_burst = NULL; + + return 0; } /* forward declaration */ @@ -2363,7 +2388,9 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete) struct bond_dev_private *bond_ctx; struct rte_eth_link slave_link; + bool one_link_update_succeeded; uint32_t idx; + int ret; bond_ctx = ethdev->data->dev_private; @@ -2396,7 +2423,17 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete) * greater than this are attempted */ for (idx = 0; idx < bond_ctx->active_slave_count; idx++) { - link_update(bond_ctx->active_slaves[idx], &slave_link); + ret = link_update(bond_ctx->active_slaves[idx], + &slave_link); + if (ret < 0) { + ethdev->data->dev_link.link_speed = + ETH_SPEED_NUM_NONE; + RTE_BOND_LOG(ERR, + "Slave (port %u) link get failed: %s", + bond_ctx->active_slaves[idx], + rte_strerror(-ret)); + return 0; + } if (slave_link.link_speed < ethdev->data->dev_link.link_speed) @@ -2406,7 +2443,13 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete) break; case BONDING_MODE_ACTIVE_BACKUP: /* Current primary slave */ - link_update(bond_ctx->current_primary_port, &slave_link); + ret = link_update(bond_ctx->current_primary_port, &slave_link); + if (ret < 0) { + RTE_BOND_LOG(ERR, "Slave (port %u) link get failed: %s", + bond_ctx->current_primary_port, + rte_strerror(-ret)); + return 0; + } ethdev->data->dev_link.link_speed = slave_link.link_speed; break; @@ -2415,7 +2458,8 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete) bond_ctx->mode4.slave_link.link_autoneg; ethdev->data->dev_link.link_duplex = bond_ctx->mode4.slave_link.link_duplex; - /* fall through to update link speed */ + /* fall through */ + /* to update link speed */ case BONDING_MODE_ROUND_ROBIN: case BONDING_MODE_BALANCE: case BONDING_MODE_TLB: @@ -2426,13 +2470,28 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete) * of all the slaves */ ethdev->data->dev_link.link_speed = ETH_SPEED_NUM_NONE; + one_link_update_succeeded = false; for (idx = 0; idx < bond_ctx->active_slave_count; idx++) { - link_update(bond_ctx->active_slaves[idx], &slave_link); + ret = link_update(bond_ctx->active_slaves[idx], + &slave_link); + if (ret < 0) { + RTE_BOND_LOG(ERR, + "Slave (port %u) link get failed: %s", + bond_ctx->active_slaves[idx], + rte_strerror(-ret)); + continue; + } + one_link_update_succeeded = true; ethdev->data->dev_link.link_speed += slave_link.link_speed; } + + if (!one_link_update_succeeded) { + RTE_BOND_LOG(ERR, "All slaves link get failed"); + return 0; + } } @@ -2603,24 +2662,41 @@ bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev) return ret; } -static void +static int bond_ethdev_allmulticast_enable(struct rte_eth_dev *eth_dev) { struct bond_dev_private *internals = eth_dev->data->dev_private; int i; + int ret = 0; + uint16_t port_id; switch (internals->mode) { /* allmulti mode is propagated to all slaves */ case BONDING_MODE_ROUND_ROBIN: case BONDING_MODE_BALANCE: case BONDING_MODE_BROADCAST: - case BONDING_MODE_8023AD: + case BONDING_MODE_8023AD: { + unsigned int slave_ok = 0; + for (i = 0; i < internals->slave_count; i++) { - uint16_t port_id = internals->slaves[i].port_id; + port_id = internals->slaves[i].port_id; - rte_eth_allmulticast_enable(port_id); + ret = rte_eth_allmulticast_enable(port_id); + if (ret != 0) + RTE_BOND_LOG(ERR, + "Failed to enable allmulti mode for port %u: %s", + port_id, rte_strerror(-ret)); + else + slave_ok++; } + /* + * Report success if operation is successful on at least + * on one slave. Otherwise return last error code. + */ + if (slave_ok > 0) + ret = 0; break; + } /* allmulti mode is propagated only to primary slave */ case BONDING_MODE_ACTIVE_BACKUP: case BONDING_MODE_TLB: @@ -2629,22 +2705,33 @@ bond_ethdev_allmulticast_enable(struct rte_eth_dev *eth_dev) /* Do not touch allmulti when there cannot be primary ports */ if (internals->slave_count == 0) break; - rte_eth_allmulticast_enable(internals->current_primary_port); + port_id = internals->current_primary_port; + ret = rte_eth_allmulticast_enable(port_id); + if (ret != 0) + RTE_BOND_LOG(ERR, + "Failed to enable allmulti mode for port %u: %s", + port_id, rte_strerror(-ret)); } + + return ret; } -static void +static int bond_ethdev_allmulticast_disable(struct rte_eth_dev *eth_dev) { struct bond_dev_private *internals = eth_dev->data->dev_private; int i; + int ret = 0; + uint16_t port_id; switch (internals->mode) { /* allmulti mode is propagated to all slaves */ case BONDING_MODE_ROUND_ROBIN: case BONDING_MODE_BALANCE: case BONDING_MODE_BROADCAST: - case BONDING_MODE_8023AD: + case BONDING_MODE_8023AD: { + unsigned int slave_ok = 0; + for (i = 0; i < internals->slave_count; i++) { uint16_t port_id = internals->slaves[i].port_id; @@ -2652,9 +2739,23 @@ bond_ethdev_allmulticast_disable(struct rte_eth_dev *eth_dev) bond_mode_8023ad_ports[port_id].forced_rx_flags == BOND_8023AD_FORCED_ALLMULTI) continue; - rte_eth_allmulticast_disable(port_id); + + ret = rte_eth_allmulticast_disable(port_id); + if (ret != 0) + RTE_BOND_LOG(ERR, + "Failed to disable allmulti mode for port %u: %s", + port_id, rte_strerror(-ret)); + else + slave_ok++; } + /* + * Report success if operation is successful on at least + * on one slave. Otherwise return last error code. + */ + if (slave_ok > 0) + ret = 0; break; + } /* allmulti mode is propagated only to primary slave */ case BONDING_MODE_ACTIVE_BACKUP: case BONDING_MODE_TLB: @@ -2663,8 +2764,15 @@ bond_ethdev_allmulticast_disable(struct rte_eth_dev *eth_dev) /* Do not touch allmulti when there cannot be primary ports */ if (internals->slave_count == 0) break; - rte_eth_allmulticast_disable(internals->current_primary_port); + port_id = internals->current_primary_port; + ret = rte_eth_allmulticast_disable(port_id); + if (ret != 0) + RTE_BOND_LOG(ERR, + "Failed to disable allmulti mode for port %u: %s", + port_id, rte_strerror(-ret)); } + + return ret; } static void @@ -2673,7 +2781,7 @@ bond_ethdev_delayed_lsc_propagation(void *arg) if (arg == NULL) return; - _rte_eth_dev_callback_process((struct rte_eth_dev *)arg, + rte_eth_dev_callback_process((struct rte_eth_dev *)arg, RTE_ETH_EVENT_INTR_LSC, NULL); } @@ -2685,6 +2793,7 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type, struct bond_dev_private *internals; struct rte_eth_link link; int rc = -1; + int ret; uint8_t lsc_flag = 0; int valid_slave = 0; @@ -2725,8 +2834,11 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type, 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) { + ret = rte_eth_link_get_nowait(port_id, &link); + if (ret < 0) + RTE_BOND_LOG(ERR, "Slave (port %u) link get failed", port_id); + + if (ret == 0 && link.link_status) { if (active_pos < internals->active_slave_count) goto link_update; @@ -2780,6 +2892,7 @@ bond_ethdev_lsc_event_callback(uint16_t port_id, enum rte_eth_event_type type, internals->active_slaves[0]); else internals->current_primary_port = internals->primary_port; + mac_address_slaves_update(bonded_eth_dev); } } @@ -2803,7 +2916,7 @@ link_update: bond_ethdev_delayed_lsc_propagation, (void *)bonded_eth_dev); else - _rte_eth_dev_callback_process(bonded_eth_dev, + rte_eth_dev_callback_process(bonded_eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL); @@ -2813,7 +2926,7 @@ link_update: bond_ethdev_delayed_lsc_propagation, (void *)bonded_eth_dev); else - _rte_eth_dev_callback_process(bonded_eth_dev, + rte_eth_dev_callback_process(bonded_eth_dev, RTE_ETH_EVENT_INTR_LSC, NULL); } @@ -2838,7 +2951,8 @@ bond_ethdev_rss_reta_update(struct rte_eth_dev *dev, return -EINVAL; /* Copy RETA table */ - reta_count = reta_size / RTE_RETA_GROUP_SIZE; + reta_count = (reta_size + RTE_RETA_GROUP_SIZE - 1) / + RTE_RETA_GROUP_SIZE; for (i = 0; i < reta_count; i++) { internals->reta_conf[i].mask = reta_conf[i].mask; @@ -3314,14 +3428,10 @@ bond_remove(struct rte_vdev_device *dev) name = rte_vdev_device_name(dev); RTE_BOND_LOG(INFO, "Uninitializing pmd_bond for %s", name); - /* now free all data allocation - for eth_dev structure, - * dummy pci driver and internal (private) data - */ - /* find an ethdev entry */ eth_dev = rte_eth_dev_allocated(name); if (eth_dev == NULL) - return -ENODEV; + return 0; /* port already released */ if (rte_eal_process_type() != RTE_PROC_PRIMARY) return rte_eth_dev_release_port(eth_dev); @@ -3336,19 +3446,6 @@ bond_remove(struct rte_vdev_device *dev) bond_ethdev_stop(eth_dev); bond_ethdev_close(eth_dev); } - - eth_dev->dev_ops = NULL; - eth_dev->rx_pkt_burst = NULL; - eth_dev->tx_pkt_burst = NULL; - - internals = eth_dev->data->dev_private; - /* Try to release mempool used in mode6. If the bond - * device is not mode6, free the NULL is not problem. - */ - rte_mempool_free(internals->mode6.mempool); - rte_bitmap_free(internals->vlan_filter_bmp); - rte_free(internals->vlan_filter_bmpmem); - rte_eth_dev_release_port(eth_dev); return 0; @@ -3657,11 +3754,4 @@ RTE_PMD_REGISTER_PARAM_STRING(net_bonding, "up_delay= " "down_delay="); -int bond_logtype; - -RTE_INIT(bond_init_log) -{ - bond_logtype = rte_log_register("pmd.net.bond"); - if (bond_logtype >= 0) - rte_log_set_level(bond_logtype, RTE_LOG_NOTICE); -} +RTE_LOG_REGISTER(bond_logtype, pmd.net.bond, NOTICE);