X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fbond.c;h=c1a84482af80c6a73fb354b5b2278e42b9e86b53;hb=2f486d4c80dada4194b170ebed0bcf77454b5404;hp=c0f79c99241641ee4a26abb42855f4a0127fe1ec;hpb=f6ba1f355075900221ffbfba127a75e540841bc5;p=sliver-openvswitch.git diff --git a/ofproto/bond.c b/ofproto/bond.c index c0f79c992..c1a84482a 100644 --- a/ofproto/bond.c +++ b/ofproto/bond.c @@ -151,7 +151,7 @@ struct bond_pr_rule_op { struct match match; ofp_port_t out_ofport; enum bond_op op; - struct rule *pr_rule; + struct rule **pr_rule; }; static void bond_entry_reset(struct bond *) OVS_REQ_WRLOCK(rwlock); @@ -292,7 +292,7 @@ bond_unref(struct bond *bond) static void add_pr_rule(struct bond *bond, const struct match *match, - ofp_port_t out_ofport, struct rule *rule) + ofp_port_t out_ofport, struct rule **rule) { uint32_t hash = match_hash(match, 0); struct bond_pr_rule_op *pr_op; @@ -329,28 +329,23 @@ update_recirc_rules(struct bond *bond) pr_op->op = DEL; } - if ((bond->hash == NULL) || (!bond->recirc_id)) { - return; - } + if (bond->hash && bond->recirc_id) { + for (i = 0; i < BOND_BUCKETS; i++) { + struct bond_slave *slave = bond->hash[i].slave; - for (i = 0; i < BOND_BUCKETS; i++) { - struct bond_slave *slave = bond->hash[i].slave; + if (slave) { + match_init_catchall(&match); + match_set_recirc_id(&match, bond->recirc_id); + match_set_dp_hash_masked(&match, i, BOND_MASK); - if (slave) { - match_init_catchall(&match); - match_set_recirc_id(&match, bond->recirc_id); - /* recirc_id -> metadata to speed up look ups. */ - match_set_metadata(&match, htonll(bond->recirc_id)); - match_set_dp_hash_masked(&match, i, BOND_MASK); - - add_pr_rule(bond, &match, slave->ofp_port, - bond->hash[i].pr_rule); + add_pr_rule(bond, &match, slave->ofp_port, + &bond->hash[i].pr_rule); + } } } HMAP_FOR_EACH_SAFE(pr_op, next_op, hmap_node, &bond->pr_rule_ops) { int error; - struct rule *rule; switch (pr_op->op) { case ADD: ofpbuf_clear(&ofpacts); @@ -358,16 +353,13 @@ update_recirc_rules(struct bond *bond) error = ofproto_dpif_add_internal_flow(bond->ofproto, &pr_op->match, RECIRC_RULE_PRIORITY, - &ofpacts, &rule); + &ofpacts, pr_op->pr_rule); if (error) { char *err_s = match_to_string(&pr_op->match, RECIRC_RULE_PRIORITY); VLOG_ERR("failed to add post recirculation flow %s", err_s); free(err_s); - pr_op->pr_rule = NULL; - } else { - pr_op->pr_rule = rule; } break; @@ -384,7 +376,7 @@ update_recirc_rules(struct bond *bond) } hmap_remove(&bond->pr_rule_ops, &pr_op->hmap_node); - pr_op->pr_rule = NULL; + *pr_op->pr_rule = NULL; free(pr_op); break; } @@ -869,7 +861,7 @@ bond_entry_account(struct bond_entry *entry, uint64_t rule_tx_bytes) } /* Maintain bond stats using post recirculation rule byte counters.*/ -void +static void bond_recirculation_account(struct bond *bond) { int i; @@ -896,7 +888,7 @@ bool bond_may_recirc(const struct bond *bond, uint32_t *recirc_id, uint32_t *hash_bias) { - if (bond->balance == BM_TCP) { + if (bond->balance == BM_TCP && recirc_id) { if (recirc_id) { *recirc_id = bond->recirc_id; } @@ -1095,15 +1087,15 @@ reinsert_bal(struct list *bals, struct bond_slave *slave) * The caller should have called bond_account() for each active flow, or in case * of recirculation is used, have called bond_recirculation_account(bond), * to ensure that flow data is consistently accounted at this point. - * - * Return whether rebalancing took place.*/ -bool + */ +void bond_rebalance(struct bond *bond) { struct bond_slave *slave; struct bond_entry *e; struct list bals; bool rebalanced = false; + bool use_recirc; ovs_rwlock_wrlock(&rwlock); if (!bond_is_balanced(bond) || time_msec() < bond->next_rebalance) { @@ -1111,6 +1103,13 @@ bond_rebalance(struct bond *bond) } bond->next_rebalance = time_msec() + bond->rebalance_interval; + use_recirc = ofproto_dpif_get_enable_recirc(bond->ofproto) && + bond_may_recirc(bond, NULL, NULL); + + if (use_recirc) { + bond_recirculation_account(bond); + } + /* Add each bond_entry to its slave's 'entries' list. * Compute each slave's tx_bytes as the sum of its entries' tx_bytes. */ HMAP_FOR_EACH (slave, hmap_node, &bond->slaves) { @@ -1166,7 +1165,7 @@ bond_rebalance(struct bond *bond) /* Re-sort 'bals'. */ reinsert_bal(&bals, from); reinsert_bal(&bals, to); - rebalanced = true; + rebalanced = true; } else { /* Can't usefully migrate anything away from 'from'. * Don't reconsider it. */ @@ -1179,14 +1178,14 @@ bond_rebalance(struct bond *bond) * take 20 rebalancing runs to decay to 0 and get deleted entirely. */ for (e = &bond->hash[0]; e <= &bond->hash[BOND_MASK]; e++) { e->tx_bytes /= 2; - if (!e->tx_bytes) { - e->slave = NULL; - } + } + + if (use_recirc && rebalanced) { + bond_update_post_recirc_rules(bond,true); } done: ovs_rwlock_unlock(&rwlock); - return rebalanced; } /* Bonding unixctl user interface functions. */