2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 22:35:15 +00:00

lib/classifier: Support variable sized miniflows.

Change the classifier to allocate variable sized miniflows and
minimasks in cls_match and cls_subtable, respectively.  Do not
duplicate the mask in cls_rule any more.

miniflow_clone and miniflow_move can now take variably sized miniflows
as source.  The destination is assumed to be regularly sized miniflow.

Inlining miniflow and mask values reduces memory indirection and helps
reduce cache misses.

Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: Ethan Jackson <ethan@nicira.com>
This commit is contained in:
Jarno Rajahalme
2014-04-29 15:50:39 -07:00
parent 27bbe15dec
commit 3016f3e4a8
3 changed files with 134 additions and 33 deletions

View File

@@ -358,14 +358,18 @@ struct miniflow {
};
};
#define MINIFLOW_VALUES_SIZE(COUNT) ((COUNT) * sizeof(uint32_t))
static inline uint32_t *miniflow_values(struct miniflow *mf)
{
return mf->values_inline ? mf->inline_values : mf->offline_values;
return OVS_LIKELY(mf->values_inline)
? mf->inline_values : mf->offline_values;
}
static inline const uint32_t *miniflow_get_values(const struct miniflow *mf)
{
return mf->values_inline ? mf->inline_values : mf->offline_values;
return OVS_LIKELY(mf->values_inline)
? mf->inline_values : mf->offline_values;
}
static inline const uint32_t *miniflow_get_u32_values(const struct miniflow *mf)
@@ -400,11 +404,31 @@ void miniflow_init(struct miniflow *, const struct flow *);
void miniflow_init_with_minimask(struct miniflow *, const struct flow *,
const struct minimask *);
void miniflow_clone(struct miniflow *, const struct miniflow *);
void miniflow_clone_inline(struct miniflow *, const struct miniflow *,
size_t n_values);
void miniflow_move(struct miniflow *dst, struct miniflow *);
void miniflow_destroy(struct miniflow *);
void miniflow_expand(const struct miniflow *, struct flow *);
static inline uint32_t
flow_get_next_in_map(const struct flow *flow, uint64_t map, uint32_t *value)
{
if (map) {
*value = ((const uint32_t *)flow)[raw_ctz(map)];
return true;
}
return false;
}
/* Iterate through all flow u32 values specified by 'MAP'.
* This works as the first statement in a block.*/
#define FLOW_FOR_EACH_IN_MAP(VALUE, FLOW, MAP) \
uint64_t map_; \
for (map_ = (MAP); \
flow_get_next_in_map(FLOW, map_, &(VALUE)); \
map_ = zero_rightmost_1bit(map_))
#define FLOW_U32_SIZE(FIELD) \
DIV_ROUND_UP(sizeof(((struct flow *)0)->FIELD), sizeof(uint32_t))
@@ -429,7 +453,7 @@ mf_get_next_in_map(uint64_t *fmap, uint64_t rm1bit, const uint32_t **fp,
return rm1bit != 0;
}
/* Iterate through all miniflow u32 values specified by the 'MAP'.
/* Iterate through all miniflow u32 values specified by 'MAP'.
* This works as the first statement in a block.*/
#define MINIFLOW_FOR_EACH_IN_MAP(VALUE, FLOW, MAP) \
const uint32_t *fp_ = miniflow_get_u32_values(FLOW); \