summaryrefslogtreecommitdiff
path: root/net/batman-adv/network-coding.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-02-11 03:49:55 -0500
committerDavid S. Miller <davem@davemloft.net>2016-02-11 03:49:55 -0500
commit30c1de08dda9202699c1ddc7fd658693faf93bf2 (patch)
tree0f4280ab8c520544fbd61866e8b5ce25f78a7294 /net/batman-adv/network-coding.c
parentdba6cf556026f38bf68a4a998671b7c44401e118 (diff)
parent92dcdf09a139e51b7b043b9443b8fd69de298dff (diff)
Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge
Antonio Quartulli says: ==================== Here you have a batch of patches by Sven Eckelmann that drops our private reference counting implementation and substitutes it with the kref objects/functions. Then you have a patch, by Simon Wunderlich, that makes the broadcast protection window code more generic so that it can be re-used in the future by other components with different requirements. Lastly, Sven is also introducing two lockdep asserts in functions operating on our TVLV container list, to make sure that the proper lock is always acquired by the users. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/batman-adv/network-coding.c')
-rw-r--r--net/batman-adv/network-coding.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
index 0b30c15eee5f..a4eb8ee4abb1 100644
--- a/net/batman-adv/network-coding.c
+++ b/net/batman-adv/network-coding.c
@@ -32,6 +32,7 @@
#include <linux/jhash.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
+#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
#include <linux/netdevice.h>
@@ -209,34 +210,50 @@ void batadv_nc_init_orig(struct batadv_orig_node *orig_node)
/**
* batadv_nc_node_release - release nc_node from lists and queue for free after
* rcu grace period
- * @nc_node: the nc node to free
+ * @ref: kref pointer of the nc_node
*/
-static void batadv_nc_node_release(struct batadv_nc_node *nc_node)
+static void batadv_nc_node_release(struct kref *ref)
{
+ struct batadv_nc_node *nc_node;
+
+ nc_node = container_of(ref, struct batadv_nc_node, refcount);
+
batadv_orig_node_free_ref(nc_node->orig_node);
kfree_rcu(nc_node, rcu);
}
/**
- * batadv_nc_node_free_ref - decrement the nc node refcounter and possibly
+ * batadv_nc_node_free_ref - decrement the nc_node refcounter and possibly
* release it
- * @nc_node: the nc node to free
+ * @nc_node: nc_node to be free'd
*/
static void batadv_nc_node_free_ref(struct batadv_nc_node *nc_node)
{
- if (atomic_dec_and_test(&nc_node->refcount))
- batadv_nc_node_release(nc_node);
+ kref_put(&nc_node->refcount, batadv_nc_node_release);
}
/**
- * 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);
}
/**
@@ -541,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;
@@ -797,7 +814,7 @@ static struct batadv_nc_node
if (!batadv_compare_eth(nc_node->addr, orig_node->orig))
continue;
- if (!atomic_inc_not_zero(&nc_node->refcount))
+ if (!kref_get_unless_zero(&nc_node->refcount))
continue;
/* Found a match */
@@ -841,14 +858,15 @@ static struct batadv_nc_node
if (!nc_node)
return NULL;
- if (!atomic_inc_not_zero(&orig_neigh_node->refcount))
+ if (!kref_get_unless_zero(&orig_neigh_node->refcount))
goto free;
/* Initialize nc_node */
INIT_LIST_HEAD(&nc_node->list);
ether_addr_copy(nc_node->addr, orig_node->orig);
nc_node->orig_node = orig_neigh_node;
- atomic_set(&nc_node->refcount, 2);
+ kref_init(&nc_node->refcount);
+ kref_get(&nc_node->refcount);
/* Select ingoing or outgoing coding node */
if (in_coding) {
@@ -967,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);