On Thu, Jul 28, 2016 at 05:55:57PM -0700, Jarno Rajahalme wrote: > Adding groups support for bundles is simpler if also groups are > modified under ofproto_mutex. > > Eliminate the search for rules when deleting a group so that we will > not keep the mutex for too long. > > Signed-off-by: Jarno Rajahalme <ja...@ovn.org>
It's confusing that rule_collection_remove() and rule_collection_remove_postponed() have unrelated effects. In rule_collection_remove(), regarding the comment below, I think that the comparison is to ensure hysteresis, not to avoid it, e.g. we want the kind of behavior described at https://en.wikipedia.org/wiki/Hysteresis#Control_systems: /* Shrink? Watermark at '/ 4' to avoid hysteresis, but leave spare * capacity. */ This adds an OVS_EXCLUDED annotation to ofproto_group_delete_all(), which is a non-static function, so it should also add the annotation to its prototype in ofproto-provider.h. There might be other functions in the same boat, didn't notice. (This also applies to static functions if there's a prototype at the top of the .c file; Clang is not smart enough to merge all the annotations and so you miss warnings if you don't annotate every prototype and definition.) Here's an incremental to make OFPACT_FOR_EACH_TYPE(_FLATTENED) more type-safe: diff --git a/include/openvswitch/ofp-actions.h b/include/openvswitch/ofp-actions.h index 6355eed..42764b1 100644 --- a/include/openvswitch/ofp-actions.h +++ b/include/openvswitch/ofp-actions.h @@ -227,6 +227,9 @@ ofpact_find_type(const struct ofpact *a, enum ofpact_type type, return NULL; } +#define OFPACT_FIND_TYPE(A, TYPE, END) \ + ofpact_get_##TYPE##_nullable(ofpact_find_type(A, OFPACT_##TYPE, END)) + static inline const struct ofpact * ofpact_find_type_flattened(const struct ofpact *a, enum ofpact_type type, const struct ofpact * const end) @@ -240,6 +243,10 @@ ofpact_find_type_flattened(const struct ofpact *a, enum ofpact_type type, return NULL; } +#define OFPACT_FIND_TYPE_FLATTENED(A, TYPE, END) \ + ofpact_get_##TYPE##_nullable( \ + ofpact_find_type_flattened(A, OFPACT_##TYPE, END)) + /* Assigns POS to each ofpact, in turn, in the OFPACTS_LEN bytes of ofpacts * starting at OFPACTS. */ #define OFPACT_FOR_EACH(POS, OFPACTS, OFPACTS_LEN) \ @@ -247,10 +254,10 @@ ofpact_find_type_flattened(const struct ofpact *a, enum ofpact_type type, (POS) = ofpact_next(POS)) #define OFPACT_FOR_EACH_TYPE(POS, TYPE, OFPACTS, OFPACTS_LEN) \ - for ((POS) = ofpact_find_type(OFPACTS, TYPE, \ + for ((POS) = OFPACT_FIND_TYPE(OFPACTS, TYPE, \ ofpact_end(OFPACTS, OFPACTS_LEN)); \ (POS); \ - (POS) = ofpact_find_type(ofpact_next(POS), TYPE, \ + (POS) = OFPACT_FIND_TYPE(ofpact_next(&(POS)->ofpact), TYPE, \ ofpact_end(OFPACTS, OFPACTS_LEN))) /* Assigns POS to each ofpact, in turn, in the OFPACTS_LEN bytes of ofpacts @@ -263,11 +270,12 @@ ofpact_find_type_flattened(const struct ofpact *a, enum ofpact_type type, (POS) = ofpact_next_flattened(POS)) #define OFPACT_FOR_EACH_TYPE_FLATTENED(POS, TYPE, OFPACTS, OFPACTS_LEN) \ - for ((POS) = ofpact_find_type_flattened(OFPACTS, TYPE, \ + for ((POS) = OFPACT_FIND_TYPE_FLATTENED(OFPACTS, TYPE, \ ofpact_end(OFPACTS, OFPACTS_LEN)); \ (POS); \ - (POS) = ofpact_find_type_flattened(ofpact_next_flattened(POS), TYPE, \ - ofpact_end(OFPACTS, OFPACTS_LEN))) + (POS) = OFPACT_FIND_TYPE_FLATTENED( \ + ofpact_next_flattened(&(POS)->ofpact), TYPE, \ + ofpact_end(OFPACTS, OFPACTS_LEN))) /* Action structure for each OFPACT_*. */ @@ -1017,6 +1025,13 @@ void *ofpact_finish(struct ofpbuf *, struct ofpact *); } \ \ static inline struct STRUCT * \ + ofpact_get_##ENUM##_nullable(const struct ofpact *ofpact) \ + { \ + ovs_assert(!ofpact || ofpact->type == OFPACT_##ENUM); \ + return ALIGNED_CAST(struct STRUCT *, ofpact); \ + } \ + \ + static inline struct STRUCT * \ ofpact_put_##ENUM(struct ofpbuf *ofpacts) \ { \ return ofpact_put(ofpacts, OFPACT_##ENUM, \ diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 7542fc3..e7fd6bb 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -3445,7 +3445,6 @@ enum ofperr ofproto_check_ofpacts(struct ofproto *ofproto, const struct ofpact ofpacts[], size_t ofpacts_len) { - const struct ofpact *a; uint32_t mid; mid = ofpacts_get_meter(ofpacts, ofpacts_len); @@ -3453,9 +3452,9 @@ ofproto_check_ofpacts(struct ofproto *ofproto, return OFPERR_OFPMMFC_INVALID_METER; } - OFPACT_FOR_EACH_TYPE_FLATTENED (a, OFPACT_GROUP, ofpacts, ofpacts_len) { - if (!ofproto_group_exists(ofproto, - ofpact_get_GROUP(a)->group_id)) { + const struct ofpact_group *a; + OFPACT_FOR_EACH_TYPE_FLATTENED (a, GROUP, ofpacts, ofpacts_len) { + if (!ofproto_group_exists(ofproto, a->group_id)) { return OFPERR_OFPBAC_BAD_OUT_GROUP; } } @@ -8022,14 +8021,12 @@ ofproto_rule_insert__(struct ofproto *ofproto, struct rule *rule) meter_insert_rule(rule); } if (actions->has_groups) { - const struct ofpact *a; - - OFPACT_FOR_EACH_TYPE_FLATTENED (a, OFPACT_GROUP, actions->ofpacts, + const struct ofpact_group *a; + OFPACT_FOR_EACH_TYPE_FLATTENED (a, GROUP, actions->ofpacts, actions->ofpacts_len) { struct ofgroup *group; - group = ofproto_group_lookup(ofproto, - ofpact_get_GROUP(a)->group_id, false); + group = ofproto_group_lookup(ofproto, a->group_id, false); ovs_assert(group != NULL); group_add_rule(group, rule); } @@ -8062,14 +8059,13 @@ ofproto_rule_remove__(struct ofproto *ofproto, struct rule *rule) const struct rule_actions *actions = rule_get_actions(rule); if (actions->has_groups) { - const struct ofpact *a; + const struct ofpact_group *a; - OFPACT_FOR_EACH_TYPE_FLATTENED (a, OFPACT_GROUP, actions->ofpacts, + OFPACT_FOR_EACH_TYPE (a, GROUP, actions->ofpacts, actions->ofpacts_len) { struct ofgroup *group; - group = ofproto_group_lookup(ofproto, - ofpact_get_GROUP(a)->group_id, false); + group = ofproto_group_lookup(ofproto, a->group_id, false); ovs_assert(group); /* Leave the rule for the group that is being deleted, if any, _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev