diff options
author | Sven Eckelmann <sven@narfation.org> | 2016-01-16 09:29:49 (GMT) |
---|---|---|
committer | Antonio Quartulli <a@unstable.cc> | 2016-02-10 15:24:03 (GMT) |
commit | 32836f56f88c280d39fc302bcc0e0e3ed6bb412e (patch) | |
tree | d6163e5e8508ad2961c3080db0b556c7d6004580 /net/batman-adv | |
parent | f7157dd135012d9e9b4d74a9f8b2426ea92131f8 (diff) | |
download | linux-32836f56f88c280d39fc302bcc0e0e3ed6bb412e.tar.xz |
batman-adv: Convert batadv_tvlv_handler to kref
batman-adv uses a self-written reference implementation which is just based
on atomic_t. This is less obvious when reading the code than kref and
therefore increases the change that the reference counting will be missed.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <a@unstable.cc>
Diffstat (limited to 'net/batman-adv')
-rw-r--r-- | net/batman-adv/main.c | 24 | ||||
-rw-r--r-- | net/batman-adv/types.h | 2 |
2 files changed, 19 insertions, 7 deletions
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 4b6c258..568c550 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -625,15 +625,27 @@ __be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr) } /** - * batadv_tvlv_handler_free_ref - decrement the tvlv handler refcounter and - * possibly free it + * batadv_tvlv_handler_release - release tvlv handler from lists and queue for + * free after rcu grace period + * @ref: kref pointer of the tvlv + */ +static void batadv_tvlv_handler_release(struct kref *ref) +{ + struct batadv_tvlv_handler *tvlv_handler; + + tvlv_handler = container_of(ref, struct batadv_tvlv_handler, refcount); + kfree_rcu(tvlv_handler, rcu); +} + +/** + * batadv_tvlv_handler_free_ref - decrement the tvlv container refcounter and + * possibly release it * @tvlv_handler: the tvlv handler to free */ static void batadv_tvlv_handler_free_ref(struct batadv_tvlv_handler *tvlv_handler) { - if (atomic_dec_and_test(&tvlv_handler->refcount)) - kfree_rcu(tvlv_handler, rcu); + kref_put(&tvlv_handler->refcount, batadv_tvlv_handler_release); } /** @@ -659,7 +671,7 @@ static struct batadv_tvlv_handler if (tvlv_handler_tmp->version != version) continue; - if (!atomic_inc_not_zero(&tvlv_handler_tmp->refcount)) + if (!kref_get_unless_zero(&tvlv_handler_tmp->refcount)) continue; tvlv_handler = tvlv_handler_tmp; @@ -1112,7 +1124,7 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv, tvlv_handler->type = type; tvlv_handler->version = version; tvlv_handler->flags = flags; - atomic_set(&tvlv_handler->refcount, 1); + kref_init(&tvlv_handler->refcount); INIT_HLIST_NODE(&tvlv_handler->list); spin_lock_bh(&bat_priv->tvlv.handler_list_lock); diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index c55925b..f89dd97 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -1293,7 +1293,7 @@ struct batadv_tvlv_handler { u8 type; u8 version; u8 flags; - atomic_t refcount; + struct kref refcount; struct rcu_head rcu; }; |