diff options
author | Sven Eckelmann | 2016-01-16 10:29:46 +0100 |
---|---|---|
committer | Antonio Quartulli | 2016-02-10 16:24:01 +0100 |
commit | 727e0cd59e7be176edc7728cef883f912a29168f (patch) | |
tree | 5e346c72949247f584a6910d88aeb85790c7d903 /net/batman-adv/network-coding.c | |
parent | batman-adv: Convert batadv_nc_node to kref (diff) | |
download | kernel-qcow2-linux-727e0cd59e7be176edc7728cef883f912a29168f.tar.gz kernel-qcow2-linux-727e0cd59e7be176edc7728cef883f912a29168f.tar.xz kernel-qcow2-linux-727e0cd59e7be176edc7728cef883f912a29168f.zip |
batman-adv: Convert batadv_nc_path 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/network-coding.c')
-rw-r--r-- | net/batman-adv/network-coding.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index 7a1216eeb4cf..371fc6bbf9d6 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c @@ -233,14 +233,27 @@ static void batadv_nc_node_free_ref(struct batadv_nc_node *nc_node) } /** - * batadv_nc_path_free_ref - decrements the nc path refcounter and possibly - * frees it - * @nc_path: the nc node to free + * batadv_nc_path_release - release nc_path from lists and queue for free after + * rcu grace period + * @ref: kref pointer of the nc_path + */ +static void batadv_nc_path_release(struct kref *ref) +{ + struct batadv_nc_path *nc_path; + + nc_path = container_of(ref, struct batadv_nc_path, refcount); + + kfree_rcu(nc_path, rcu); +} + +/** + * batadv_nc_path_free_ref - decrement the nc_path refcounter and possibly + * release it + * @nc_path: nc_path to be free'd */ static void batadv_nc_path_free_ref(struct batadv_nc_path *nc_path) { - if (atomic_dec_and_test(&nc_path->refcount)) - kfree_rcu(nc_path, rcu); + kref_put(&nc_path->refcount, batadv_nc_path_release); } /** @@ -545,7 +558,7 @@ batadv_nc_hash_find(struct batadv_hashtable *hash, if (!batadv_nc_hash_compare(&nc_path->hash_entry, data)) continue; - if (!atomic_inc_not_zero(&nc_path->refcount)) + if (!kref_get_unless_zero(&nc_path->refcount)) continue; nc_path_tmp = nc_path; @@ -972,7 +985,8 @@ static struct batadv_nc_path *batadv_nc_get_path(struct batadv_priv *bat_priv, /* Initialize nc_path */ INIT_LIST_HEAD(&nc_path->packet_list); spin_lock_init(&nc_path->packet_list_lock); - atomic_set(&nc_path->refcount, 2); + kref_init(&nc_path->refcount); + kref_get(&nc_path->refcount); nc_path->last_valid = jiffies; ether_addr_copy(nc_path->next_hop, dst); ether_addr_copy(nc_path->prev_hop, src); |