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

Reply via email to