Hey Andy, >At a high level, ofgroup struct current has rwlock that essentially >solving >the same problem as the ref count proposed in this patch. It would be >better >it seems confusing if we use both method together. > >Looking at the code, I'd think extending rwlock to cover xlate >fastpath is the most >straight forward approach.
The reason I use the reference count is because of the following situation: - The main thread and xlate cache both have pointers to the group. - The main thread deletes the group and frees memory. - However, the xlate cache still has a pointer to the group and if a handler is run prior to the revalidator clearing the xlate cache, a handler could write to freed memory. Thus, similar to netdev, I use a ref here, so the memory is not freed until both the cache and main thread are done with the group. Again, like netdev_mutex, the groups' rwlock is to serialize access to the group and bucket stats. Plus the rwlock won't work once the group is freed. Let me know if you have a cleaner suggestion to deal with this issue; I agree, I would prefer to use just a lock and / or a ref count. >I also noticed the lock annotation may be lacking around group >functions. It would >be nice to add them. I'll add these annotations in my next patch. Thanks for the review, Ryan > >On Mon, May 19, 2014 at 6:20 AM, Ryan Wilson <wr...@nicira.com> wrote: >> 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 >> >>https://urldefense.proofpoint.com/v1/url?u=http://openvswitch.org/mailman >>/listinfo/dev&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=TfBS78Vw3dzttvXidhbff >>g%3D%3D%0A&m=yJOSSP0gTPFhsJ2%2FdAJK7eyDBE8f7He9ElabH7ctSb4%3D%0A&s=c8eb05 >>9001930596833f500f75ed0cdf49802abfe3dac0d98729da1cdd7f905f >_______________________________________________ >dev mailing list >dev@openvswitch.org >https://urldefense.proofpoint.com/v1/url?u=http://openvswitch.org/mailman/ >listinfo/dev&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=TfBS78Vw3dzttvXidhbffg% >3D%3D%0A&m=yJOSSP0gTPFhsJ2%2FdAJK7eyDBE8f7He9ElabH7ctSb4%3D%0A&s=c8eb05900 >1930596833f500f75ed0cdf49802abfe3dac0d98729da1cdd7f905f _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev