Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
[deliverable/linux.git] / net / batman-adv / originator.c
index fe578f75c39137c451fcc307e729046bd1d1c3c0..e4cbb0753e37ff6681a20e8912df1f4ad1e74a05 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009-2015 B.A.T.M.A.N. contributors:
+/* Copyright (C) 2009-201 B.A.T.M.A.N. contributors:
  *
  * Marek Lindner, Simon Wunderlich
  *
 #include "originator.h"
 #include "main.h"
 
+#include <linux/atomic.h>
 #include <linux/errno.h>
 #include <linux/etherdevice.h>
 #include <linux/fs.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>
@@ -47,7 +49,13 @@ static struct lock_class_key batadv_orig_hash_lock_class_key;
 
 static void batadv_purge_orig(struct work_struct *work);
 
-/* returns 1 if they are the same originator */
+/**
+ * batadv_compare_orig - comparing function used in the originator hash table
+ * @node: node in the local table
+ * @data2: second object to compare the node to
+ *
+ * Return: 1 if they are the same originator
+ */
 int batadv_compare_orig(const struct hlist_node *node, const void *data2)
 {
        const void *data1 = container_of(node, struct batadv_orig_node,
@@ -61,7 +69,7 @@ int batadv_compare_orig(const struct hlist_node *node, const void *data2)
  * @orig_node: the originator serving the VLAN
  * @vid: the VLAN identifier
  *
- * Returns the vlan object identified by vid and belonging to orig_node or NULL
+ * Return: the vlan object identified by vid and belonging to orig_node or NULL
  * if it does not exist.
  */
 struct batadv_orig_node_vlan *
@@ -75,7 +83,7 @@ batadv_orig_node_vlan_get(struct batadv_orig_node *orig_node,
                if (tmp->vid != vid)
                        continue;
 
-               if (!atomic_inc_not_zero(&tmp->refcount))
+               if (!kref_get_unless_zero(&tmp->refcount))
                        continue;
 
                vlan = tmp;
@@ -93,7 +101,7 @@ batadv_orig_node_vlan_get(struct batadv_orig_node *orig_node,
  * @orig_node: the originator serving the VLAN
  * @vid: the VLAN identifier
  *
- * Returns NULL in case of failure or the vlan object identified by vid and
+ * Return: NULL in case of failure or the vlan object identified by vid and
  * belonging to orig_node otherwise. The object is created and added to the list
  * if it does not exist.
  *
@@ -116,7 +124,8 @@ batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
        if (!vlan)
                goto out;
 
-       atomic_set(&vlan->refcount, 2);
+       kref_init(&vlan->refcount);
+       kref_get(&vlan->refcount);
        vlan->vid = vid;
 
        hlist_add_head_rcu(&vlan->list, &orig_node->vlan_list);
@@ -128,14 +137,27 @@ out:
 }
 
 /**
- * batadv_orig_node_vlan_free_ref - decrement the refcounter and possibly free
+ * batadv_orig_node_vlan_release - release originator-vlan object from lists
+ *  and queue for free after rcu grace period
+ * @ref: kref pointer of the originator-vlan object
+ */
+static void batadv_orig_node_vlan_release(struct kref *ref)
+{
+       struct batadv_orig_node_vlan *orig_vlan;
+
+       orig_vlan = container_of(ref, struct batadv_orig_node_vlan, refcount);
+
+       kfree_rcu(orig_vlan, rcu);
+}
+
+/**
+ * batadv_orig_node_vlan_put - decrement the refcounter and possibly release
  *  the originator-vlan object
  * @orig_vlan: the originator-vlan object to release
  */
-void batadv_orig_node_vlan_free_ref(struct batadv_orig_node_vlan *orig_vlan)
+void batadv_orig_node_vlan_put(struct batadv_orig_node_vlan *orig_vlan)
 {
-       if (atomic_dec_and_test(&orig_vlan->refcount))
-               kfree_rcu(orig_vlan, rcu);
+       kref_put(&orig_vlan->refcount, batadv_orig_node_vlan_release);
 }
 
 int batadv_originator_init(struct batadv_priv *bat_priv)
@@ -165,99 +187,105 @@ err:
 /**
  * batadv_neigh_ifinfo_release - release neigh_ifinfo from lists and queue for
  *  free after rcu grace period
- * @neigh_ifinfo: the neigh_ifinfo object to release
+ * @ref: kref pointer of the neigh_ifinfo
  */
-static void
-batadv_neigh_ifinfo_release(struct batadv_neigh_ifinfo *neigh_ifinfo)
+static void batadv_neigh_ifinfo_release(struct kref *ref)
 {
+       struct batadv_neigh_ifinfo *neigh_ifinfo;
+
+       neigh_ifinfo = container_of(ref, struct batadv_neigh_ifinfo, refcount);
+
        if (neigh_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
-               batadv_hardif_free_ref(neigh_ifinfo->if_outgoing);
+               batadv_hardif_put(neigh_ifinfo->if_outgoing);
 
        kfree_rcu(neigh_ifinfo, rcu);
 }
 
 /**
- * batadv_neigh_ifinfo_free_ref - decrement the refcounter and possibly release
+ * batadv_neigh_ifinfo_put - decrement the refcounter and possibly release
  *  the neigh_ifinfo
  * @neigh_ifinfo: the neigh_ifinfo object to release
  */
-void batadv_neigh_ifinfo_free_ref(struct batadv_neigh_ifinfo *neigh_ifinfo)
+void batadv_neigh_ifinfo_put(struct batadv_neigh_ifinfo *neigh_ifinfo)
 {
-       if (atomic_dec_and_test(&neigh_ifinfo->refcount))
-               batadv_neigh_ifinfo_release(neigh_ifinfo);
+       kref_put(&neigh_ifinfo->refcount, batadv_neigh_ifinfo_release);
 }
 
 /**
  * batadv_hardif_neigh_release - release hardif neigh node from lists and
  *  queue for free after rcu grace period
- * @hardif_neigh: hardif neigh neighbor to free
+ * @ref: kref pointer of the neigh_node
  */
-static void
-batadv_hardif_neigh_release(struct batadv_hardif_neigh_node *hardif_neigh)
+static void batadv_hardif_neigh_release(struct kref *ref)
 {
+       struct batadv_hardif_neigh_node *hardif_neigh;
+
+       hardif_neigh = container_of(ref, struct batadv_hardif_neigh_node,
+                                   refcount);
+
        spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
        hlist_del_init_rcu(&hardif_neigh->list);
        spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock);
 
-       batadv_hardif_free_ref(hardif_neigh->if_incoming);
+       batadv_hardif_put(hardif_neigh->if_incoming);
        kfree_rcu(hardif_neigh, rcu);
 }
 
 /**
- * batadv_hardif_neigh_free_ref - decrement the hardif neighbors refcounter
+ * batadv_hardif_neigh_put - decrement the hardif neighbors refcounter
  *  and possibly release it
  * @hardif_neigh: hardif neigh neighbor to free
  */
-void batadv_hardif_neigh_free_ref(struct batadv_hardif_neigh_node *hardif_neigh)
+void batadv_hardif_neigh_put(struct batadv_hardif_neigh_node *hardif_neigh)
 {
-       if (atomic_dec_and_test(&hardif_neigh->refcount))
-               batadv_hardif_neigh_release(hardif_neigh);
+       kref_put(&hardif_neigh->refcount, batadv_hardif_neigh_release);
 }
 
 /**
  * batadv_neigh_node_release - release neigh_node from lists and queue for
  *  free after rcu grace period
- * @neigh_node: neigh neighbor to free
+ * @ref: kref pointer of the neigh_node
  */
-static void batadv_neigh_node_release(struct batadv_neigh_node *neigh_node)
+static void batadv_neigh_node_release(struct kref *ref)
 {
        struct hlist_node *node_tmp;
+       struct batadv_neigh_node *neigh_node;
        struct batadv_hardif_neigh_node *hardif_neigh;
        struct batadv_neigh_ifinfo *neigh_ifinfo;
        struct batadv_algo_ops *bao;
 
+       neigh_node = container_of(ref, struct batadv_neigh_node, refcount);
        bao = neigh_node->orig_node->bat_priv->bat_algo_ops;
 
        hlist_for_each_entry_safe(neigh_ifinfo, node_tmp,
                                  &neigh_node->ifinfo_list, list) {
-               batadv_neigh_ifinfo_free_ref(neigh_ifinfo);
+               batadv_neigh_ifinfo_put(neigh_ifinfo);
        }
 
        hardif_neigh = batadv_hardif_neigh_get(neigh_node->if_incoming,
                                               neigh_node->addr);
        if (hardif_neigh) {
                /* batadv_hardif_neigh_get() increases refcount too */
-               batadv_hardif_neigh_free_ref(hardif_neigh);
-               batadv_hardif_neigh_free_ref(hardif_neigh);
+               batadv_hardif_neigh_put(hardif_neigh);
+               batadv_hardif_neigh_put(hardif_neigh);
        }
 
        if (bao->bat_neigh_free)
                bao->bat_neigh_free(neigh_node);
 
-       batadv_hardif_free_ref(neigh_node->if_incoming);
+       batadv_hardif_put(neigh_node->if_incoming);
 
        kfree_rcu(neigh_node, rcu);
 }
 
 /**
- * batadv_neigh_node_free_ref - decrement the neighbors refcounter
- *  and possibly release it
+ * batadv_neigh_node_put - decrement the neighbors refcounter and possibly
+ *  release it
  * @neigh_node: neigh neighbor to free
  */
-void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node)
+void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node)
 {
-       if (atomic_dec_and_test(&neigh_node->refcount))
-               batadv_neigh_node_release(neigh_node);
+       kref_put(&neigh_node->refcount, batadv_neigh_node_release);
 }
 
 /**
@@ -266,7 +294,7 @@ void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node)
  * @if_outgoing: the interface where the payload packet has been received or
  *  the OGM should be sent to
  *
- * Returns the neighbor which should be router for this orig_node/iface.
+ * Return: the neighbor which should be router for this orig_node/iface.
  *
  * The object is returned with refcounter increased by 1.
  */
@@ -286,7 +314,7 @@ batadv_orig_router_get(struct batadv_orig_node *orig_node,
                break;
        }
 
-       if (router && !atomic_inc_not_zero(&router->refcount))
+       if (router && !kref_get_unless_zero(&router->refcount))
                router = NULL;
 
        rcu_read_unlock();
@@ -298,7 +326,7 @@ batadv_orig_router_get(struct batadv_orig_node *orig_node,
  * @orig_node: the orig node to be queried
  * @if_outgoing: the interface for which the ifinfo should be acquired
  *
- * Returns the requested orig_ifinfo or NULL if not found.
+ * Return: the requested orig_ifinfo or NULL if not found.
  *
  * The object is returned with refcounter increased by 1.
  */
@@ -314,7 +342,7 @@ batadv_orig_ifinfo_get(struct batadv_orig_node *orig_node,
                if (tmp->if_outgoing != if_outgoing)
                        continue;
 
-               if (!atomic_inc_not_zero(&tmp->refcount))
+               if (!kref_get_unless_zero(&tmp->refcount))
                        continue;
 
                orig_ifinfo = tmp;
@@ -330,7 +358,7 @@ batadv_orig_ifinfo_get(struct batadv_orig_node *orig_node,
  * @orig_node: the orig node to be queried
  * @if_outgoing: the interface for which the ifinfo should be acquired
  *
- * Returns NULL in case of failure or the orig_ifinfo object for the if_outgoing
+ * Return: NULL in case of failure or the orig_ifinfo object for the if_outgoing
  * interface otherwise. The object is created and added to the list
  * if it does not exist.
  *
@@ -354,7 +382,7 @@ batadv_orig_ifinfo_new(struct batadv_orig_node *orig_node,
                goto out;
 
        if (if_outgoing != BATADV_IF_DEFAULT &&
-           !atomic_inc_not_zero(&if_outgoing->refcount)) {
+           !kref_get_unless_zero(&if_outgoing->refcount)) {
                kfree(orig_ifinfo);
                orig_ifinfo = NULL;
                goto out;
@@ -365,7 +393,8 @@ batadv_orig_ifinfo_new(struct batadv_orig_node *orig_node,
        orig_ifinfo->batman_seqno_reset = reset_time;
        orig_ifinfo->if_outgoing = if_outgoing;
        INIT_HLIST_NODE(&orig_ifinfo->list);
-       atomic_set(&orig_ifinfo->refcount, 2);
+       kref_init(&orig_ifinfo->refcount);
+       kref_get(&orig_ifinfo->refcount);
        hlist_add_head_rcu(&orig_ifinfo->list,
                           &orig_node->ifinfo_list);
 out:
@@ -375,12 +404,12 @@ out:
 
 /**
  * batadv_neigh_ifinfo_get - find the ifinfo from an neigh_node
- * @neigh_node: the neigh node to be queried
+ * @neigh: the neigh node to be queried
  * @if_outgoing: the interface for which the ifinfo should be acquired
  *
  * The object is returned with refcounter increased by 1.
  *
- * Returns the requested neigh_ifinfo or NULL if not found
+ * Return: the requested neigh_ifinfo or NULL if not found
  */
 struct batadv_neigh_ifinfo *
 batadv_neigh_ifinfo_get(struct batadv_neigh_node *neigh,
@@ -395,7 +424,7 @@ batadv_neigh_ifinfo_get(struct batadv_neigh_node *neigh,
                if (tmp_neigh_ifinfo->if_outgoing != if_outgoing)
                        continue;
 
-               if (!atomic_inc_not_zero(&tmp_neigh_ifinfo->refcount))
+               if (!kref_get_unless_zero(&tmp_neigh_ifinfo->refcount))
                        continue;
 
                neigh_ifinfo = tmp_neigh_ifinfo;
@@ -408,10 +437,10 @@ batadv_neigh_ifinfo_get(struct batadv_neigh_node *neigh,
 
 /**
  * batadv_neigh_ifinfo_new - search and possibly create an neigh_ifinfo object
- * @neigh_node: the neigh node to be queried
+ * @neigh: the neigh node to be queried
  * @if_outgoing: the interface for which the ifinfo should be acquired
  *
- * Returns NULL in case of failure or the neigh_ifinfo object for the
+ * Return: NULL in case of failure or the neigh_ifinfo object for the
  * if_outgoing interface otherwise. The object is created and added to the list
  * if it does not exist.
  *
@@ -433,14 +462,15 @@ batadv_neigh_ifinfo_new(struct batadv_neigh_node *neigh,
        if (!neigh_ifinfo)
                goto out;
 
-       if (if_outgoing && !atomic_inc_not_zero(&if_outgoing->refcount)) {
+       if (if_outgoing && !kref_get_unless_zero(&if_outgoing->refcount)) {
                kfree(neigh_ifinfo);
                neigh_ifinfo = NULL;
                goto out;
        }
 
        INIT_HLIST_NODE(&neigh_ifinfo->list);
-       atomic_set(&neigh_ifinfo->refcount, 2);
+       kref_init(&neigh_ifinfo->refcount);
+       kref_get(&neigh_ifinfo->refcount);
        neigh_ifinfo->if_outgoing = if_outgoing;
 
        hlist_add_head_rcu(&neigh_ifinfo->list, &neigh->ifinfo_list);
@@ -459,7 +489,8 @@ out:
  *
  * Looks for and possibly returns a neighbour belonging to this originator list
  * which is connected through the provided hard interface.
- * Returns NULL if the neighbour is not found.
+ *
+ * Return: neighbor when found. Othwerwise NULL
  */
 static struct batadv_neigh_node *
 batadv_neigh_node_get(const struct batadv_orig_node *orig_node,
@@ -476,7 +507,7 @@ batadv_neigh_node_get(const struct batadv_orig_node *orig_node,
                if (tmp_neigh_node->if_incoming != hard_iface)
                        continue;
 
-               if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
+               if (!kref_get_unless_zero(&tmp_neigh_node->refcount))
                        continue;
 
                res = tmp_neigh_node;
@@ -492,7 +523,7 @@ batadv_neigh_node_get(const struct batadv_orig_node *orig_node,
  * @hard_iface: the interface this neighbour is connected to
  * @neigh_addr: the interface address of the neighbour to retrieve
  *
- * Returns the hardif neighbour node if found or created or NULL otherwise.
+ * Return: the hardif neighbour node if found or created or NULL otherwise.
  */
 static struct batadv_hardif_neigh_node *
 batadv_hardif_neigh_create(struct batadv_hard_iface *hard_iface,
@@ -508,12 +539,12 @@ batadv_hardif_neigh_create(struct batadv_hard_iface *hard_iface,
        if (hardif_neigh)
                goto out;
 
-       if (!atomic_inc_not_zero(&hard_iface->refcount))
+       if (!kref_get_unless_zero(&hard_iface->refcount))
                goto out;
 
        hardif_neigh = kzalloc(sizeof(*hardif_neigh), GFP_ATOMIC);
        if (!hardif_neigh) {
-               batadv_hardif_free_ref(hard_iface);
+               batadv_hardif_put(hard_iface);
                goto out;
        }
 
@@ -522,7 +553,7 @@ batadv_hardif_neigh_create(struct batadv_hard_iface *hard_iface,
        hardif_neigh->if_incoming = hard_iface;
        hardif_neigh->last_seen = jiffies;
 
-       atomic_set(&hardif_neigh->refcount, 1);
+       kref_init(&hardif_neigh->refcount);
 
        if (bat_priv->bat_algo_ops->bat_hardif_neigh_init)
                bat_priv->bat_algo_ops->bat_hardif_neigh_init(hardif_neigh);
@@ -540,7 +571,7 @@ out:
  * @hard_iface: the interface this neighbour is connected to
  * @neigh_addr: the interface address of the neighbour to retrieve
  *
- * Returns the hardif neighbour node if found or created or NULL otherwise.
+ * Return: the hardif neighbour node if found or created or NULL otherwise.
  */
 static struct batadv_hardif_neigh_node *
 batadv_hardif_neigh_get_or_create(struct batadv_hard_iface *hard_iface,
@@ -562,7 +593,8 @@ batadv_hardif_neigh_get_or_create(struct batadv_hard_iface *hard_iface,
  * @neigh_addr: the address of the neighbour
  *
  * Looks for and possibly returns a neighbour belonging to this hard interface.
- * Returns NULL if the neighbour is not found.
+ *
+ * Return: neighbor when found. Othwerwise NULL
  */
 struct batadv_hardif_neigh_node *
 batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface,
@@ -576,7 +608,7 @@ batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface,
                if (!batadv_compare_eth(tmp_hardif_neigh->addr, neigh_addr))
                        continue;
 
-               if (!atomic_inc_not_zero(&tmp_hardif_neigh->refcount))
+               if (!kref_get_unless_zero(&tmp_hardif_neigh->refcount))
                        continue;
 
                hardif_neigh = tmp_hardif_neigh;
@@ -594,7 +626,8 @@ batadv_hardif_neigh_get(const struct batadv_hard_iface *hard_iface,
  * @neigh_addr: the mac address of the neighbour interface
  *
  * Allocates a new neigh_node object and initialises all the generic fields.
- * Returns the new object or NULL on failure.
+ *
+ * Return: neighbor when found. Othwerwise NULL
  */
 struct batadv_neigh_node *
 batadv_neigh_node_new(struct batadv_orig_node *orig_node,
@@ -617,7 +650,7 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node,
        if (!neigh_node)
                goto out;
 
-       if (!atomic_inc_not_zero(&hard_iface->refcount)) {
+       if (!kref_get_unless_zero(&hard_iface->refcount)) {
                kfree(neigh_node);
                neigh_node = NULL;
                goto out;
@@ -632,14 +665,15 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node,
        neigh_node->orig_node = orig_node;
 
        /* extra reference for return */
-       atomic_set(&neigh_node->refcount, 2);
+       kref_init(&neigh_node->refcount);
+       kref_get(&neigh_node->refcount);
 
        spin_lock_bh(&orig_node->neigh_list_lock);
        hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
        spin_unlock_bh(&orig_node->neigh_list_lock);
 
        /* increment unique neighbor refcount */
-       atomic_inc(&hardif_neigh->refcount);
+       kref_get(&hardif_neigh->refcount);
 
        batadv_dbg(BATADV_DBG_BATMAN, orig_node->bat_priv,
                   "Creating new neighbor %pM for orig_node %pM on interface %s\n",
@@ -647,7 +681,7 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node,
 
 out:
        if (hardif_neigh)
-               batadv_hardif_neigh_free_ref(hardif_neigh);
+               batadv_hardif_neigh_put(hardif_neigh);
        return neigh_node;
 }
 
@@ -656,7 +690,7 @@ out:
  * @seq: neighbour table seq_file struct
  * @offset: not used
  *
- * Always returns 0.
+ * Return: always 0
  */
 int batadv_hardif_neigh_seq_print_text(struct seq_file *seq, void *offset)
 {
@@ -673,7 +707,7 @@ int batadv_hardif_neigh_seq_print_text(struct seq_file *seq, void *offset)
                   primary_if->net_dev->dev_addr, net_dev->name,
                   bat_priv->bat_algo_ops->name);
 
-       batadv_hardif_free_ref(primary_if);
+       batadv_hardif_put(primary_if);
 
        if (!bat_priv->bat_algo_ops->bat_neigh_print) {
                seq_puts(seq,
@@ -688,32 +722,34 @@ int batadv_hardif_neigh_seq_print_text(struct seq_file *seq, void *offset)
 /**
  * batadv_orig_ifinfo_release - release orig_ifinfo from lists and queue for
  *  free after rcu grace period
- * @orig_ifinfo: the orig_ifinfo object to release
+ * @ref: kref pointer of the orig_ifinfo
  */
-static void batadv_orig_ifinfo_release(struct batadv_orig_ifinfo *orig_ifinfo)
+static void batadv_orig_ifinfo_release(struct kref *ref)
 {
+       struct batadv_orig_ifinfo *orig_ifinfo;
        struct batadv_neigh_node *router;
 
+       orig_ifinfo = container_of(ref, struct batadv_orig_ifinfo, refcount);
+
        if (orig_ifinfo->if_outgoing != BATADV_IF_DEFAULT)
-               batadv_hardif_free_ref(orig_ifinfo->if_outgoing);
+               batadv_hardif_put(orig_ifinfo->if_outgoing);
 
        /* this is the last reference to this object */
        router = rcu_dereference_protected(orig_ifinfo->router, true);
        if (router)
-               batadv_neigh_node_free_ref(router);
+               batadv_neigh_node_put(router);
 
        kfree_rcu(orig_ifinfo, rcu);
 }
 
 /**
- * batadv_orig_ifinfo_free_ref - decrement the refcounter and possibly release
+ * batadv_orig_ifinfo_put - decrement the refcounter and possibly release
  *  the orig_ifinfo
  * @orig_ifinfo: the orig_ifinfo object to release
  */
-void batadv_orig_ifinfo_free_ref(struct batadv_orig_ifinfo *orig_ifinfo)
+void batadv_orig_ifinfo_put(struct batadv_orig_ifinfo *orig_ifinfo)
 {
-       if (atomic_dec_and_test(&orig_ifinfo->refcount))
-               batadv_orig_ifinfo_release(orig_ifinfo);
+       kref_put(&orig_ifinfo->refcount, batadv_orig_ifinfo_release);
 }
 
 /**
@@ -740,27 +776,30 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
 /**
  * batadv_orig_node_release - release orig_node from lists and queue for
  *  free after rcu grace period
- * @orig_node: the orig node to free
+ * @ref: kref pointer of the orig_node
  */
-static void batadv_orig_node_release(struct batadv_orig_node *orig_node)
+static void batadv_orig_node_release(struct kref *ref)
 {
        struct hlist_node *node_tmp;
        struct batadv_neigh_node *neigh_node;
+       struct batadv_orig_node *orig_node;
        struct batadv_orig_ifinfo *orig_ifinfo;
 
+       orig_node = container_of(ref, struct batadv_orig_node, refcount);
+
        spin_lock_bh(&orig_node->neigh_list_lock);
 
        /* for all neighbors towards this originator ... */
        hlist_for_each_entry_safe(neigh_node, node_tmp,
                                  &orig_node->neigh_list, list) {
                hlist_del_rcu(&neigh_node->list);
-               batadv_neigh_node_free_ref(neigh_node);
+               batadv_neigh_node_put(neigh_node);
        }
 
        hlist_for_each_entry_safe(orig_ifinfo, node_tmp,
                                  &orig_node->ifinfo_list, list) {
                hlist_del_rcu(&orig_ifinfo->list);
-               batadv_orig_ifinfo_free_ref(orig_ifinfo);
+               batadv_orig_ifinfo_put(orig_ifinfo);
        }
        spin_unlock_bh(&orig_node->neigh_list_lock);
 
@@ -771,14 +810,13 @@ static void batadv_orig_node_release(struct batadv_orig_node *orig_node)
 }
 
 /**
- * batadv_orig_node_free_ref - decrement the orig node refcounter and possibly
+ * batadv_orig_node_put - decrement the orig node refcounter and possibly
  *  release it
  * @orig_node: the orig node to free
  */
-void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node)
+void batadv_orig_node_put(struct batadv_orig_node *orig_node)
 {
-       if (atomic_dec_and_test(&orig_node->refcount))
-               batadv_orig_node_release(orig_node);
+       kref_put(&orig_node->refcount, batadv_orig_node_release);
 }
 
 void batadv_originator_free(struct batadv_priv *bat_priv)
@@ -805,7 +843,7 @@ void batadv_originator_free(struct batadv_priv *bat_priv)
                hlist_for_each_entry_safe(orig_node, node_tmp,
                                          head, hash_entry) {
                        hlist_del_rcu(&orig_node->hash_entry);
-                       batadv_orig_node_free_ref(orig_node);
+                       batadv_orig_node_put(orig_node);
                }
                spin_unlock_bh(list_lock);
        }
@@ -820,7 +858,8 @@ void batadv_originator_free(struct batadv_priv *bat_priv)
  *
  * Creates a new originator object and initialise all the generic fields.
  * The new object is not added to the originator list.
- * Returns the newly created object or NULL on failure.
+ *
+ * Return: the newly created object or NULL on failure.
  */
 struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
                                              const u8 *addr)
@@ -849,7 +888,8 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
        batadv_nc_init_orig(orig_node);
 
        /* extra reference for return */
-       atomic_set(&orig_node->refcount, 2);
+       kref_init(&orig_node->refcount);
+       kref_get(&orig_node->refcount);
 
        orig_node->bat_priv = bat_priv;
        ether_addr_copy(orig_node->orig, addr);
@@ -877,7 +917,7 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
         * Immediately release vlan since it is not needed anymore in this
         * context
         */
-       batadv_orig_node_vlan_free_ref(vlan);
+       batadv_orig_node_vlan_put(vlan);
 
        for (i = 0; i < BATADV_FRAG_BUFFER_COUNT; i++) {
                INIT_HLIST_HEAD(&orig_node->fragments[i].head);
@@ -926,7 +966,7 @@ batadv_purge_neigh_ifinfo(struct batadv_priv *bat_priv,
                           neigh->addr, if_outgoing->net_dev->name);
 
                hlist_del_rcu(&neigh_ifinfo->list);
-               batadv_neigh_ifinfo_free_ref(neigh_ifinfo);
+               batadv_neigh_ifinfo_put(neigh_ifinfo);
        }
 
        spin_unlock_bh(&neigh->ifinfo_lock);
@@ -937,7 +977,7 @@ batadv_purge_neigh_ifinfo(struct batadv_priv *bat_priv,
  * @bat_priv: the bat priv with all the soft interface information
  * @orig_node: orig node which is to be checked
  *
- * Returns true if any ifinfo entry was purged, false otherwise.
+ * Return: true if any ifinfo entry was purged, false otherwise.
  */
 static bool
 batadv_purge_orig_ifinfo(struct batadv_priv *bat_priv,
@@ -972,10 +1012,10 @@ batadv_purge_orig_ifinfo(struct batadv_priv *bat_priv,
                ifinfo_purged = true;
 
                hlist_del_rcu(&orig_ifinfo->list);
-               batadv_orig_ifinfo_free_ref(orig_ifinfo);
+               batadv_orig_ifinfo_put(orig_ifinfo);
                if (orig_node->last_bonding_candidate == orig_ifinfo) {
                        orig_node->last_bonding_candidate = NULL;
-                       batadv_orig_ifinfo_free_ref(orig_ifinfo);
+                       batadv_orig_ifinfo_put(orig_ifinfo);
                }
        }
 
@@ -989,7 +1029,7 @@ batadv_purge_orig_ifinfo(struct batadv_priv *bat_priv,
  * @bat_priv: the bat priv with all the soft interface information
  * @orig_node: orig node which is to be checked
  *
- * Returns true if any neighbor was purged, false otherwise
+ * Return: true if any neighbor was purged, false otherwise
  */
 static bool
 batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
@@ -1029,7 +1069,7 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
                        neigh_purged = true;
 
                        hlist_del_rcu(&neigh_node->list);
-                       batadv_neigh_node_free_ref(neigh_node);
+                       batadv_neigh_node_put(neigh_node);
                } else {
                        /* only necessary if not the whole neighbor is to be
                         * deleted, but some interface has been removed.
@@ -1048,7 +1088,7 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
  * @orig_node: orig node which is to be checked
  * @if_outgoing: the interface for which the metric should be compared
  *
- * Returns the current best neighbor, with refcount increased.
+ * Return: the current best neighbor, with refcount increased.
  */
 static struct batadv_neigh_node *
 batadv_find_best_neighbor(struct batadv_priv *bat_priv,
@@ -1064,11 +1104,11 @@ batadv_find_best_neighbor(struct batadv_priv *bat_priv,
                                                best, if_outgoing) <= 0))
                        continue;
 
-               if (!atomic_inc_not_zero(&neigh->refcount))
+               if (!kref_get_unless_zero(&neigh->refcount))
                        continue;
 
                if (best)
-                       batadv_neigh_node_free_ref(best);
+                       batadv_neigh_node_put(best);
 
                best = neigh;
        }
@@ -1085,7 +1125,7 @@ batadv_find_best_neighbor(struct batadv_priv *bat_priv,
  * This function checks if the orig_node or substructures of it have become
  * obsolete, and purges this information if that's the case.
  *
- * Returns true if the orig_node is to be removed, false otherwise.
+ * Return: true if the orig_node is to be removed, false otherwise.
  */
 static bool batadv_purge_orig_node(struct batadv_priv *bat_priv,
                                   struct batadv_orig_node *orig_node)
@@ -1114,7 +1154,7 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv,
        batadv_update_route(bat_priv, orig_node, BATADV_IF_DEFAULT,
                            best_neigh_node);
        if (best_neigh_node)
-               batadv_neigh_node_free_ref(best_neigh_node);
+               batadv_neigh_node_put(best_neigh_node);
 
        /* ... then for all other interfaces. */
        rcu_read_lock();
@@ -1131,7 +1171,7 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv,
                batadv_update_route(bat_priv, orig_node, hard_iface,
                                    best_neigh_node);
                if (best_neigh_node)
-                       batadv_neigh_node_free_ref(best_neigh_node);
+                       batadv_neigh_node_put(best_neigh_node);
        }
        rcu_read_unlock();
 
@@ -1164,7 +1204,7 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv)
                                batadv_tt_global_del_orig(orig_node->bat_priv,
                                                          orig_node, -1,
                                                          "originator timed out");
-                               batadv_orig_node_free_ref(orig_node);
+                               batadv_orig_node_put(orig_node);
                                continue;
                        }
 
@@ -1210,7 +1250,7 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)
                   primary_if->net_dev->dev_addr, net_dev->name,
                   bat_priv->bat_algo_ops->name);
 
-       batadv_hardif_free_ref(primary_if);
+       batadv_hardif_put(primary_if);
 
        if (!bat_priv->bat_algo_ops->bat_orig_print) {
                seq_puts(seq,
@@ -1230,7 +1270,7 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)
  * @seq: debugfs table seq_file struct
  * @offset: not used
  *
- * Returns 0
+ * Return: 0
  */
 int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset)
 {
@@ -1266,7 +1306,7 @@ int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset)
 
 out:
        if (hard_iface)
-               batadv_hardif_free_ref(hard_iface);
+               batadv_hardif_put(hard_iface);
        return 0;
 }
 
This page took 0.062001 seconds and 5 git commands to generate.