Skip to content

Commit

Permalink
ofproto-dpif: Improve load balancing in dp_hash select groups.
Browse files Browse the repository at this point in the history
Here is some data:

  coeff.  :   1         2         3         4         5        100
  -------------------------------------------------------------------
  AvgDiff : 43.1 %    27.1 %    18.3 %    15.1 %    13.6 %    10.9 %
  MaxDiff : 50.0 %    33.3 %    25.0 %    20.0 %    20.0 %    20.0 %
  AvgDev  : 24.9 %    13.4 %     8.5 %     6.9 %     6.1 %     4.8 %
  MaxDev  : 35.4 %    20.4 %    14.4 %    11.2 %    11.2 %    11.2 %
  --------+----------------------------------------------------------
    16    :   1         1         1         1         1         -
    32    :  17         9         6         5         4         -
    64    :  33        17        11         9         7         -
   128    :  65        33        22        17        13         1
   256    : 129        65        43        33        26         2
  --------+----------------------------------------------------------
           current                       proposed

Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
  • Loading branch information
igsilya committed Sep 19, 2024
1 parent b620116 commit 3b67664
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 2 deletions.
6 changes: 4 additions & 2 deletions ofproto/ofproto-dpif.c
Original file line number Diff line number Diff line change
Expand Up @@ -5341,8 +5341,10 @@ group_setup_dp_hash_table(struct group_dpif *group, size_t max_hash)
min_weight, total_weight);

uint64_t min_slots = DIV_ROUND_UP(total_weight, min_weight);
uint64_t min_slots2 = ROUND_UP_POW2(min_slots);
uint64_t n_hash = MAX(16, min_slots2);
uint64_t min_slots2 =
MAX(min_slots, MIN(n_buckets * 4, MAX_SELECT_GROUP_HASH_VALUES));
uint64_t min_slots3 = ROUND_UP_POW2(min_slots2);
uint64_t n_hash = MAX(16, min_slots3);
if (n_hash > MAX_SELECT_GROUP_HASH_VALUES ||
(max_hash != 0 && n_hash > max_hash)) {
VLOG_DBG(" Too many hash values required: %"PRIu64, n_hash);
Expand Down
54 changes: 54 additions & 0 deletions tests/ofproto-dpif.at
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,60 @@ bucket3 >= 500
OVS_VSWITCHD_STOP
AT_CLEANUP

AT_SETUP([ofproto-dpif - select group with dp_hash and equal weights])

OVS_VSWITCHD_START
add_of_ports br0 1 10

ovs-appctl vlog/set ofproto_dpif:file:dbg vconn:file:info

AT_DATA([stddev.awk], [
{
# $1 (target) is a mean value, because all weights are the same.
# $2 (hits) is an actual number of hashes assigned to this bucket.
n_hashes += $2
n_buckets++
sum_sq_diff += ($2 - $1) * ($2 - $1)
}
END {
mean = n_hashes / n_buckets
stddev = sqrt(sum_sq_diff / n_buckets)
stddevp = stddev * 100 / mean

print "hashes:", n_hashes, "buckets:", n_buckets
print "mean:", mean, "stddev:", stddev, "(", stddevp, "% )"

# Make sure that standard deviation of load between buckets is below 12.5%.
# Note: it's not a strict requirement, but a good number that passes tests.
if (stddevp <= 12.5) { print "PASS" }
else { print "FAIL" }
}
])

m4_define([CHECK_DISTRIBUTION], [
AT_CHECK([tail -n $1 ovs-vswitchd.log | grep 'ofproto_dpif|DBG|.*Bucket' \
| sed 's/.*target=\([[0-9\.]]*\) hits=\([[0-9]]*\)/\1 \2/' \
| awk -f stddev.awk], [0], [stdout])
AT_CHECK([grep -q "buckets: $2" stdout])
AT_CHECK([grep -q 'PASS' stdout])
])

m4_define([OF_GROUP], [group_id=$1,type=select,selection_method=dp_hash])
m4_define([OFG_BUCKET], [bucket=weight=$1,output:10])

dnl Test load distribution in groups with up to 64 equally weighted buckets.
m4_define([OFG_BUCKETS], [OFG_BUCKET(100)])
m4_for([id], [1], [64], [1], [
get_log_next_line_num
AT_CHECK([ovs-ofctl -O OpenFlow15 add-group br0 \
"OF_GROUP(id),OFG_BUCKETS()"])
CHECK_DISTRIBUTION([+$LINENUM], [id])
m4_append([OFG_BUCKETS], [,OFG_BUCKET(100)])
])

OVS_VSWITCHD_STOP
AT_CLEANUP

AT_SETUP([ofproto-dpif - select group with explicit dp_hash selection method])

OVS_VSWITCHD_START
Expand Down

0 comments on commit 3b67664

Please sign in to comment.