Introduce new functions: * bond_should_account() determines whether statistics should be accounted for this bond. * bond_account_by_hash() allows accounting stats by a pre-computed hash, rather than by re-hashing the flow.
bond_hash() is also exported in this patch, but should only be used if bond_should_account() returns true. These changes will be used in a future patch to account bond statistics more cheaply. Signed-off-by: Joe Stringer <joestrin...@nicira.com> --- ofproto/bond.c | 34 ++++++++++++++++++++++++++++++++-- ofproto/bond.h | 4 ++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/ofproto/bond.c b/ofproto/bond.c index c4cfa45..3816480 100644 --- a/ofproto/bond.c +++ b/ofproto/bond.c @@ -136,6 +136,9 @@ static struct bond_entry *lookup_bond_entry(const struct bond *, const struct flow *, uint16_t vlan) OVS_REQ_RDLOCK(rwlock); +static struct bond_entry *lookup_bond_entry_by_hash(const struct bond *, + unsigned int hash) + OVS_REQ_RDLOCK(rwlock); static struct bond_slave *get_enabled_slave(struct bond *) OVS_REQ_RDLOCK(rwlock); static struct bond_slave *choose_output_slave(const struct bond *, @@ -698,6 +701,17 @@ bond_is_balanced(const struct bond *bond) OVS_REQ_RDLOCK(rwlock) && (bond->balance == BM_SLB || bond->balance == BM_TCP); } +bool +bond_should_account(struct bond *bond) +{ + bool ok; + + ovs_rwlock_rdlock(&rwlock); + ok = bond_is_balanced(bond); + ovs_rwlock_unlock(&rwlock); + return ok; +} + /* Notifies 'bond' that 'n_bytes' bytes were sent in 'flow' within 'vlan'. */ void bond_account(struct bond *bond, const struct flow *flow, uint16_t vlan, @@ -710,6 +724,16 @@ bond_account(struct bond *bond, const struct flow *flow, uint16_t vlan, ovs_rwlock_unlock(&rwlock); } +void +bond_account_by_hash(struct bond *bond, unsigned int hash, uint64_t n_bytes) +{ + ovs_rwlock_wrlock(&rwlock); + if (bond_is_balanced(bond)) { + lookup_bond_entry_by_hash(bond, hash)->tx_bytes += n_bytes; + } + ovs_rwlock_unlock(&rwlock); +} + static struct bond_slave * bond_slave_from_bal_node(struct list *bal) OVS_REQ_RDLOCK(rwlock) { @@ -1420,7 +1444,7 @@ bond_hash_tcp(const struct flow *flow, uint16_t vlan, uint32_t basis) return flow_hash_symmetric_l4(&hash_flow, basis); } -static unsigned int +unsigned int bond_hash(const struct bond *bond, const struct flow *flow, uint16_t vlan) { ovs_assert(bond->balance == BM_TCP || bond->balance == BM_SLB); @@ -1431,10 +1455,16 @@ bond_hash(const struct bond *bond, const struct flow *flow, uint16_t vlan) } static struct bond_entry * +lookup_bond_entry_by_hash(const struct bond *bond, unsigned int hash) +{ + return &bond->hash[hash & BOND_MASK]; +} + +static struct bond_entry * lookup_bond_entry(const struct bond *bond, const struct flow *flow, uint16_t vlan) { - return &bond->hash[bond_hash(bond, flow, vlan) & BOND_MASK]; + return lookup_bond_entry_by_hash(bond, bond_hash(bond, flow, vlan)); } /* Selects and returns an enabled slave from the 'enabled_slaves' list diff --git a/ofproto/bond.h b/ofproto/bond.h index 5b3814e..95eafb8 100644 --- a/ofproto/bond.h +++ b/ofproto/bond.h @@ -92,8 +92,12 @@ void *bond_choose_output_slave(struct bond *, const struct flow *, struct flow_wildcards *, uint16_t vlan); /* Rebalancing. */ +unsigned int bond_hash(const struct bond *bond, const struct flow *flow, + uint16_t vlan); +bool bond_should_account(struct bond *bond); void bond_account(struct bond *, const struct flow *, uint16_t vlan, uint64_t n_bytes); +void bond_account_by_hash(struct bond *, unsigned int hash, uint64_t n_bytes); void bond_rebalance(struct bond *); #endif /* bond.h */ -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev