[ovs-dev] [threaded-learning v2 20/25] ofproto: Mark immutable members of struct rule 'const'.
Ethan Jackson
ethan at nicira.com
Thu Sep 12 23:42:08 UTC 2013
Acked-by: Ethan Jackson <ethan at nicira.com>
On Thu, Sep 12, 2013 at 12:39 AM, Ben Pfaff <blp at nicira.com> wrote:
> One difficult part of make flow_mods thread-safe is sorting out which
> members of each structure can be modified under which locks and,
> especially, documenting this in a way that makes it hard for programmers to
> get it wrong later. The compiler provides some tools for us, however, and
> 'const' is one of the nicer ones since it is standardized rather than part
> of a compiler extension.
>
> This commit makes use of 'const' to mark the immutable members of struct
> rule, which is definitely the most confusing structure regarding thread
> safety simply because it has so many members that use different forms of
> synchronization. It also adds a bunch of CONST_CASTs to allow these
> members to be initialized and destroyed where necessary.
>
> Signed-off-by: Ben Pfaff <blp at nicira.com>
> ---
> ofproto/ofproto-dpif.c | 2 +-
> ofproto/ofproto-provider.h | 10 +++++++---
> ofproto/ofproto.c | 12 ++++++------
> 3 files changed, 14 insertions(+), 10 deletions(-)
>
> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
> index 81adb0a..5b60e36 100644
> --- a/ofproto/ofproto-dpif.c
> +++ b/ofproto/ofproto-dpif.c
> @@ -4777,7 +4777,7 @@ rule_dpif_lookup_in_table(struct ofproto_dpif *ofproto,
> const struct flow *flow, struct flow_wildcards *wc,
> uint8_t table_id, struct rule_dpif **rule)
> {
> - struct cls_rule *cls_rule;
> + const struct cls_rule *cls_rule;
> struct classifier *cls;
> bool frag;
>
> diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
> index 6583294e..a3640bd 100644
> --- a/ofproto/ofproto-provider.h
> +++ b/ofproto/ofproto-provider.h
> @@ -227,8 +227,13 @@ struct oftable {
> * With few exceptions, ofproto implementations may look at these fields but
> * should not modify them. */
> struct rule {
> - struct ofproto *ofproto; /* The ofproto that contains this rule. */
> - struct cls_rule cr; /* In owning ofproto's classifier. */
> + /* Where this rule resides in an OpenFlow switch.
> + *
> + * These are immutable once the rule is constructed, hence 'const'. */
> + struct ofproto *const ofproto; /* The ofproto that contains this rule. */
> + const struct cls_rule cr; /* In owning ofproto's classifier. */
> + const uint8_t table_id; /* Index in ofproto's 'tables' array. */
> +
> atomic_uint ref_count;
>
> struct ofoperation *pending; /* Operation now in progress, if nonnull. */
> @@ -240,7 +245,6 @@ struct rule {
> long long int created; /* Creation time. */
> long long int modified; /* Time of last modification. */
> long long int used; /* Last use; time created if never used. */
> - uint8_t table_id; /* Index in ofproto's 'tables' array. */
> enum ofputil_flow_mod_flags flags;
>
> uint16_t hard_timeout OVS_GUARDED; /* In seconds from ->modified. */
> diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
> index 882d503..160d6b0 100644
> --- a/ofproto/ofproto.c
> +++ b/ofproto/ofproto.c
> @@ -2377,7 +2377,7 @@ ofproto_rule_unref(struct rule *rule)
> static void
> ofproto_rule_destroy__(struct rule *rule)
> {
> - cls_rule_destroy(&rule->cr);
> + cls_rule_destroy(CONST_CAST(struct cls_rule *, &rule->cr));
> rule_actions_unref(rule->actions);
> ovs_mutex_destroy(&rule->mutex);
> rule->ofproto->ofproto_class->rule_dealloc(rule);
> @@ -3759,8 +3759,8 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn,
> }
>
> /* Initialize base state. */
> - rule->ofproto = ofproto;
> - cls_rule_move(&rule->cr, &cr);
> + *CONST_CAST(struct ofproto **, &rule->ofproto) = ofproto;
> + cls_rule_move(CONST_CAST(struct cls_rule *, &rule->cr), &cr);
> atomic_init(&rule->ref_count, 1);
> rule->pending = NULL;
> rule->flow_cookie = fm->new_cookie;
> @@ -3772,7 +3772,7 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn,
> rule->hard_timeout = fm->hard_timeout;
> ovs_mutex_unlock(&rule->mutex);
>
> - rule->table_id = table - ofproto->tables;
> + *CONST_CAST(uint8_t *, &rule->table_id) = table - ofproto->tables;
> rule->flags = fm->flags & OFPUTIL_FF_STATE;
> rule->actions = rule_actions_create(fm->ofpacts, fm->ofpacts_len);
> list_init(&rule->meter_list_node);
> @@ -6335,7 +6335,7 @@ oftable_remove_rule__(struct ofproto *ofproto, struct classifier *cls,
> struct rule *rule)
> OVS_REQ_WRLOCK(cls->rwlock) OVS_RELEASES(rule->mutex)
> {
> - classifier_remove(cls, &rule->cr);
> + classifier_remove(cls, CONST_CAST(struct cls_rule *, &rule->cr));
>
> ovs_mutex_lock(&ofproto_mutex);
> cookies_remove(ofproto, rule);
> @@ -6393,7 +6393,7 @@ oftable_insert_rule(struct rule *rule)
> list_insert(&meter->rules, &rule->meter_list_node);
> }
> ovs_rwlock_wrlock(&table->cls.rwlock);
> - classifier_insert(&table->cls, &rule->cr);
> + classifier_insert(&table->cls, CONST_CAST(struct cls_rule *, &rule->cr));
> ovs_rwlock_unlock(&table->cls.rwlock);
> eviction_group_add_rule(rule);
> }
> --
> 1.7.10.4
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
More information about the dev
mailing list