batman-adv: Convert batadv_nc_node 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>
This commit is contained in:
parent
71b7e3d316
commit
daf99b4810
@ -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,23 +210,26 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -797,7 +801,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 */
|
||||
@ -848,7 +852,8 @@ static struct batadv_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) {
|
||||
|
@ -1067,7 +1067,7 @@ struct batadv_tt_roam_node {
|
||||
struct batadv_nc_node {
|
||||
struct list_head list;
|
||||
u8 addr[ETH_ALEN];
|
||||
atomic_t refcount;
|
||||
struct kref refcount;
|
||||
struct rcu_head rcu;
|
||||
struct batadv_orig_node *orig_node;
|
||||
unsigned long last_seen;
|
||||
|
Loading…
Reference in New Issue
Block a user