zoukankan      html  css  js  c++  java
  • dpdk bond

    bond_ethdev_mode_set(struct rte_eth_dev *eth_dev, int mode)
    {
            struct bond_dev_private *internals;
    
            internals = eth_dev->data->dev_private;
    
            switch (mode) {
            case BONDING_MODE_ROUND_ROBIN:
                    eth_dev->tx_pkt_burst = bond_ethdev_tx_burst_round_robin;
                    eth_dev->rx_pkt_burst = bond_ethdev_rx_burst;
                    break;
            case BONDING_MODE_ACTIVE_BACKUP:
                    eth_dev->tx_pkt_burst = bond_ethdev_tx_burst_active_backup;
                    eth_dev->rx_pkt_burst = bond_ethdev_rx_burst_active_backup;
                    break;
            case BONDING_MODE_BALANCE:
                    eth_dev->tx_pkt_burst = bond_ethdev_tx_burst_balance;
                    eth_dev->rx_pkt_burst = bond_ethdev_rx_burst;
                    break;
            case BONDING_MODE_BROADCAST:
                    eth_dev->tx_pkt_burst = bond_ethdev_tx_burst_broadcast;
                    eth_dev->rx_pkt_burst = bond_ethdev_rx_burst;
                    break;
            case BONDING_MODE_8023AD:
                    if (bond_mode_8023ad_enable(eth_dev) != 0)
                            return -1;
    
                    if (internals->mode4.dedicated_queues.enabled == 0) {
                            eth_dev->rx_pkt_burst = bond_ethdev_rx_burst_8023ad;
                            eth_dev->tx_pkt_burst = bond_ethdev_tx_burst_8023ad;
                            RTE_BOND_LOG(WARNING,
                                    "Using mode 4, it is necessary to do TX burst "
                                    "and RX burst at least every 100ms.");
                    } else {
                            /* Use flow director's optimization */
                            eth_dev->rx_pkt_burst =
                                            bond_ethdev_rx_burst_8023ad_fast_queue;
                            eth_dev->tx_pkt_burst =
                                            bond_ethdev_tx_burst_8023ad_fast_queue;
                    }
                    break;
            case BONDING_MODE_TLB:
                    eth_dev->tx_pkt_burst = bond_ethdev_tx_burst_tlb;
                    eth_dev->rx_pkt_burst = bond_ethdev_rx_burst_active_backup;
                    break;
            case BONDING_MODE_ALB:
                    if (bond_mode_alb_enable(eth_dev) != 0)
                            return -1;
    
                    eth_dev->tx_pkt_burst = bond_ethdev_tx_burst_alb;
                    eth_dev->rx_pkt_burst = bond_ethdev_rx_burst_alb;
                    break;
            default:
                    return -1;
            }
    
            internals->mode = mode;
    
            return 0;
    }

    bond_ethdev_rx_queue_setup

    static int
    bond_ethdev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
                    uint16_t nb_rx_desc, unsigned int socket_id __rte_unused,
                    const struct rte_eth_rxconf *rx_conf, struct rte_mempool *mb_pool)
    {
            struct bond_rx_queue *bd_rx_q = (struct bond_rx_queue *)
                            rte_zmalloc_socket(NULL, sizeof(struct bond_rx_queue),
                                            0, dev->data->numa_node);
            if (bd_rx_q == NULL)
                    return -1;
    
            bd_rx_q->queue_id = rx_queue_id;
            bd_rx_q->dev_private = dev->data->dev_private;
    
            bd_rx_q->nb_rx_desc = nb_rx_desc;
    
            memcpy(&(bd_rx_q->rx_conf), rx_conf, sizeof(struct rte_eth_rxconf));
            bd_rx_q->mb_pool = mb_pool;
    
            dev->data->rx_queues[rx_queue_id] = bd_rx_q;
    
            return 0;
    }

    bond_ethdev_rx_burst

    static uint16_t
    bond_ethdev_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
    {
            struct bond_dev_private *internals;
    
            uint16_t num_rx_total = 0;
            uint16_t slave_count;
            uint16_t active_slave;
            int i;
    
            /* Cast to structure, containing bonded device's port id and queue id */
            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;
    
            for (i = 0; i < slave_count && nb_pkts; i++) {
                    uint16_t num_rx_slave;
    
                    /* Offset of pointer to *bufs increases as packets are received
                     * from other slaves */
                    num_rx_slave =
                            rte_eth_rx_burst(internals->active_slaves[active_slave],
                                             bd_rx_q->queue_id,
                                             bufs + num_rx_total, nb_pkts);
                    num_rx_total += num_rx_slave;
                    nb_pkts -= num_rx_slave;
                    if (++active_slave == slave_count)
                            active_slave = 0;
            }
    
            if (++internals->active_slave >= slave_count)
                    internals->active_slave = 0;
            return num_rx_total;
    }

    rte_eth_bond_slave_add

    rte_eth_bond_slave_add(uint16_t bonded_port_id, uint16_t slave_port_id)
    {
            struct rte_eth_dev *bonded_eth_dev;
            struct bond_dev_private *internals;
    
            int retval;
    
            /* Verify that port id's are valid bonded and slave ports */
            if (valid_bonded_port_id(bonded_port_id) != 0)
                    return -1;
    
            bonded_eth_dev = &rte_eth_devices[bonded_port_id];
            internals = bonded_eth_dev->data->dev_private;
    
            rte_spinlock_lock(&internals->lock);
    
            retval = __eth_bond_slave_add_lock_free(bonded_port_id, slave_port_id);
    
            rte_spinlock_unlock(&internals->lock);
    
            return retval;
    }
    static int
    __eth_bond_slave_add_lock_free(uint16_t bonded_port_id, uint16_t slave_port_id)
    {
            struct rte_eth_dev *bonded_eth_dev, *slave_eth_dev;
            struct bond_dev_private *internals;
            struct rte_eth_link link_props;
            struct rte_eth_dev_info dev_info;
            int ret;
    
            bonded_eth_dev = &rte_eth_devices[bonded_port_id];
            internals = bonded_eth_dev->data->dev_private;
    
            if (valid_slave_port_id(slave_port_id, internals->mode) != 0)
                    return -1;
    
            slave_eth_dev = &rte_eth_devices[slave_port_id];
            if (slave_eth_dev->data->dev_flags & RTE_ETH_DEV_BONDED_SLAVE) {
                    RTE_BOND_LOG(ERR, "Slave device is already a slave of a bonded device");
                    return -1;
            }
    
            ret = rte_eth_dev_info_get(slave_port_id, &dev_info);
            if (ret != 0) {
                    RTE_BOND_LOG(ERR,
                            "%s: Error during getting device (port %u) info: %s
    ",
                            __func__, slave_port_id, strerror(-ret));
    
                    return ret;
            }
            if (dev_info.max_rx_pktlen < internals->max_rx_pktlen) {
                    RTE_BOND_LOG(ERR, "Slave (port %u) max_rx_pktlen too small",
                                 slave_port_id);
                    return -1;
            }
    
            slave_add(internals, slave_eth_dev);
    
            /* We need to store slaves reta_size to be able to synchronize RETA for all
             * slave devices even if its sizes are different.
             */
            internals->slaves[internals->slave_count].reta_size = dev_info.reta_size;
    
            if (internals->slave_count < 1) {
                    /* if MAC is not user defined then use MAC of first slave add to
                     * bonded device */
                    if (!internals->user_defined_mac) {
                            if (mac_address_set(bonded_eth_dev,
                                                slave_eth_dev->data->mac_addrs)) {
                                    RTE_BOND_LOG(ERR, "Failed to set MAC address");
                                    return -1;
                            }
                    }
    
                    /* Make primary slave */
                    internals->primary_port = slave_port_id;
                    internals->current_primary_port = slave_port_id;

     /* Inherit queues settings from first slave */
                    internals->nb_rx_queues = slave_eth_dev->data->nb_rx_queues;
                    internals->nb_tx_queues = slave_eth_dev->data->nb_tx_queues;
    
                    eth_bond_slave_inherit_dev_info_rx_first(internals, &dev_info);
                    eth_bond_slave_inherit_dev_info_tx_first(internals, &dev_info);
    
                    eth_bond_slave_inherit_desc_lim_first(&internals->rx_desc_lim,
                                                          &dev_info.rx_desc_lim);
                    eth_bond_slave_inherit_desc_lim_first(&internals->tx_desc_lim,
                                                          &dev_info.tx_desc_lim);
            } else {
                    int ret;
    
                    eth_bond_slave_inherit_dev_info_rx_next(internals, &dev_info);
                    eth_bond_slave_inherit_dev_info_tx_next(internals, &dev_info);
    
                    ret = eth_bond_slave_inherit_desc_lim_next(
                                    &internals->rx_desc_lim, &dev_info.rx_desc_lim);
                    if (ret != 0)
                            return ret;
    
                    ret = eth_bond_slave_inherit_desc_lim_next(
                                    &internals->tx_desc_lim, &dev_info.tx_desc_lim);
                    if (ret != 0)
                            return ret;
            }
    
            bonded_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf &=
                            internals->flow_type_rss_offloads;
    
            if (slave_rte_flow_prepare(internals->slave_count, internals) != 0) {
                    RTE_BOND_LOG(ERR, "Failed to prepare new slave flows: port=%d",
                                 slave_port_id);
                    return -1;
            }
    
            /* Add additional MAC addresses to the slave */
            if (slave_add_mac_addresses(bonded_eth_dev, slave_port_id) != 0) {
                    RTE_BOND_LOG(ERR, "Failed to add mac address(es) to slave %hu",
                                    slave_port_id);
                    return -1;
            }
    
            internals->slave_count++;
    
            if (bonded_eth_dev->data->dev_started) {
                    if (slave_configure(bonded_eth_dev, slave_eth_dev) != 0) {
                            internals->slave_count--;
                            RTE_BOND_LOG(ERR, "rte_bond_slaves_configure: port=%d",
                                            slave_port_id);
                            return -1;
                    }
            }
    
            /* Update all slave devices MACs */
            mac_address_slaves_update(bonded_eth_dev);
    
            /* Register link status change callback with bonded device pointer as
             * argument*/
            rte_eth_dev_callback_register(slave_port_id, RTE_ETH_EVENT_INTR_LSC,
                            bond_ethdev_lsc_event_callback, &bonded_eth_dev->data->port_id);
    
            /* If bonded device is started then we can add the slave to our active
             * slave array */
            if (bonded_eth_dev->data->dev_started) {
                    ret = rte_eth_link_get_nowait(slave_port_id, &link_props);
                    if (ret < 0) {
                            rte_eth_dev_callback_unregister(slave_port_id,
                                            RTE_ETH_EVENT_INTR_LSC,
            /* If bonded device is started then we can add the slave to our active
             * slave array */
            if (bonded_eth_dev->data->dev_started) {
                    ret = rte_eth_link_get_nowait(slave_port_id, &link_props);
                    if (ret < 0) {
                            rte_eth_dev_callback_unregister(slave_port_id,
                                            RTE_ETH_EVENT_INTR_LSC,
                                            bond_ethdev_lsc_event_callback,
                                            &bonded_eth_dev->data->port_id);
                            internals->slave_count--;
                            RTE_BOND_LOG(ERR,
                                    "Slave (port %u) link get failed: %s
    ",
                                    slave_port_id, rte_strerror(-ret));
                            return -1;
                    }
    
                     if (link_props.link_status == ETH_LINK_UP) {
                            if (internals->active_slave_count == 0 &&
                                !internals->user_defined_primary_port)
                                    bond_ethdev_primary_set(internals,
                                                            slave_port_id);
                    }
            }
    
            /* Add slave details to bonded device */
            slave_eth_dev->data->dev_flags |= RTE_ETH_DEV_BONDED_SLAVE;
    
            slave_vlan_filter_set(bonded_port_id, slave_port_id);
    
            return 0;
    
    }

    eth_bond_slave_inherit_dev_info_rx_next

    static void
    eth_bond_slave_inherit_dev_info_rx_next(struct bond_dev_private *internals,
                                            const struct rte_eth_dev_info *di)
    {
            struct rte_eth_rxconf *rxconf_i = &internals->default_rxconf;
            const struct rte_eth_rxconf *rxconf = &di->default_rxconf;
    
            internals->rx_offload_capa &= di->rx_offload_capa;
            internals->rx_queue_offload_capa &= di->rx_queue_offload_capa;
            internals->flow_type_rss_offloads &= di->flow_type_rss_offloads;
    
            /*
             * If at least one slave device suggests enabling this
             * setting by default, enable it for all slave devices
             * since disabling it may not be necessarily supported.
             */
            if (rxconf->rx_drop_en == 1)
                    rxconf_i->rx_drop_en = 1;
    
            /*
             * Adding a new slave device may cause some of previously inherited
             * offloads to be withdrawn from the internal rx_queue_offload_capa
             * value. Thus, the new internal value of default Rx queue offloads
             * has to be masked by rx_queue_offload_capa to make sure that only
             * commonly supported offloads are preserved from both the previous
             * value and the value being inhereted from the new slave device.
             */
            rxconf_i->offloads = (rxconf_i->offloads | rxconf->offloads) &
                                 internals->rx_queue_offload_capa;
    
            /*
             * RETA size is GCD of all slaves RETA sizes, so, if all sizes will be
             * the power of 2, the lower one is GCD
             */
            if (internals->reta_size > di->reta_size)
                    internals->reta_size = di->reta_size;
    
            if (!internals->max_rx_pktlen &&
                di->max_rx_pktlen < internals->candidate_max_rx_pktlen)
                    internals->candidate_max_rx_pktlen = di->max_rx_pktlen;
    }

    primary

    bond_ethdev_primary_set(struct bond_dev_private *internals,
                    uint16_t slave_port_id)
    {
            int i;
    
            if (internals->active_slave_count < 1)
                    internals->current_primary_port = slave_port_id;
            else
                    /* Search bonded device slave ports for new proposed primary port */
                    for (i = 0; i < internals->active_slave_count; i++) {
                            if (internals->active_slaves[i] == slave_port_id)
                                    internals->current_primary_port = slave_port_id;
                    }
    }
    bond_ethdev_promiscuous_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) {
            /* Promiscuous mode is propagated to all slaves */
            case BONDING_MODE_ROUND_ROBIN:
            case BONDING_MODE_BALANCE:
            case BONDING_MODE_BROADCAST:
            case BONDING_MODE_8023AD: {
                    unsigned int slave_ok = 0;
    
                    for (i = 0; i < internals->slave_count; i++) {
                            port_id = internals->slaves[i].port_id;
    
                            ret = rte_eth_promiscuous_enable(port_id);
                            if (ret != 0)
                                    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:
            case BONDING_MODE_ALB:
            default:
                    /* Do not touch promisc when there cannot be primary ports */
                    if (internals->slave_count == 0)
                            break;
                    port_id = internals->current_primary_port;
                    ret = rte_eth_promiscuous_enable(port_id);
                    if (ret != 0)
                            RTE_BOND_LOG(ERR,
                                    "Failed to enable promiscuous mode for port %u: %s",
                                    port_id, rte_strerror(-ret));
            }
    
            return ret;
    }
  • 相关阅读:
    微服务架构
    微服务架构
    Java语言编程
    Java语言编程
    Java语言编程
    《自己动手写云盘》 – 确立需求
    树上差分
    线性基
    BM(Berlekamp-Massey)算法
    FFT/FWT
  • 原文地址:https://www.cnblogs.com/dream397/p/14870529.html
Copyright © 2011-2022 走看看