On 17.12.2019 20:23, Ben Pfaff wrote:
> Thanks for the patch!
>
> "sparse" reports some type errors:
>
> ../ofproto/bond.c:357:30: error: incorrect type in assignment (different
> base types)
> ../ofproto/bond.c:357:30: expected unsigned int
> ../ofproto/bond.c:357:30: got restricted ofp_port_t [usertype] ofp_port
> ../ofproto/ofproto-dpif.c:3454:56: error: incorrect type in argument 2
> (different base types)
> ../ofproto/ofproto-dpif.c:3454:56: expected restricted ofp_port_t
> [usertype]
> ../ofproto/ofproto-dpif.c:3454:56: got unsigned int [usertype]
> ../ofproto/ofproto-dpif.c:3453:31: error: incorrect type in assignment
> (different base types)
> ../ofproto/ofproto-dpif.c:3453:31: expected unsigned int [usertype]
> ../ofproto/ofproto-dpif.c:3453:31: got restricted odp_port_t
> ../ofproto/ofproto-dpif-xlate.c:4208:39: error: incorrect type in
> argument 3 (different base types)
> ../ofproto/ofproto-dpif-xlate.c:4208:39: expected restricted
> odp_port_t [usertype] value
> ../ofproto/ofproto-dpif-xlate.c:4208:39: got unsigned int const
> [usertype] recirc_id
>
> I took a look. The underlying issue is that code here mixes integers,
> ofp_port_t, and odp_port_t. OVS uses "sparse" annotations to keep these
> from being confused, since they are different in important ways. I
> spent some time working through the types here and appended a patch that
> fixes them up. I also made a bunch of style updates throughout the
> code, which might obscure the relevant changes a bit; my apologies.
>
> It seems odd that dpif_bond_*() succeed if the dpif doesn't support
> them. Shouldn't they return an error by default, instead of 0?
>
> Is there a reason to allow users to turn this off? What is the downside
> of enabling it? Why is it disabled by default? In general, OVS should
> optimize itself to the extent it can rather than relying on a
> knowledgeable user to tweak it. If it's necessary to make it
> configurable, then the documentation (in vswitch.xml) should explain why
> one would want to turn it on or off and what the default is.
Hi Ben,
I just wanted to add a few comments here. There are few possibly unwanted
things that appears while enabling the feature:
1. Bonding rebalancing triggers reload of PMD threads, that might affect
performance of highly loaded threads.
2. While datapath supports lb_output action, netdev-offload provider might
not support it. This could be an issue.
So, I think it's sane to have a configuration knob. Not sure about disabling
by default but it might make a bit of sense keeping this feature as experimental
for some time. And yes, I agree that documentation should be updated.
>
> This introduces a new capabilities flag, which should be documented with
> the other capabilities in vswitch.xml.
>
> I'm appending a suggested diff to fold into your patch.
>
> I did not do a full technical review for correctness. I'll do that on
> the next revision.
>
> Thanks,
>
> Ben.
>
> -8<--------------------------cut here-------------------------->8--
>
> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
> index 9a2befdcbc02..fa9ff73a4101 100644
> --- a/lib/dpif-netdev.c
> +++ b/lib/dpif-netdev.c
> @@ -604,7 +604,7 @@ struct tx_port {
>
> /* Contained by struct tx_bond 'slave_buckets' */
> struct slave_entry {
> - uint32_t slave_id;
> + odp_port_t slave_id;
> atomic_ullong n_packets;
> atomic_ullong n_bytes;
> };
> @@ -1427,12 +1427,10 @@ dpif_netdev_dp_bond_show(struct unixctl_conn *conn,
> int argc,
> const char *argv[], void *aux OVS_UNUSED)
> {
> struct ds reply = DS_EMPTY_INITIALIZER;
> - struct dp_netdev *dp = NULL;
> - uint32_t bucket;
> - struct tx_bond *dp_bond_entry = NULL;
>
> ovs_mutex_lock(&dp_netdev_mutex);
>
> + struct dp_netdev *dp = NULL;
> if (argc == 2) {
> dp = shash_find_data(&dp_netdevs, argv[1]);
> } else if (shash_count(&dp_netdevs) == 1) {
> @@ -1446,10 +1444,12 @@ dpif_netdev_dp_bond_show(struct unixctl_conn *conn,
> int argc,
> return;
> }
> ds_put_cstr(&reply, "\nBonds:\n");
> +
> + struct tx_bond *dp_bond_entry;
> HMAP_FOR_EACH (dp_bond_entry, node, &dp->bonds) {
> ds_put_format(&reply, "\tbond-id %u :\n",
> dp_bond_entry->bond_id);
> - for (bucket = 0; bucket < BOND_BUCKETS; bucket++) {
> + for (int bucket = 0; bucket < BOND_BUCKETS; bucket++) {
> ds_put_format(&reply, "\t\tbucket %u - slave %u \n",
> bucket,
> dp_bond_entry->slave_buckets[bucket].slave_id);
> @@ -1735,7 +1735,6 @@ dp_netdev_free(struct dp_netdev *dp)
> OVS_REQUIRES(dp_netdev_mutex)
> {
> struct dp_netdev_port *port, *next;
> - struct tx_bond *bond, *next_bond;
>
> shash_find_and_delete(&dp_netdevs, dp->name);
>
> @@ -1746,6 +1745,7 @@ dp_netdev_free(struct dp_netdev *dp)
> ovs_mutex_unlock(&dp->port_mutex);
>
> ovs_mutex_lock(&dp->bond_mutex);
> + struct tx_bond *bond, *next_bond;
> HMAP_FOR_EACH_SAFE (bond, next_bond, node, &dp->bonds) {
> hmap_remove(&dp->bonds, &bond->node);
> free(bond);
> @@ -4933,11 +4933,10 @@ pmd_remove_stale_bonds(struct dp_netdev *dp,
> OVS_EXCLUDED(pmd->bond_mutex)
> OVS_EXCLUDED(dp->bond_mutex)
> {
> - struct tx_bond *tx, *tx_next;
> -
> ovs_mutex_lock(&dp->bond_mutex);
> ovs_mutex_lock(&pmd->bond_mutex);
>
> + struct tx_bond *tx, *tx_next;
> HMAP_FOR_EACH_SAFE (tx, tx_next, node, &pmd->tx_bonds) {
> if (!tx_bond_lookup(&dp->bonds, tx->bond_id)) {
> dp_netdev_del_bond_tx_from_pmd(pmd, tx);
> @@ -4958,7 +4957,6 @@ reconfigure_datapath(struct dp_netdev *dp)
> struct hmapx busy_threads = HMAPX_INITIALIZER(&busy_threads);
> struct dp_netdev_pmd_thread *pmd;
> struct dp_netdev_port *port;
> - struct tx_bond *bond;
> int wanted_txqs;
>
> dp->last_reconfigure_seq = seq_read(dp->reconfigure_seq);
> @@ -5119,6 +5117,7 @@ reconfigure_datapath(struct dp_netdev *dp)
> CMAP_FOR_EACH (pmd, node, &dp->poll_threads) {
> ovs_mutex_lock(&pmd->bond_mutex);
> if (hmap_count(&pmd->poll_list) || pmd->core_id == NON_PMD_CORE_ID) {
> + struct tx_bond *bond;
> HMAP_FOR_EACH (bond, node, &dp->bonds) {
> dp_netdev_add_bond_tx_to_pmd(pmd, bond);
> }
> @@ -5577,13 +5576,11 @@ static void
> pmd_load_cached_bonds(struct dp_netdev_pmd_thread *pmd)
> OVS_REQUIRES(pmd->bond_mutex)
> {
> - struct tx_bond *tx_bond, *tx_bond_cached;
> -
> pmd_free_cached_bonds(pmd);
> hmap_shrink(&pmd->bond_cache);
>
> + struct tx_bond *tx_bond, *tx_bond_cached;
> HMAP_FOR_EACH (tx_bond, node, &pmd->tx_bonds) {
> - uint32_t bucket = 0;
> /* Check if bond already exist on pmd. */
> tx_bond_cached = tx_bond_lookup(&pmd->bond_cache, tx_bond->bond_id);
>
> @@ -5594,12 +5591,12 @@ pmd_load_cached_bonds(struct dp_netdev_pmd_thread
> *pmd)
> hash_bond_id(tx_bond_cached->bond_id));
> } else {
> /* Update the slave-map. */
> - for (bucket = 0; bucket <= BOND_MASK; bucket++) {
> + for (int bucket = 0; bucket <= BOND_MASK; bucket++) {
> tx_bond_cached->slave_buckets[bucket].slave_id =
> tx_bond->slave_buckets[bucket].slave_id;
> }
> }
> - VLOG_DBG("Caching bond-id %d pmd %d\n",
> + VLOG_DBG("Caching bond-id %d pmd %d",
> tx_bond_cached->bond_id, pmd->core_id);
> }
> }
> @@ -6432,14 +6429,11 @@ dp_netdev_add_bond_tx_to_pmd(struct
> dp_netdev_pmd_thread *pmd,
> struct tx_bond *bond)
> OVS_REQUIRES(pmd->bond_mutex)
> {
> - struct tx_bond *tx;
> - uint32_t i;
> bool reload = false;
> -
> - tx = tx_bond_lookup(&pmd->tx_bonds, bond->bond_id);
> + struct tx_bond *tx = tx_bond_lookup(&pmd->tx_bonds, bond->bond_id);
> if (tx) {
> /* Check if mapping is changed. */
> - for (i = 0; i <= BOND_MASK; i++) {
> + for (int i = 0; i <= BOND_MASK; i++) {
> if (bond->slave_buckets[i].slave_id !=
> tx->slave_buckets[i].slave_id) {
> /* Mapping is modified. Reload pmd bond cache again. */
> @@ -6453,7 +6447,7 @@ dp_netdev_add_bond_tx_to_pmd(struct
> dp_netdev_pmd_thread *pmd,
> hmap_insert(&pmd->tx_bonds, &tx->node, hash_bond_id(bond->bond_id));
> reload = true;
> }
> - if (reload == true) {
> + if (reload) {
> pmd->need_reload = true;
> }
> }
> @@ -7296,49 +7290,89 @@ dp_execute_userspace_action(struct
> dp_netdev_pmd_thread *pmd,
> }
> }
>
> -static int
> +static bool
> dp_execute_output_action(struct dp_netdev_pmd_thread *pmd,
> struct dp_packet_batch *packets_,
> - bool should_steal,
> - odp_port_t port_no)
> + bool should_steal, odp_port_t port_no)
> {
> - struct tx_port *p;
> - p = pmd_send_port_cache_lookup(pmd, port_no);
> - if (OVS_LIKELY(p)) {
> - struct dp_packet *packet;
> - struct dp_packet_batch out;
> - if (!should_steal) {
> - dp_packet_batch_clone(&out, packets_);
> - dp_packet_batch_reset_cutlen(packets_);
> - packets_ = &out;
> - }
> - dp_packet_batch_apply_cutlen(packets_);
> + struct tx_port *p = pmd_send_port_cache_lookup(pmd, port_no);
> + if (!OVS_LIKELY(p)) {
> + return false;
> + }
> +
> + struct dp_packet_batch out;
> + if (!should_steal) {
> + dp_packet_batch_clone(&out, packets_);
> + dp_packet_batch_reset_cutlen(packets_);
> + packets_ = &out;
> + }
> + dp_packet_batch_apply_cutlen(packets_);
> #ifdef DPDK_NETDEV
> - if (OVS_UNLIKELY(!dp_packet_batch_is_empty(&p->output_pkts)
> - && packets_->packets[0]->source
> - != p->output_pkts.packets[0]->source)) {
> - /* netdev-dpdk assumes that all packets in a single
> - * output batch has the same source. Flush here to
> - * avoid memory access issues. */
> - dp_netdev_pmd_flush_output_on_port(pmd, p);
> - }
> + if (OVS_UNLIKELY(!dp_packet_batch_is_empty(&p->output_pkts)
> + && packets_->packets[0]->source
> + != p->output_pkts.packets[0]->source)) {
> + /* netdev-dpdk assumes that all packets in a single
> + * output batch has the same source. Flush here to
> + * avoid memory access issues. */
> + dp_netdev_pmd_flush_output_on_port(pmd, p);
> + }
> #endif
> - if (dp_packet_batch_size(&p->output_pkts)
> - + dp_packet_batch_size(packets_) > NETDEV_MAX_BURST) {
> - /* Flush here to avoid overflow. */
> - dp_netdev_pmd_flush_output_on_port(pmd, p);
> - }
> - if (dp_packet_batch_is_empty(&p->output_pkts)) {
> - pmd->n_output_batches++;
> - }
> - DP_PACKET_BATCH_FOR_EACH (i, packet, packets_) {
> - p->output_pkts_rxqs[dp_packet_batch_size(&p->output_pkts)] =
> - pmd->ctx.last_rxq;
> - dp_packet_batch_add(&p->output_pkts, packet);
> + if (dp_packet_batch_size(&p->output_pkts)
> + + dp_packet_batch_size(packets_) > NETDEV_MAX_BURST) {
> + /* Flush here to avoid overflow. */
> + dp_netdev_pmd_flush_output_on_port(pmd, p);
> + }
> + if (dp_packet_batch_is_empty(&p->output_pkts)) {
> + pmd->n_output_batches++;
> + }
> +
> + struct dp_packet *packet;
> + DP_PACKET_BATCH_FOR_EACH (i, packet, packets_) {
> + p->output_pkts_rxqs[dp_packet_batch_size(&p->output_pkts)] =
> + pmd->ctx.last_rxq;
> + dp_packet_batch_add(&p->output_pkts, packet);
> + }
> + return true;
> +}
> +
> +static bool
> +dp_execute_lb_output_action(struct dp_netdev_pmd_thread *pmd,
> + struct dp_packet_batch *packets_,
> + bool should_steal, uint32_t bond)
> +{
> + struct tx_bond *p_bond = pmd_tx_bond_cache_lookup(pmd, bond);
> + if (!p_bond) {
> + return false;
> + }
> +
> + struct dp_packet_batch del_pkts;
> + dp_packet_batch_init(&del_pkts);
> +
> + struct dp_packet *packet;
> + DP_PACKET_BATCH_FOR_EACH (i, packet, packets_) {
> + /*
> + * Lookup the bond-hash table using hash to get the slave.
> + */
> + uint32_t hash = dp_packet_get_rss_hash(packet);
> + struct slave_entry *s_entry = &p_bond->slave_buckets[hash &
> BOND_MASK];
> + odp_port_t bond_member = s_entry->slave_id;
> + uint32_t size = dp_packet_size(packet);
> +
> + struct dp_packet_batch output_pkt;
> + dp_packet_batch_init_packet(&output_pkt, packet);
> + if (OVS_LIKELY(dp_execute_output_action(pmd, &output_pkt,
> should_steal,
> + bond_member))) {
> + /* Update slave stats. */
> + non_atomic_ullong_add(&s_entry->n_packets, 1);
> + non_atomic_ullong_add(&s_entry->n_bytes, size);
> + } else {
> + dp_packet_batch_add(&del_pkts, packet);
> }
> - return 0;
> }
> - return -1;
> +
> + /* Delete packets that failed OUTPUT action */
> + dp_packet_delete_batch(&del_pkts, should_steal);
> + return true;
> }
>
> static void
> @@ -7352,59 +7386,21 @@ dp_execute_cb(void *aux_, struct dp_packet_batch
> *packets_,
> struct dp_netdev *dp = pmd->dp;
> int type = nl_attr_type(a);
> struct tx_port *p;
> - int ret;
>
> switch ((enum ovs_action_attr)type) {
> case OVS_ACTION_ATTR_OUTPUT:
> - ret = dp_execute_output_action(pmd, packets_, should_steal,
> - nl_attr_get_odp_port(a));
> - if (ret == 0) {
> - /* Output action executed successfully. */
> + if (dp_execute_output_action(pmd, packets_, should_steal,
> + nl_attr_get_odp_port(a))) {
> return;
> }
> break;
>
> - case OVS_ACTION_ATTR_LB_OUTPUT: {
> - uint32_t bond = nl_attr_get_u32(a);
> - uint32_t bond_member;
> - uint32_t bucket, hash;
> - struct dp_packet_batch del_pkts;
> - struct dp_packet_batch output_pkt;
> - struct dp_packet *packet;
> - struct tx_bond *p_bond;
> - struct slave_entry *s_entry;
> - uint32_t size;
> -
> - p_bond = pmd_tx_bond_cache_lookup(pmd, bond);
> - dp_packet_batch_init(&del_pkts);
> - if (p_bond) {
> - DP_PACKET_BATCH_FOR_EACH (i, packet, packets_) {
> - /*
> - * Lookup the bond-hash table using hash to get the slave.
> - */
> - hash = dp_packet_get_rss_hash(packet);
> - bucket = hash & BOND_MASK;
> - s_entry = &p_bond->slave_buckets[bucket];
> - bond_member = s_entry->slave_id;
> - size = dp_packet_size(packet);
> -
> - dp_packet_batch_init_packet(&output_pkt, packet);
> - ret = dp_execute_output_action(pmd, &output_pkt,
> should_steal,
> - u32_to_odp(bond_member));
> - if (OVS_UNLIKELY(ret != 0)) {
> - dp_packet_batch_add(&del_pkts, packet);
> - } else {
> - /* Update slave stats. */
> - non_atomic_ullong_add(&s_entry->n_packets, 1);
> - non_atomic_ullong_add(&s_entry->n_bytes, size);
> - }
> - }
> - /* Delete packets that failed OUTPUT action */
> - dp_packet_delete_batch(&del_pkts, should_steal);
> + case OVS_ACTION_ATTR_LB_OUTPUT:
> + if (dp_execute_lb_output_action(pmd, packets_, should_steal,
> + nl_attr_get_u32(a))) {
> return;
> }
> break;
> - }
>
> case OVS_ACTION_ATTR_TUNNEL_PUSH:
> if (should_steal) {
> @@ -7936,23 +7932,23 @@ dpif_netdev_ipf_dump_done(struct dpif *dpif
> OVS_UNUSED, void *ipf_dump_ctx)
> }
>
> static int
> -dpif_netdev_bond_add(struct dpif *dpif, uint32_t bond_id, uint32_t
> slave_map[])
> +dpif_netdev_bond_add(struct dpif *dpif, uint32_t bond_id,
> + odp_port_t slave_map[])
> {
> struct dp_netdev *dp = get_dp_netdev(dpif);
> - struct dp_netdev_pmd_thread *pmd;
> - uint32_t bucket;
> - struct tx_bond *dp_bond_entry = NULL;
>
> ovs_mutex_lock(&dp->bond_mutex);
> /*
> * Lookup for the bond. If already exists, just update the slave-map.
> * Else create new.
> */
> - dp_bond_entry = tx_bond_lookup(&dp->bonds, bond_id);
> + struct tx_bond *dp_bond_entry = tx_bond_lookup(&dp->bonds, bond_id);
> if (dp_bond_entry) {
> - for (bucket = 0; bucket <= BOND_MASK; bucket++) {
> + for (int bucket = 0; bucket <= BOND_MASK; bucket++) {
> dp_bond_entry->slave_buckets[bucket].slave_id =
> slave_map[bucket];
> }
> +
> + struct dp_netdev_pmd_thread *pmd;
> CMAP_FOR_EACH (pmd, node, &dp->poll_threads) {
> ovs_mutex_lock(&pmd->bond_mutex);
> dp_netdev_add_bond_tx_to_pmd(pmd, dp_bond_entry);
> @@ -7961,12 +7957,14 @@ dpif_netdev_bond_add(struct dpif *dpif, uint32_t
> bond_id, uint32_t slave_map[])
> } else {
> struct tx_bond *dp_bond = xzalloc(sizeof *dp_bond);
> dp_bond->bond_id = bond_id;
> - for (bucket = 0; bucket < BOND_BUCKETS; bucket++) {
> + for (int bucket = 0; bucket < BOND_BUCKETS; bucket++) {
> dp_bond->slave_buckets[bucket].slave_id = slave_map[bucket];
> }
> hmap_insert(&dp->bonds, &dp_bond->node,
> hash_bond_id(dp_bond->bond_id));
> +
> /* Insert the bond map in all pmds. */
> + struct dp_netdev_pmd_thread *pmd;
> CMAP_FOR_EACH (pmd, node, &dp->poll_threads) {
> ovs_mutex_lock(&pmd->bond_mutex);
> dp_netdev_add_bond_tx_to_pmd(pmd, dp_bond);
> @@ -7981,15 +7979,14 @@ static int
> dpif_netdev_bond_del(struct dpif *dpif, uint32_t bond_id)
> {
> struct dp_netdev *dp = get_dp_netdev(dpif);
> - struct dp_netdev_pmd_thread *pmd;
> - struct tx_bond *dp_bond_entry = NULL;
>
> ovs_mutex_lock(&dp->bond_mutex);
>
> /* Find the bond and delete it if present */
> - dp_bond_entry = tx_bond_lookup(&dp->bonds, bond_id);
> + struct tx_bond *dp_bond_entry = tx_bond_lookup(&dp->bonds, bond_id);
> if (dp_bond_entry) {
> /* Remove the bond map in all pmds. */
> + struct dp_netdev_pmd_thread *pmd;
> CMAP_FOR_EACH (pmd, node, &dp->poll_threads) {
> ovs_mutex_lock(&pmd->bond_mutex);
> dp_netdev_del_bond_tx_from_pmd(pmd, dp_bond_entry);
> @@ -8008,24 +8005,22 @@ dpif_netdev_bond_stats_get(struct dpif *dpif,
> uint32_t bond_id,
> uint64_t *n_bytes)
> {
> struct dp_netdev *dp = get_dp_netdev(dpif);
> - struct dp_netdev_pmd_thread *pmd;
> - struct tx_bond *dp_bond_entry = NULL;
> - struct tx_bond *pmd_bond_entry = NULL;
> - uint32_t i;
>
> ovs_mutex_lock(&dp->bond_mutex);
>
> /* Find the bond and retrieve stats if present */
> - dp_bond_entry = tx_bond_lookup(&dp->bonds, bond_id);
> + struct tx_bond *dp_bond_entry = tx_bond_lookup(&dp->bonds, bond_id);
> if (dp_bond_entry) {
> /* Search the bond in all PMDs */
> + struct dp_netdev_pmd_thread *pmd;
> CMAP_FOR_EACH (pmd, node, &dp->poll_threads) {
> - uint64_t pmd_n_bytes;
> ovs_mutex_lock(&pmd->bond_mutex);
> - pmd_bond_entry = tx_bond_lookup(&pmd->bond_cache, bond_id);
> + struct tx_bond *pmd_bond_entry
> + = tx_bond_lookup(&pmd->bond_cache, bond_id);
> if (pmd_bond_entry) {
> /* Read bond stats. */
> - for (i = 0;i <= BOND_MASK; i++) {
> + for (int i = 0; i <= BOND_MASK; i++) {
> + uint64_t pmd_n_bytes;
> atomic_read_relaxed(
> &pmd_bond_entry->slave_buckets[i].n_bytes,
> &pmd_n_bytes);
> diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
> index c544684ec0c0..82e2149d2a79 100644
> --- a/lib/dpif-provider.h
> +++ b/lib/dpif-provider.h
> @@ -616,7 +616,8 @@ struct dpif_class {
> struct ofputil_meter_stats *, uint16_t n_bands);
>
> /* Adds a bond with 'bond_id' and the slave-map to 'dpif'. */
> - int (*bond_add)(struct dpif *dpif, uint32_t bond_id, uint32_t
> slave_map[]);
> + int (*bond_add)(struct dpif *dpif, uint32_t bond_id,
> + odp_port_t slave_map[]);
> /* Removes bond identified by 'bond_id' from 'dpif'. */
> int (*bond_del)(struct dpif *dpif, uint32_t bond_id);
> /* Reads bond stats from 'dpif'. */
> diff --git a/lib/dpif.c b/lib/dpif.c
> index 2411c2cbeb41..71a752dba7dd 100644
> --- a/lib/dpif.c
> +++ b/lib/dpif.c
> @@ -1990,7 +1990,7 @@ dpif_meter_del(struct dpif *dpif, ofproto_meter_id
> meter_id,
> }
>
> int
> -dpif_bond_add(struct dpif *dpif, uint32_t bond_id, uint32_t slave_map[])
> +dpif_bond_add(struct dpif *dpif, uint32_t bond_id, odp_port_t slave_map[])
> {
> int error = 0;
>
> @@ -2013,8 +2013,9 @@ dpif_bond_del(struct dpif *dpif, uint32_t bond_id)
> return error;
> }
>
> -int dpif_bond_stats_get(struct dpif *dpif, uint32_t bond_id,
> - uint64_t *n_bytes)
> +int
> +dpif_bond_stats_get(struct dpif *dpif, uint32_t bond_id,
> + uint64_t *n_bytes)
> {
> int error = 0;
>
> diff --git a/lib/dpif.h b/lib/dpif.h
> index 82b1901697a3..6907bf19925d 100644
> --- a/lib/dpif.h
> +++ b/lib/dpif.h
> @@ -907,7 +907,7 @@ bool dpif_supports_tnl_push_pop(const struct dpif *);
>
> bool dpif_supports_balance_tcp_opt(const struct dpif *);
>
> -int dpif_bond_add(struct dpif *dpif, uint32_t bond_id, uint32_t slave_map[]);
> +int dpif_bond_add(struct dpif *dpif, uint32_t bond_id, odp_port_t
> slave_map[]);
> int dpif_bond_del(struct dpif *dpif, uint32_t bond_id);
> int dpif_bond_stats_get(struct dpif *dpif, uint32_t bond_id,
> uint64_t *n_bytes);
> diff --git a/ofproto/bond.c b/ofproto/bond.c
> index df9110e92d18..59fc5c9c43b3 100644
> --- a/ofproto/bond.c
> +++ b/ofproto/bond.c
> @@ -335,7 +335,7 @@ update_recirc_rules__(struct bond *bond, uint32_t
> bond_recirc_id)
> uint64_t ofpacts_stub[128 / 8];
> struct ofpbuf ofpacts;
> int i;
> - uint32_t slave_map[BOND_MASK];
> + ofp_port_t slave_map[BOND_MASK];
>
> ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
>
> @@ -356,7 +356,7 @@ update_recirc_rules__(struct bond *bond, uint32_t
> bond_recirc_id)
> &bond->hash[i].pr_rule);
> slave_map[i] = slave->ofp_port;
> } else {
> - slave_map[i] = -1;
> + slave_map[i] = OFP_PORT_C(-1);
> }
> }
> ofproto_dpif_bundle_add(bond->ofproto, bond->recirc_id, slave_map);
> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
> index 13789ac35225..5c1d0b981e06 100644
> --- a/ofproto/ofproto-dpif-xlate.c
> +++ b/ofproto/ofproto-dpif-xlate.c
> @@ -4203,9 +4203,8 @@ compose_output_action__(struct xlate_ctx *ctx,
> ofp_port_t ofp_port,
> *
> * Currently support for netdev datapath only.
> */
> - nl_msg_put_odp_port(ctx->odp_actions,
> - OVS_ACTION_ATTR_LB_OUTPUT,
> - xr->recirc_id);
> + nl_msg_put_u32(ctx->odp_actions, OVS_ACTION_ATTR_LB_OUTPUT,
> + xr->recirc_id);
> } else {
> act_hash = nl_msg_put_unspec_uninit(ctx->odp_actions,
> OVS_ACTION_ATTR_HASH,
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index 5f9f1889bc32..1ccebcab4438 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -3441,32 +3441,23 @@ bundle_remove(struct ofport *port_)
>
> int
> ofproto_dpif_bundle_add(struct ofproto_dpif *ofproto,
> - uint32_t bond_id,
> - uint32_t slave_map[])
> + uint32_t bond_id, const ofp_port_t slave_map[])
> {
> - int error;
> - uint32_t bucket;
> -
> /* Convert ofp_port to odp_port */
> - for (bucket = 0; bucket < BOND_BUCKETS; bucket++) {
> - if (slave_map[bucket] != -1) {
> - slave_map[bucket] =
> - ofp_port_to_odp_port(ofproto, slave_map[bucket]);
> - }
> + odp_port_t odp_map[BOND_BUCKETS];
> + for (int bucket = 0; bucket < BOND_BUCKETS; bucket++) {
> + odp_map[bucket] = (slave_map[bucket] == OFP_PORT_C(-1)
> + ? ODP_PORT_C(-1)
> + : ofp_port_to_odp_port(ofproto,
> slave_map[bucket]));
> }
>
> - error = dpif_bond_add(ofproto->backer->dpif, bond_id, slave_map);
> - return error;
> + return dpif_bond_add(ofproto->backer->dpif, bond_id, odp_map);
> }
>
> int
> -ofproto_dpif_bundle_del(struct ofproto_dpif *ofproto,
> - uint32_t bond_id)
> +ofproto_dpif_bundle_del(struct ofproto_dpif *ofproto, uint32_t bond_id)
> {
> - int error;
> -
> - error = dpif_bond_del(ofproto->backer->dpif, bond_id);
> - return error;
> + return dpif_bond_del(ofproto->backer->dpif, bond_id);
> }
>
> static void
> diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h
> index 484a6d4b5272..aa46d9d67fe2 100644
> --- a/ofproto/ofproto-dpif.h
> +++ b/ofproto/ofproto-dpif.h
> @@ -378,11 +378,9 @@ int ofproto_dpif_add_internal_flow(struct ofproto_dpif *,
> struct rule **rulep);
> int ofproto_dpif_delete_internal_flow(struct ofproto_dpif *, struct match *,
> int priority);
> -int ofproto_dpif_bundle_add(struct ofproto_dpif *,
> - uint32_t bond_id,
> - uint32_t slave_map[]);
> -int ofproto_dpif_bundle_del(struct ofproto_dpif *,
> - uint32_t bond_id);
> +int ofproto_dpif_bundle_add(struct ofproto_dpif *, uint32_t bond_id,
> + const ofp_port_t slave_map[]);
> +int ofproto_dpif_bundle_del(struct ofproto_dpif *, uint32_t bond_id);
>
> bool ovs_native_tunneling_is_on(struct ofproto_dpif *);
>
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev