[ovs-dev] [PATCH] vswitchd: Make the bond rebalancing interval user-configurable.

Ben Pfaff blp at nicira.com
Mon Apr 5 23:44:28 UTC 2010


Thanks, I pushed this one out too.

On Mon, Apr 05, 2010 at 04:37:17PM -0700, Justin Pettit wrote:
> Looks good.
> 
> --Justin
> 
> 
> On Apr 5, 2010, at 2:21 PM, Ben Pfaff wrote:
> 
> > This may make some bond debugging problems easier.  It also seems
> > reasonable to expose this parameter to the user.
> > 
> > Related to bug #2366.
> > ---
> > vswitchd/bridge.c    |   58 +++++++++++++++++++++++++++++++++++++-------------
> > vswitchd/vswitch.xml |    7 ++++++
> > 2 files changed, 50 insertions(+), 15 deletions(-)
> > 
> > diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
> > index 130e094..7986168 100644
> > --- a/vswitchd/bridge.c
> > +++ b/vswitchd/bridge.c
> > @@ -137,6 +137,8 @@ struct port {
> >     int updelay, downdelay;     /* Delay before iface goes up/down, in ms. */
> >     bool bond_compat_is_stale;  /* Need to call port_update_bond_compat()? */
> >     bool bond_fake_iface;       /* Fake a bond interface for legacy compat? */
> > +    int bond_rebalance_interval; /* Interval between rebalances, in ms. */
> > +    long long int bond_next_rebalance; /* Next rebalancing time. */
> > 
> >     /* Port mirroring info. */
> >     mirror_mask_t src_mirrors;  /* Mirrors triggered when packet received. */
> > @@ -180,7 +182,6 @@ struct bridge {
> > 
> >     /* Bonding. */
> >     bool has_bonded_ports;
> > -    long long int bond_next_rebalance;
> > 
> >     /* Flow tracking. */
> >     bool flush;
> > @@ -807,18 +808,27 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
> > }
> > 
> > static const char *
> > -bridge_get_other_config(const struct ovsrec_bridge *br_cfg, const char *key)
> > +get_ovsrec_key_value(const char *key, char **keys, char **values, size_t n)
> > {
> >     size_t i;
> > 
> > -    for (i = 0; i < br_cfg->n_other_config; i++) {
> > -        if (!strcmp(br_cfg->key_other_config[i], key)) {
> > -            return br_cfg->value_other_config[i];
> > +    for (i = 0; i < n; i++) {
> > +        if (!strcmp(keys[i], key)) {
> > +            return values[i];
> >         }
> >     }
> >     return NULL;
> > }
> > 
> > +static const char *
> > +bridge_get_other_config(const struct ovsrec_bridge *br_cfg, const char *key)
> > +{
> > +    return get_ovsrec_key_value(key,
> > +                                br_cfg->key_other_config,
> > +                                br_cfg->value_other_config,
> > +                                br_cfg->n_other_config);
> > +}
> > +
> > static void
> > bridge_pick_local_hw_addr(struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
> >                           struct iface **hw_addr_iface)
> > @@ -1145,7 +1155,6 @@ bridge_create(const struct ovsrec_bridge *br_cfg)
> >     port_array_init(&br->ifaces);
> > 
> >     br->flush = false;
> > -    br->bond_next_rebalance = time_msec() + 10000;
> > 
> >     list_push_back(&all_bridges, &br->node);
> > 
> > @@ -2365,22 +2374,18 @@ static void
> > bridge_account_checkpoint_ofhook_cb(void *br_)
> > {
> >     struct bridge *br = br_;
> > +    long long int now;
> >     size_t i;
> > 
> >     if (!br->has_bonded_ports) {
> >         return;
> >     }
> > 
> > -    /* The current ofproto implementation calls this callback at least once a
> > -     * second, so this timer implementation is sufficient. */
> > -    if (time_msec() < br->bond_next_rebalance) {
> > -        return;
> > -    }
> > -    br->bond_next_rebalance = time_msec() + 10000;
> > -
> > +    now = time_msec();
> >     for (i = 0; i < br->n_ports; i++) {
> >         struct port *port = br->ports[i];
> > -        if (port->n_ifaces > 1) {
> > +        if (port->n_ifaces > 1 && now >= port->bond_next_rebalance) {
> > +            port->bond_next_rebalance = now + port->bond_rebalance_interval;
> >             bond_rebalance_port(port);
> >         }
> >     }
> > @@ -2827,7 +2832,7 @@ bond_unixctl_show(struct unixctl_conn *conn,
> >     ds_put_format(&ds, "updelay: %d ms\n", port->updelay);
> >     ds_put_format(&ds, "downdelay: %d ms\n", port->downdelay);
> >     ds_put_format(&ds, "next rebalance: %lld ms\n",
> > -                  port->bridge->bond_next_rebalance - time_msec());
> > +                  port->bond_next_rebalance - time_msec());
> >     for (j = 0; j < port->n_ifaces; j++) {
> >         const struct iface *iface = port->ifaces[j];
> >         struct bond_entry *be;
> > @@ -3090,10 +3095,22 @@ port_create(struct bridge *br, const char *name)
> >     return port;
> > }
> > 
> > +static const char *
> > +get_port_other_config(const struct ovsrec_port *port, const char *key,
> > +                      const char *default_value)
> > +{
> > +    const char *value = get_ovsrec_key_value(key,
> > +                                             port->key_other_config,
> > +                                             port->value_other_config,
> > +                                             port->n_other_config);
> > +    return value ? value : default_value;
> > +}
> > +
> > static void
> > port_reconfigure(struct port *port, const struct ovsrec_port *cfg)
> > {
> >     struct shash old_ifaces, new_ifaces;
> > +    long long int next_rebalance;
> >     struct shash_node *node;
> >     unsigned long *trunks;
> >     int vlan;
> > @@ -3122,6 +3139,15 @@ port_reconfigure(struct port *port, const struct ovsrec_port *cfg)
> >     if (port->downdelay < 0) {
> >         port->downdelay = 0;
> >     }
> > +    port->bond_rebalance_interval = atoi(
> > +        get_port_other_config(cfg, "bond-rebalance-interval", "10000"));
> > +    if (port->bond_rebalance_interval < 1000) {
> > +        port->bond_rebalance_interval = 1000;
> > +    }
> > +    next_rebalance = time_msec() + port->bond_rebalance_interval;
> > +    if (port->bond_next_rebalance > next_rebalance) {
> > +        port->bond_next_rebalance = next_rebalance;
> > +    }
> > 
> >     /* Get rid of deleted interfaces and add new interfaces. */
> >     SHASH_FOR_EACH (node, &old_ifaces) {
> > @@ -3299,6 +3325,8 @@ port_update_bonding(struct port *port)
> >             }
> >             port->no_ifaces_tag = tag_create_random();
> >             bond_choose_active_iface(port);
> > +            port->bond_next_rebalance
> > +                = time_msec() + port->bond_rebalance_interval;
> >         }
> >         port->bond_compat_is_stale = true;
> >         port->bond_fake_iface = port->cfg->bond_fake_iface;
> > diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
> > index e6ad387..e0f7d82 100644
> > --- a/vswitchd/vswitch.xml
> > +++ b/vswitchd/vswitch.xml
> > @@ -278,6 +278,13 @@
> >           <dt><code>hwaddr</code></dt>
> >           <dd>An Ethernet address in the form
> >             <code><var>xx</var>:<var>xx</var>:<var>xx</var>:<var>xx</var>:<var>xx</var>:<var>xx</var></code>.</dd>
> > +          <dt><code>bond-rebalance-interval</code></dt>
> > +          <dd>For a bonded port, the number of milliseconds between
> > +            successive attempts to rebalance the bond, that is, to
> > +            move source MACs and their flows from one interface on
> > +            the bond to another in an attempt to keep usage of each
> > +            interface roughly equal.  The default is 10000 (10
> > +            seconds), and the minimum is 1000 (1 second).</dd>
> >         </dl>
> >       </column>
> >     </group>
> > -- 
> > 1.6.6.1
> > 
> > 
> > _______________________________________________
> > dev mailing list
> > dev at openvswitch.org
> > http://openvswitch.org/mailman/listinfo/dev_openvswitch.org
> 




More information about the dev mailing list