Signed-off-by: Ryan Wilson <wr...@nicira.com> --- v2: Fixed bug with group stats all buckets, cleaned up ofgroup unref code, added Andy Zhou's test for more complete test coverage v3: Split group reference count, support for group and bucket stats into 2 patches. Commit Andy Zhou's test patch separately. --- ofproto/ofproto-dpif.h | 16 ++++++++++++++++ ofproto/ofproto-provider.h | 8 ++++++++ ofproto/ofproto.c | 32 +++++++++++++++++++++++++++----- 3 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index e49616e..345117a 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -232,6 +232,22 @@ BUILD_ASSERT_DECL(N_TABLES >= 2 && N_TABLES <= 255); /* struct rule_dpif has struct rule as it's first member. */ #define RULE_CAST(RULE) ((struct rule *)RULE) +#define GROUP_CAST(GROUP) ((struct ofgroup *)GROUP) + +static inline struct group_dpif* group_dpif_ref(struct group_dpif *group) +{ + if (group) { + ofproto_group_ref(GROUP_CAST(group)); + } + return group; +} + +static inline void group_dpif_unref(struct group_dpif *group) +{ + if (group) { + ofproto_group_unref(GROUP_CAST(group)); + } +} static inline void rule_dpif_ref(struct rule_dpif *rule) { diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 141adec..209f6f9 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -488,6 +488,11 @@ struct ofgroup { uint32_t group_id; enum ofp11_group_type type; /* One of OFPGT_*. */ + /* Number of references. + * The classifier owns one reference. + * The xlate cache may also hold a reference. */ + struct ovs_refcount ref_count; + long long int created; /* Creation time. */ long long int modified; /* Time of last modification. */ @@ -502,6 +507,9 @@ bool ofproto_group_lookup(const struct ofproto *ofproto, uint32_t group_id, void ofproto_group_release(struct ofgroup *group) OVS_RELEASES(group->rwlock); +void ofproto_group_ref(struct ofgroup *); +void ofproto_group_unref(struct ofgroup *); + /* ofproto class structure, to be defined by each ofproto implementation. * * diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 9b26da7..b5a59f8 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -2647,6 +2647,31 @@ ofproto_rule_unref(struct rule *rule) } } +static void +group_destroy_cb(struct ofgroup *group) +{ + group->ofproto->ofproto_class->group_destruct(group); + ofputil_bucket_list_destroy(&group->buckets); + ovs_rwlock_destroy(&group->rwlock); + group->ofproto->ofproto_class->group_dealloc(group); +} + +void +ofproto_group_ref(struct ofgroup *group) +{ + if (group) { + ovs_refcount_ref(&group->ref_count); + } +} + +void +ofproto_group_unref(struct ofgroup *group) +{ + if (group && ovs_refcount_unref(&group->ref_count) == 1) { + ovsrcu_postpone(group_destroy_cb, group); + } +} + static uint32_t get_provider_meter_id(const struct ofproto *, uint32_t of_meter_id); @@ -5622,6 +5647,7 @@ add_group(struct ofproto *ofproto, struct ofputil_group_mod *gm) ofgroup->group_id = gm->group_id; ofgroup->type = gm->type; ofgroup->created = ofgroup->modified = time_msec(); + ovs_refcount_init(&ofgroup->ref_count); list_move(&ofgroup->buckets, &gm->buckets); ofgroup->n_buckets = list_size(&ofgroup->buckets); @@ -5752,12 +5778,8 @@ delete_group__(struct ofproto *ofproto, struct ofgroup *ofgroup) /* No-one can find this group any more. */ ofproto->n_groups[ofgroup->type]--; ovs_rwlock_unlock(&ofproto->groups_rwlock); - - ofproto->ofproto_class->group_destruct(ofgroup); - ofputil_bucket_list_destroy(&ofgroup->buckets); ovs_rwlock_unlock(&ofgroup->rwlock); - ovs_rwlock_destroy(&ofgroup->rwlock); - ofproto->ofproto_class->group_dealloc(ofgroup); + ofproto_group_unref(ofgroup); } /* Implements OFPGC_DELETE. */ -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev