X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fbonding%2Frte_eth_bond_pmd.c;h=707a0f3cdd73377ea08f71b45d35f33d4ef8815a;hb=de480bbf138bf61b14dafb806f6e66808871f3e3;hp=edf660db3462f31b1368357268b2d6d66f6a2061;hpb=ae9f487f2ea463eac4424d7ca19bcb18a9287906;p=dpdk.git diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c index edf660db34..707a0f3cdd 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) @@ -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; @@ -1915,7 +1921,7 @@ bond_ethdev_primary_set(struct bond_dev_private *internals, } } -static void +static int bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev); static int @@ -2358,12 +2364,14 @@ bond_ethdev_slave_link_status_change_monitor(void *cb_arg) static int bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete) { - void (*link_update)(uint16_t port_id, struct rte_eth_link *eth_link); + int (*link_update)(uint16_t port_id, struct rte_eth_link *eth_link); 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; @@ -2395,8 +2403,18 @@ bond_ethdev_link_update(struct rte_eth_dev *ethdev, int wait_to_complete) * packet loss will occur on this slave if transmission at rates * greater than this are attempted */ - for (idx = 1; idx < bond_ctx->active_slave_count; idx++) { - link_update(bond_ctx->active_slaves[0], &slave_link); + for (idx = 0; idx < bond_ctx->active_slave_count; idx++) { + 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 +2424,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 +2439,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 +2451,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; + } } @@ -2472,17 +2512,24 @@ bond_ethdev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) return 0; } -static void +static int bond_ethdev_stats_reset(struct rte_eth_dev *dev) { struct bond_dev_private *internals = dev->data->dev_private; int i; + int err; + int ret; - for (i = 0; i < internals->slave_count; i++) - rte_eth_stats_reset(internals->slaves[i].port_id); + for (i = 0, err = 0; i < internals->slave_count; i++) { + ret = rte_eth_stats_reset(internals->slaves[i].port_id); + if (ret != 0) + err = ret; + } + + return err; } -static void +static int bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev) { struct bond_dev_private *internals = eth_dev->data->dev_private; @@ -2495,7 +2542,9 @@ bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev) 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++) { port_id = internals->slaves[i].port_id; @@ -2504,8 +2553,17 @@ bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev) RTE_BOND_LOG(ERR, "Failed to enable promiscuous 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; + } /* Promiscuous mode is propagated only to primary slave */ case BONDING_MODE_ACTIVE_BACKUP: case BONDING_MODE_TLB: @@ -2521,14 +2579,16 @@ bond_ethdev_promiscuous_enable(struct rte_eth_dev *eth_dev) "Failed to enable promiscuous mode for port %u: %s", port_id, rte_strerror(-ret)); } + + return ret; } -static void +static int bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev) { struct bond_dev_private *internals = dev->data->dev_private; int i; - int ret; + int ret = 0; uint16_t port_id; switch (internals->mode) { @@ -2536,21 +2596,34 @@ bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev) 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++) { port_id = internals->slaves[i].port_id; if (internals->mode == BONDING_MODE_8023AD && bond_mode_8023ad_ports[port_id].forced_rx_flags == - BOND_8023AD_FORCED_PROMISC) + BOND_8023AD_FORCED_PROMISC) { + slave_ok++; continue; + } ret = rte_eth_promiscuous_disable(port_id); if (ret != 0) RTE_BOND_LOG(ERR, "Failed to disable promiscuous 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; + } /* Promiscuous mode is propagated only to primary slave */ case BONDING_MODE_ACTIVE_BACKUP: case BONDING_MODE_TLB: @@ -2566,26 +2639,45 @@ bond_ethdev_promiscuous_disable(struct rte_eth_dev *dev) "Failed to disable promiscuous mode for port %u: %s", port_id, rte_strerror(-ret)); } + + 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: @@ -2594,22 +2686,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; @@ -2617,9 +2720,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: @@ -2628,8 +2745,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 @@ -2650,6 +2774,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; @@ -2690,8 +2815,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;