2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-23 14:57:06 +00:00

flow: Add struct flowmap.

Struct miniflow is now sometimes used just as a map.  Define a new
struct flowmap for that purpose.  The flowmap is defined as an array of
maps, and it is automatically sized according to the size of struct
flow, so it will be easier to maintain in the future.

It would have been tempting to use the existing struct bitmap for this
purpose. The main reason this is not feasible at the moment is that
some flowmap algorithms are simpler when it can be assumed that no
struct flow member requires more bits than can fit to a single map
unit. The tunnel member already requires more than 32 bits, so the map
unit needs to be 64 bits wide.

Performance critical algorithms enumerate the flowmap array units
explicitly, as it is easier for the compiler to optimize, compared to
the normal iterator.  Without this optimization a classifier lookup
without wildcard masks would be about 25% slower.

With this more general (and maintainable) algorithm the classifier
lookups are about 5% slower, when the struct flow actually becomes big
enough to require a second map.  This negates the performance gained
in the "Pre-compute stage masks" patch earlier in the series.

Requested-by: Ben Pfaff <blp@nicira.com>
Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Jarno Rajahalme
2015-08-25 13:55:03 -07:00
parent fa2fdbf8d0
commit 5fcff47b0b
7 changed files with 677 additions and 629 deletions

View File

@@ -1256,13 +1256,12 @@ bool
minimatch_matches_flow(const struct minimatch *match,
const struct flow *target)
{
const uint64_t *target_u64 = (const uint64_t *) target;
const uint64_t *flowp = miniflow_get_values(match->flow);
const uint64_t *maskp = miniflow_get_values(&match->mask->masks);
size_t idx;
MAPS_FOR_EACH_INDEX(idx, *match->flow) {
if ((*flowp++ ^ target_u64[idx]) & *maskp++) {
FLOWMAP_FOR_EACH_INDEX(idx, match->flow->map) {
if ((*flowp++ ^ flow_u64_value(target, idx)) & *maskp++) {
return false;
}
}