Acked-by: Ethan Jackson <et...@nicira.com>
On Wed, Apr 23, 2014 at 4:20 PM, Jarno Rajahalme <jrajaha...@nicira.com> wrote: > This allows rules to be used without taking references while RCU > protected. > > The last step of destroying an ofproto also needs to be postponed, as > the rule destruction requires the class structure to be available at > the postponed destruction callback. > > Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> > --- > ofproto/ofproto.c | 40 ++++++++++++++++++++++++++-------------- > 1 file changed, 26 insertions(+), 14 deletions(-) > > diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c > index f16005c..f10d3ae 100644 > --- a/ofproto/ofproto.c > +++ b/ofproto/ofproto.c > @@ -259,7 +259,6 @@ struct ofport_usage { > }; > > /* rule. */ > -static void ofproto_rule_destroy__(struct rule *); > static void ofproto_rule_send_removed(struct rule *, uint8_t reason); > static bool rule_is_modifiable(const struct rule *rule, > enum ofputil_flow_mod_flags flag); > @@ -1372,7 +1371,8 @@ ofproto_destroy(struct ofproto *p) > } > > p->ofproto_class->destruct(p); > - ofproto_destroy__(p); > + /* Destroying rules is deferred, must have 'ofproto' around for them. */ > + ovsrcu_postpone(ofproto_destroy__, p); > } > > /* Destroys the datapath with the respective 'name' and 'type'. With the > Linux > @@ -2642,6 +2642,23 @@ update_mtu(struct ofproto *p, struct ofport *port) > } > } > > +static void > +ofproto_rule_destroy__(struct rule *rule) > + OVS_NO_THREAD_SAFETY_ANALYSIS > +{ > + cls_rule_destroy(CONST_CAST(struct cls_rule *, &rule->cr)); > + rule_actions_destroy(rule_get_actions(rule)); > + ovs_mutex_destroy(&rule->mutex); > + rule->ofproto->ofproto_class->rule_dealloc(rule); > +} > + > +static void > +rule_destroy_cb(struct rule *rule) > +{ > + rule->ofproto->ofproto_class->rule_destruct(rule); > + ofproto_rule_destroy__(rule); > +} > + > void > ofproto_rule_ref(struct rule *rule) > { > @@ -2650,25 +2667,20 @@ ofproto_rule_ref(struct rule *rule) > } > } > > +/* Decrements 'rule''s ref_count and schedules 'rule' to be destroyed if the > + * ref_count reaches 0. > + * > + * Use of RCU allows short term use (between RCU quiescent periods) without > + * keeping a reference. A reference must be taken if the rule needs to > + * stay around accross the RCU quiescent periods. */ > void > ofproto_rule_unref(struct rule *rule) > { > if (rule && ovs_refcount_unref(&rule->ref_count) == 1) { > - rule->ofproto->ofproto_class->rule_destruct(rule); > - ofproto_rule_destroy__(rule); > + ovsrcu_postpone(rule_destroy_cb, rule); > } > } > > -static void > -ofproto_rule_destroy__(struct rule *rule) > - OVS_NO_THREAD_SAFETY_ANALYSIS > -{ > - cls_rule_destroy(CONST_CAST(struct cls_rule *, &rule->cr)); > - rule_actions_destroy(rule_get_actions(rule)); > - ovs_mutex_destroy(&rule->mutex); > - rule->ofproto->ofproto_class->rule_dealloc(rule); > -} > - > static uint32_t get_provider_meter_id(const struct ofproto *, > uint32_t of_meter_id); > > -- > 1.7.10.4 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev