From: Ben Pfaff Date: Sat, 28 Dec 2013 03:39:24 +0000 (-0800) Subject: ovs-atomic: Introduce a new 'struct ovs_refcount'. X-Git-Tag: v2.3~800 X-Git-Url: http://git.cascardo.eti.br/?a=commitdiff_plain;h=37bec3d330ed7f72b6a867728c538b49e5727dc7;p=cascardo%2Fovs.git ovs-atomic: Introduce a new 'struct ovs_refcount'. This is a thin wrapper around an atomic_uint. It is useful anyhow because each ovs_refcount_ref() or ovs_refcount_unref() call saves a few lines of code. This commit also changes all the potential direct users over to use the new data structure. Signed-off-by: Ben Pfaff --- diff --git a/lib/bfd.c b/lib/bfd.c index ad2d7531c..e5bf5a140 100644 --- a/lib/bfd.c +++ b/lib/bfd.c @@ -193,7 +193,7 @@ struct bfd { int forwarding_override; /* Manual override of 'forwarding' status. */ atomic_bool check_tnl_key; /* Verify tunnel key of inbound packets? */ - atomic_int ref_cnt; + struct ovs_refcount ref_cnt; /* When forward_if_rx is true, bfd_forwarding() will return * true as long as there are incoming packets received. @@ -341,7 +341,7 @@ bfd_configure(struct bfd *bfd, const char *name, const struct smap *cfg, bfd->diag = DIAG_NONE; bfd->min_tx = 1000; bfd->mult = 3; - atomic_init(&bfd->ref_cnt, 1); + ovs_refcount_init(&bfd->ref_cnt); bfd->netdev = netdev_ref(netdev); bfd->rx_packets = bfd_rx_packets(bfd); bfd->in_decay = false; @@ -440,9 +440,7 @@ bfd_ref(const struct bfd *bfd_) { struct bfd *bfd = CONST_CAST(struct bfd *, bfd_); if (bfd) { - int orig; - atomic_add(&bfd->ref_cnt, 1, &orig); - ovs_assert(orig > 0); + ovs_refcount_ref(&bfd->ref_cnt); } return bfd; } @@ -450,20 +448,14 @@ bfd_ref(const struct bfd *bfd_) void bfd_unref(struct bfd *bfd) OVS_EXCLUDED(mutex) { - if (bfd) { - int orig; - - atomic_sub(&bfd->ref_cnt, 1, &orig); - ovs_assert(orig > 0); - if (orig == 1) { - ovs_mutex_lock(&mutex); - hmap_remove(all_bfds, &bfd->node); - netdev_close(bfd->netdev); - free(bfd->name); - atomic_destroy(&bfd->ref_cnt); - free(bfd); - ovs_mutex_unlock(&mutex); - } + if (bfd && ovs_refcount_unref(&bfd->ref_cnt) == 1) { + ovs_mutex_lock(&mutex); + hmap_remove(all_bfds, &bfd->node); + netdev_close(bfd->netdev); + ovs_refcount_destroy(&bfd->ref_cnt); + free(bfd->name); + free(bfd); + ovs_mutex_unlock(&mutex); } } diff --git a/lib/cfm.c b/lib/cfm.c index fc0ef7859..bd2f6ea19 100644 --- a/lib/cfm.c +++ b/lib/cfm.c @@ -130,7 +130,7 @@ struct cfm { atomic_bool check_tnl_key; /* Verify the tunnel key of inbound packets? */ atomic_bool extended; /* Extended mode. */ - atomic_int ref_cnt; + struct ovs_refcount ref_cnt; uint64_t flap_count; /* Count the flaps since boot. */ }; @@ -337,7 +337,7 @@ cfm_create(const struct netdev *netdev) OVS_EXCLUDED(mutex) cfm->flap_count = 0; atomic_init(&cfm->extended, false); atomic_init(&cfm->check_tnl_key, false); - atomic_init(&cfm->ref_cnt, 1); + ovs_refcount_init(&cfm->ref_cnt); ovs_mutex_lock(&mutex); cfm_generate_maid(cfm); @@ -350,15 +350,12 @@ void cfm_unref(struct cfm *cfm) OVS_EXCLUDED(mutex) { struct remote_mp *rmp, *rmp_next; - int orig; if (!cfm) { return; } - atomic_sub(&cfm->ref_cnt, 1, &orig); - ovs_assert(orig > 0); - if (orig != 1) { + if (ovs_refcount_unref(&cfm->ref_cnt) != 1) { return; } @@ -377,7 +374,7 @@ cfm_unref(struct cfm *cfm) OVS_EXCLUDED(mutex) atomic_destroy(&cfm->extended); atomic_destroy(&cfm->check_tnl_key); - atomic_destroy(&cfm->ref_cnt); + ovs_refcount_destroy(&cfm->ref_cnt); free(cfm); } @@ -387,9 +384,7 @@ cfm_ref(const struct cfm *cfm_) { struct cfm *cfm = CONST_CAST(struct cfm *, cfm_); if (cfm) { - int orig; - atomic_add(&cfm->ref_cnt, 1, &orig); - ovs_assert(orig > 0); + ovs_refcount_ref(&cfm->ref_cnt); } return cfm; } diff --git a/lib/lacp.c b/lib/lacp.c index 2c17e22c3..a3f72edd0 100644 --- a/lib/lacp.c +++ b/lib/lacp.c @@ -106,7 +106,7 @@ struct lacp { bool update; /* True if lacp_update() needs to be called. */ bool fallback_ab; /* True if fallback to active-backup on LACP failure. */ - atomic_int ref_cnt; + struct ovs_refcount ref_cnt; }; struct slave { @@ -216,7 +216,7 @@ lacp_create(void) OVS_EXCLUDED(mutex) lacp = xzalloc(sizeof *lacp); hmap_init(&lacp->slaves); - atomic_init(&lacp->ref_cnt, 1); + ovs_refcount_init(&lacp->ref_cnt); ovs_mutex_lock(&mutex); list_push_back(all_lacps, &lacp->node); @@ -229,9 +229,7 @@ lacp_ref(const struct lacp *lacp_) { struct lacp *lacp = CONST_CAST(struct lacp *, lacp_); if (lacp) { - int orig; - atomic_add(&lacp->ref_cnt, 1, &orig); - ovs_assert(orig > 0); + ovs_refcount_ref(&lacp->ref_cnt); } return lacp; } @@ -240,15 +238,7 @@ lacp_ref(const struct lacp *lacp_) void lacp_unref(struct lacp *lacp) OVS_EXCLUDED(mutex) { - int orig; - - if (!lacp) { - return; - } - - atomic_sub(&lacp->ref_cnt, 1, &orig); - ovs_assert(orig > 0); - if (orig == 1) { + if (lacp && ovs_refcount_unref(&lacp->ref_cnt) == 1) { struct slave *slave, *next; ovs_mutex_lock(&mutex); @@ -259,7 +249,7 @@ lacp_unref(struct lacp *lacp) OVS_EXCLUDED(mutex) hmap_destroy(&lacp->slaves); list_remove(&lacp->node); free(lacp->name); - atomic_destroy(&lacp->ref_cnt); + ovs_refcount_destroy(&lacp->ref_cnt); free(lacp); ovs_mutex_unlock(&mutex); } diff --git a/lib/mac-learning.c b/lib/mac-learning.c index f540d6dce..01a34f583 100644 --- a/lib/mac-learning.c +++ b/lib/mac-learning.c @@ -111,7 +111,7 @@ mac_learning_create(unsigned int idle_time) ml->idle_time = normalize_idle_time(idle_time); ml->max_entries = MAC_DEFAULT_MAX; ml->need_revalidate = false; - atomic_init(&ml->ref_cnt, 1); + ovs_refcount_init(&ml->ref_cnt); ovs_rwlock_init(&ml->rwlock); return ml; } @@ -121,9 +121,7 @@ mac_learning_ref(const struct mac_learning *ml_) { struct mac_learning *ml = CONST_CAST(struct mac_learning *, ml_); if (ml) { - int orig; - atomic_add(&ml->ref_cnt, 1, &orig); - ovs_assert(orig > 0); + ovs_refcount_ref(&ml->ref_cnt); } return ml; } @@ -132,15 +130,7 @@ mac_learning_ref(const struct mac_learning *ml_) void mac_learning_unref(struct mac_learning *ml) { - int orig; - - if (!ml) { - return; - } - - atomic_sub(&ml->ref_cnt, 1, &orig); - ovs_assert(orig > 0); - if (orig == 1) { + if (ml && ovs_refcount_unref(&ml->ref_cnt) == 1) { struct mac_entry *e, *next; HMAP_FOR_EACH_SAFE (e, next, hmap_node, &ml->table) { @@ -151,7 +141,7 @@ mac_learning_unref(struct mac_learning *ml) bitmap_free(ml->flood_vlans); ovs_rwlock_destroy(&ml->rwlock); - atomic_destroy(&ml->ref_cnt); + ovs_refcount_destroy(&ml->ref_cnt); free(ml); } } diff --git a/lib/mac-learning.h b/lib/mac-learning.h index ba7f73421..34dc12c47 100644 --- a/lib/mac-learning.h +++ b/lib/mac-learning.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -80,7 +80,7 @@ struct mac_learning { unsigned long *flood_vlans; /* Bitmap of learning disabled VLANs. */ unsigned int idle_time; /* Max age before deleting an entry. */ size_t max_entries; /* Max number of learned MACs. */ - atomic_int ref_cnt; + struct ovs_refcount ref_cnt; struct ovs_rwlock rwlock; bool need_revalidate; }; diff --git a/lib/ovs-atomic.h b/lib/ovs-atomic.h index 2c071385a..4d43a42a5 100644 --- a/lib/ovs-atomic.h +++ b/lib/ovs-atomic.h @@ -280,4 +280,65 @@ #endif #undef IN_OVS_ATOMIC_H +/* Reference count. */ +struct ovs_refcount { + atomic_uint count; +}; + +/* Initializes 'refcount'. The reference count is initially 1. */ +static inline void +ovs_refcount_init(struct ovs_refcount *refcount) +{ + atomic_init(&refcount->count, 1); +} + +/* Destroys 'refcount'. */ +static inline void +ovs_refcount_destroy(struct ovs_refcount *refcount) +{ + atomic_destroy(&refcount->count); +} + +/* Increments 'refcount'. */ +static inline void +ovs_refcount_ref(struct ovs_refcount *refcount) +{ + unsigned int old_refcount; + + atomic_add(&refcount->count, 1, &old_refcount); + ovs_assert(old_refcount > 0); +} + +/* Decrements 'refcount' and returns the previous reference count. Often used + * in this form: + * + * if (ovs_refcount_unref(&object->ref_cnt) == 1) { + * // ...uninitialize object... + * free(object); + * } + */ +static inline unsigned int +ovs_refcount_unref(struct ovs_refcount *refcount) +{ + unsigned int old_refcount; + + atomic_sub(&refcount->count, 1, &old_refcount); + ovs_assert(old_refcount > 0); + return old_refcount; +} + +/* Reads and returns 'ref_count_''s current reference count. + * + * Rarely useful. */ +static inline unsigned int +ovs_refcount_read(const struct ovs_refcount *refcount_) +{ + struct ovs_refcount *refcount + = CONST_CAST(struct ovs_refcount *, refcount_); + unsigned int count; + + atomic_read(&refcount->count, &count); + return count; +} + #endif /* ovs-atomic.h */ diff --git a/lib/stp.c b/lib/stp.c index 818f2ca3d..e4ddf3ca2 100644 --- a/lib/stp.c +++ b/lib/stp.c @@ -143,7 +143,7 @@ struct stp { void (*send_bpdu)(struct ofpbuf *bpdu, int port_no, void *aux); void *aux; - atomic_int ref_cnt; + struct ovs_refcount ref_cnt; }; static struct ovs_mutex mutex; @@ -306,7 +306,7 @@ stp_create(const char *name, stp_identifier bridge_id, p->path_cost = 19; /* Recommended default for 100 Mb/s link. */ stp_initialize_port(p, STP_DISABLED); } - atomic_init(&stp->ref_cnt, 1); + ovs_refcount_init(&stp->ref_cnt); list_push_back(all_stps, &stp->node); ovs_mutex_unlock(&mutex); @@ -318,9 +318,7 @@ stp_ref(const struct stp *stp_) { struct stp *stp = CONST_CAST(struct stp *, stp_); if (stp) { - int orig; - atomic_add(&stp->ref_cnt, 1, &orig); - ovs_assert(orig > 0); + ovs_refcount_ref(&stp->ref_cnt); } return stp; } @@ -329,20 +327,12 @@ stp_ref(const struct stp *stp_) void stp_unref(struct stp *stp) { - int orig; - - if (!stp) { - return; - } - - atomic_sub(&stp->ref_cnt, 1, &orig); - ovs_assert(orig > 0); - if (orig == 1) { + if (stp && ovs_refcount_unref(&stp->ref_cnt) == 1) { ovs_mutex_lock(&mutex); list_remove(&stp->node); ovs_mutex_unlock(&mutex); free(stp->name); - atomic_destroy(&stp->ref_cnt); + ovs_refcount_destroy(&stp->ref_cnt); free(stp); } } diff --git a/ofproto/bond.c b/ofproto/bond.c index 3b0c11c93..a651d8d2d 100644 --- a/ofproto/bond.c +++ b/ofproto/bond.c @@ -103,7 +103,7 @@ struct bond { long long int next_fake_iface_update; /* LLONG_MAX if disabled. */ bool lacp_fallback_ab; /* Fallback to active-backup on LACP failure. */ - atomic_int ref_cnt; + struct ovs_refcount ref_cnt; }; static struct ovs_rwlock rwlock = OVS_RWLOCK_INITIALIZER; @@ -181,7 +181,7 @@ bond_create(const struct bond_settings *s) bond = xzalloc(sizeof *bond); hmap_init(&bond->slaves); bond->next_fake_iface_update = LLONG_MAX; - atomic_init(&bond->ref_cnt, 1); + ovs_refcount_init(&bond->ref_cnt); bond_reconfigure(bond, s); return bond; @@ -193,9 +193,7 @@ bond_ref(const struct bond *bond_) struct bond *bond = CONST_CAST(struct bond *, bond_); if (bond) { - int orig; - atomic_add(&bond->ref_cnt, 1, &orig); - ovs_assert(orig > 0); + ovs_refcount_ref(&bond->ref_cnt); } return bond; } @@ -205,15 +203,8 @@ void bond_unref(struct bond *bond) { struct bond_slave *slave, *next_slave; - int orig; - if (!bond) { - return; - } - - atomic_sub(&bond->ref_cnt, 1, &orig); - ovs_assert(orig > 0); - if (orig != 1) { + if (!bond || ovs_refcount_unref(&bond->ref_cnt) != 1) { return; } @@ -231,7 +222,7 @@ bond_unref(struct bond *bond) free(bond->hash); free(bond->name); - atomic_destroy(&bond->ref_cnt); + ovs_refcount_destroy(&bond->ref_cnt); free(bond); } diff --git a/ofproto/netflow.c b/ofproto/netflow.c index 3aa0630bf..8259cede3 100644 --- a/ofproto/netflow.c +++ b/ofproto/netflow.c @@ -53,7 +53,7 @@ struct netflow { struct hmap flows; /* Contains 'netflow_flows'. */ - atomic_int ref_cnt; + struct ovs_refcount ref_cnt; }; struct netflow_flow { @@ -405,7 +405,7 @@ netflow_create(void) nf->add_id_to_iface = false; nf->netflow_cnt = 0; hmap_init(&nf->flows); - atomic_init(&nf->ref_cnt, 1); + ovs_refcount_init(&nf->ref_cnt); ofpbuf_init(&nf->packet, 1500); atomic_add(&netflow_count, 1, &junk); return nf; @@ -416,9 +416,7 @@ netflow_ref(const struct netflow *nf_) { struct netflow *nf = CONST_CAST(struct netflow *, nf_); if (nf) { - int orig; - atomic_add(&nf->ref_cnt, 1, &orig); - ovs_assert(orig > 0); + ovs_refcount_ref(&nf->ref_cnt); } return nf; } @@ -426,19 +424,13 @@ netflow_ref(const struct netflow *nf_) void netflow_unref(struct netflow *nf) { - int orig; - - if (!nf) { - return; - } + if (nf && ovs_refcount_unref(&nf->ref_cnt) == 1) { + int orig; - atomic_sub(&nf->ref_cnt, 1, &orig); - ovs_assert(orig > 0); - if (orig == 1) { atomic_sub(&netflow_count, 1, &orig); collectors_destroy(nf->collectors); ofpbuf_uninit(&nf->packet); - atomic_destroy(&nf->ref_cnt); + ovs_refcount_destroy(&nf->ref_cnt); free(nf); } } diff --git a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c index 55544cc66..2500efdd2 100644 --- a/ofproto/ofproto-dpif-ipfix.c +++ b/ofproto/ofproto-dpif-ipfix.c @@ -70,7 +70,7 @@ struct dpif_ipfix_flow_exporter_map_node { struct dpif_ipfix { struct dpif_ipfix_bridge_exporter bridge_exporter; struct hmap flow_exporter_map; /* dpif_ipfix_flow_exporter_map_node. */ - atomic_int ref_cnt; + struct ovs_refcount ref_cnt; }; #define IPFIX_VERSION 0x000a @@ -639,7 +639,7 @@ dpif_ipfix_create(void) di = xzalloc(sizeof *di); dpif_ipfix_bridge_exporter_init(&di->bridge_exporter); hmap_init(&di->flow_exporter_map); - atomic_init(&di->ref_cnt, 1); + ovs_refcount_init(&di->ref_cnt); return di; } @@ -648,9 +648,7 @@ dpif_ipfix_ref(const struct dpif_ipfix *di_) { struct dpif_ipfix *di = CONST_CAST(struct dpif_ipfix *, di_); if (di) { - int orig; - atomic_add(&di->ref_cnt, 1, &orig); - ovs_assert(orig > 0); + ovs_refcount_ref(&di->ref_cnt); } return di; } @@ -683,20 +681,12 @@ dpif_ipfix_clear(struct dpif_ipfix *di) OVS_REQUIRES(mutex) void dpif_ipfix_unref(struct dpif_ipfix *di) OVS_EXCLUDED(mutex) { - int orig; - - if (!di) { - return; - } - - atomic_sub(&di->ref_cnt, 1, &orig); - ovs_assert(orig > 0); - if (orig == 1) { + if (di && ovs_refcount_unref(&di->ref_cnt) == 1) { ovs_mutex_lock(&mutex); dpif_ipfix_clear(di); dpif_ipfix_bridge_exporter_destroy(&di->bridge_exporter); hmap_destroy(&di->flow_exporter_map); - atomic_destroy(&di->ref_cnt); + ovs_refcount_destroy(&di->ref_cnt); free(di); ovs_mutex_unlock(&mutex); } diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c index d45eadac1..e9ef434dd 100644 --- a/ofproto/ofproto-dpif-sflow.c +++ b/ofproto/ofproto-dpif-sflow.c @@ -59,7 +59,7 @@ struct dpif_sflow { size_t n_flood, n_all; struct hmap ports; /* Contains "struct dpif_sflow_port"s. */ uint32_t probability; - atomic_int ref_cnt; + struct ovs_refcount ref_cnt; }; static void dpif_sflow_del_port__(struct dpif_sflow *, @@ -327,7 +327,7 @@ dpif_sflow_create(void) hmap_init(&ds->ports); ds->probability = 0; route_table_register(); - atomic_init(&ds->ref_cnt, 1); + ovs_refcount_init(&ds->ref_cnt); return ds; } @@ -337,9 +337,7 @@ dpif_sflow_ref(const struct dpif_sflow *ds_) { struct dpif_sflow *ds = CONST_CAST(struct dpif_sflow *, ds_); if (ds) { - int orig; - atomic_add(&ds->ref_cnt, 1, &orig); - ovs_assert(orig > 0); + ovs_refcount_ref(&ds->ref_cnt); } return ds; } @@ -360,15 +358,7 @@ dpif_sflow_get_probability(const struct dpif_sflow *ds) OVS_EXCLUDED(mutex) void dpif_sflow_unref(struct dpif_sflow *ds) OVS_EXCLUDED(mutex) { - int orig; - - if (!ds) { - return; - } - - atomic_sub(&ds->ref_cnt, 1, &orig); - ovs_assert(orig > 0); - if (orig == 1) { + if (ds && ovs_refcount_unref(&ds->ref_cnt) == 1) { struct dpif_sflow_port *dsp, *next; route_table_unregister(); @@ -377,7 +367,7 @@ dpif_sflow_unref(struct dpif_sflow *ds) OVS_EXCLUDED(mutex) dpif_sflow_del_port__(ds, dsp); } hmap_destroy(&ds->ports); - atomic_destroy(&ds->ref_cnt); + ovs_refcount_destroy(&ds->ref_cnt); free(ds); } } diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index cc318eed1..19d155172 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -346,7 +346,7 @@ struct rule { * The classifier owns one reference. * Any thread trying to keep a rule from being freed should hold its own * reference. */ - atomic_uint ref_count; + struct ovs_refcount ref_count; /* Operation now in progress, if nonnull. */ struct ofoperation *pending OVS_GUARDED_BY(ofproto_mutex); @@ -426,7 +426,7 @@ rule_is_table_miss(const struct rule *rule) * 'rule' is the rule for which 'rule->actions == actions') or that owns a * reference to 'actions->ref_count' (or both). */ struct rule_actions { - atomic_uint ref_count; + struct ovs_refcount ref_count; /* These members are immutable: they do not change during the struct's * lifetime. */ diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index f65137455..fbcd30652 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -2527,26 +2527,16 @@ void ofproto_rule_ref(struct rule *rule) { if (rule) { - unsigned int orig; - - atomic_add(&rule->ref_count, 1, &orig); - ovs_assert(orig != 0); + ovs_refcount_ref(&rule->ref_count); } } void ofproto_rule_unref(struct rule *rule) { - if (rule) { - unsigned int orig; - - atomic_sub(&rule->ref_count, 1, &orig); - if (orig == 1) { - rule->ofproto->ofproto_class->rule_destruct(rule); - ofproto_rule_destroy__(rule); - } else { - ovs_assert(orig != 0); - } + if (rule && ovs_refcount_unref(&rule->ref_count) == 1) { + rule->ofproto->ofproto_class->rule_destruct(rule); + ofproto_rule_destroy__(rule); } } @@ -2578,7 +2568,7 @@ ofproto_rule_destroy__(struct rule *rule) cls_rule_destroy(CONST_CAST(struct cls_rule *, &rule->cr)); rule_actions_unref(rule->actions); ovs_mutex_destroy(&rule->mutex); - atomic_destroy(&rule->ref_count); + ovs_refcount_destroy(&rule->ref_count); rule->ofproto->ofproto_class->rule_dealloc(rule); } @@ -2594,7 +2584,7 @@ rule_actions_create(const struct ofproto *ofproto, struct rule_actions *actions; actions = xmalloc(sizeof *actions); - atomic_init(&actions->ref_count, 1); + ovs_refcount_init(&actions->ref_count); actions->ofpacts = xmemdup(ofpacts, ofpacts_len); actions->ofpacts_len = ofpacts_len; actions->provider_meter_id @@ -2609,10 +2599,7 @@ void rule_actions_ref(struct rule_actions *actions) { if (actions) { - unsigned int orig; - - atomic_add(&actions->ref_count, 1, &orig); - ovs_assert(orig != 0); + ovs_refcount_ref(&actions->ref_count); } } @@ -2621,17 +2608,10 @@ rule_actions_ref(struct rule_actions *actions) void rule_actions_unref(struct rule_actions *actions) { - if (actions) { - unsigned int orig; - - atomic_sub(&actions->ref_count, 1, &orig); - if (orig == 1) { - atomic_destroy(&actions->ref_count); - free(actions->ofpacts); - free(actions); - } else { - ovs_assert(orig != 0); - } + if (actions && ovs_refcount_unref(&actions->ref_count) == 1) { + ovs_refcount_destroy(&actions->ref_count); + free(actions->ofpacts); + free(actions); } } @@ -4032,7 +4012,7 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, /* Initialize base state. */ *CONST_CAST(struct ofproto **, &rule->ofproto) = ofproto; cls_rule_move(CONST_CAST(struct cls_rule *, &rule->cr), &cr); - atomic_init(&rule->ref_count, 1); + ovs_refcount_init(&rule->ref_count); rule->pending = NULL; rule->flow_cookie = fm->new_cookie; rule->created = rule->modified = rule->used = time_msec();