So switch to kref instead of using the self-made, atomic_t-based
implementation.

Signed-off-by: Sven Eckelmann <[email protected]>
---
 net/batman-adv/bat_iv_ogm.c            | 21 ++++++-------
 net/batman-adv/distributed-arp-table.c |  2 +-
 net/batman-adv/fragmentation.c         |  2 +-
 net/batman-adv/gateway_client.c        | 14 ++++-----
 net/batman-adv/hard-interface.h        | 12 --------
 net/batman-adv/icmp_socket.c           |  2 +-
 net/batman-adv/network-coding.c        |  4 +--
 net/batman-adv/originator.c            | 54 +++++++++++++---------------------
 net/batman-adv/originator.h            |  2 +-
 net/batman-adv/routing.c               | 22 +++++++-------
 net/batman-adv/send.c                  |  2 +-
 net/batman-adv/translation-table.c     |  6 ++--
 net/batman-adv/types.h                 |  2 +-
 13 files changed, 61 insertions(+), 84 deletions(-)

diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index f128e60..7d61afb 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/jiffies.h>
 #include <linux/list.h>
+#include <linux/kref.h>
 #include <linux/netdevice.h>
 #include <linux/pkt_sched.h>
 #include <linux/printk.h>
@@ -1000,9 +1001,9 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
                neigh_addr = tmp_neigh_node->addr;
                if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
                    tmp_neigh_node->if_incoming == if_incoming &&
-                   atomic_inc_not_zero(&tmp_neigh_node->refcount)) {
+                   kref_get_unless_zero(&tmp_neigh_node->refcount)) {
                        if (WARN(neigh_node, "too many matching neigh_nodes"))
-                               batadv_neigh_node_free_ref(neigh_node);
+                               batadv_neigh_node_put(neigh_node);
                        neigh_node = tmp_neigh_node;
                        continue;
                }
@@ -1113,9 +1114,9 @@ unlock:
        rcu_read_unlock();
 out:
        if (neigh_node)
-               batadv_neigh_node_free_ref(neigh_node);
+               batadv_neigh_node_put(neigh_node);
        if (router)
-               batadv_neigh_node_free_ref(router);
+               batadv_neigh_node_put(router);
        if (neigh_ifinfo)
                batadv_neigh_ifinfo_put(neigh_ifinfo);
        if (router_ifinfo)
@@ -1159,7 +1160,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node 
*orig_node,
                if (tmp_neigh_node->if_incoming != if_incoming)
                        continue;
 
-               if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
+               if (!kref_get_unless_zero(&tmp_neigh_node->refcount))
                        continue;
 
                neigh_node = tmp_neigh_node;
@@ -1262,7 +1263,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node 
*orig_node,
 
 out:
        if (neigh_node)
-               batadv_neigh_node_free_ref(neigh_node);
+               batadv_neigh_node_put(neigh_node);
        return ret;
 }
 
@@ -1565,11 +1566,11 @@ out:
        if (router_ifinfo)
                batadv_neigh_ifinfo_put(router_ifinfo);
        if (router)
-               batadv_neigh_node_free_ref(router);
+               batadv_neigh_node_put(router);
        if (router_router)
-               batadv_neigh_node_free_ref(router_router);
+               batadv_neigh_node_put(router_router);
        if (orig_neigh_router)
-               batadv_neigh_node_free_ref(orig_neigh_router);
+               batadv_neigh_node_put(orig_neigh_router);
        if (hardif_neigh)
                batadv_hardif_neigh_put(hardif_neigh);
 
@@ -1865,7 +1866,7 @@ static void batadv_iv_ogm_orig_print(struct batadv_priv 
*bat_priv,
                        batman_count++;
 
 next:
-                       batadv_neigh_node_free_ref(neigh_node);
+                       batadv_neigh_node_put(neigh_node);
                        if (n_ifinfo)
                                batadv_neigh_ifinfo_put(n_ifinfo);
                }
diff --git a/net/batman-adv/distributed-arp-table.c 
b/net/batman-adv/distributed-arp-table.c
index 34d0950..fa605c3 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -674,7 +674,7 @@ static bool batadv_dat_send_data(struct batadv_priv 
*bat_priv,
                        ret = true;
                }
 free_neigh:
-               batadv_neigh_node_free_ref(neigh_node);
+               batadv_neigh_node_put(neigh_node);
 free_orig:
                batadv_orig_node_free_ref(cand[i].orig_node);
        }
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
index 80eddf4..87b127c 100644
--- a/net/batman-adv/fragmentation.c
+++ b/net/batman-adv/fragmentation.c
@@ -387,7 +387,7 @@ out:
        if (orig_node_dst)
                batadv_orig_node_free_ref(orig_node_dst);
        if (neigh_node)
-               batadv_neigh_node_free_ref(neigh_node);
+               batadv_neigh_node_put(neigh_node);
        return ret;
 }
 
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 8d9933a..a5b92ef 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -234,7 +234,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
                batadv_gw_node_put(gw_node);
 
 next:
-               batadv_neigh_node_free_ref(router);
+               batadv_neigh_node_put(router);
                if (router_ifinfo)
                        batadv_neigh_ifinfo_put(router_ifinfo);
        }
@@ -351,7 +351,7 @@ out:
        if (next_gw)
                batadv_gw_node_put(next_gw);
        if (router)
-               batadv_neigh_node_free_ref(router);
+               batadv_neigh_node_put(router);
        if (router_ifinfo)
                batadv_neigh_ifinfo_put(router_ifinfo);
 }
@@ -416,9 +416,9 @@ out:
        if (curr_gw_orig)
                batadv_orig_node_free_ref(curr_gw_orig);
        if (router_gw)
-               batadv_neigh_node_free_ref(router_gw);
+               batadv_neigh_node_put(router_gw);
        if (router_orig)
-               batadv_neigh_node_free_ref(router_orig);
+               batadv_neigh_node_put(router_orig);
        if (router_gw_tq)
                batadv_neigh_ifinfo_put(router_gw_tq);
        if (router_orig_tq)
@@ -624,7 +624,7 @@ out:
        if (router_ifinfo)
                batadv_neigh_ifinfo_put(router_ifinfo);
        if (router)
-               batadv_neigh_node_free_ref(router);
+               batadv_neigh_node_put(router);
        return ret;
 }
 
@@ -883,8 +883,8 @@ out:
        if (gw_node)
                batadv_gw_node_put(gw_node);
        if (neigh_old)
-               batadv_neigh_node_free_ref(neigh_old);
+               batadv_neigh_node_put(neigh_old);
        if (neigh_curr)
-               batadv_neigh_node_free_ref(neigh_curr);
+               batadv_neigh_node_put(neigh_curr);
        return out_of_range;
 }
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h
index 5a31420..7b12ea8 100644
--- a/net/batman-adv/hard-interface.h
+++ b/net/batman-adv/hard-interface.h
@@ -75,18 +75,6 @@ batadv_hardif_free_ref(struct batadv_hard_iface *hard_iface)
                call_rcu(&hard_iface->rcu, batadv_hardif_free_rcu);
 }
 
-/**
- * batadv_hardif_free_ref_now - decrement the hard interface refcounter and
- *  possibly free it (without rcu callback)
- * @hard_iface: the hard interface to free
- */
-static inline void
-batadv_hardif_free_ref_now(struct batadv_hard_iface *hard_iface)
-{
-       if (atomic_dec_and_test(&hard_iface->refcount))
-               batadv_hardif_free_rcu(&hard_iface->rcu);
-}
-
 static inline struct batadv_hard_iface *
 batadv_primary_if_get_selected(struct batadv_priv *bat_priv)
 {
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index bcabb5e..d6574cb 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -290,7 +290,7 @@ out:
        if (primary_if)
                batadv_hardif_free_ref(primary_if);
        if (neigh_node)
-               batadv_neigh_node_free_ref(neigh_node);
+               batadv_neigh_node_put(neigh_node);
        if (orig_node)
                batadv_orig_node_free_ref(orig_node);
        return len;
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
index 329219b..41f0c2c 100644
--- a/net/batman-adv/network-coding.c
+++ b/net/batman-adv/network-coding.c
@@ -1228,9 +1228,9 @@ static bool batadv_nc_code_packets(struct batadv_priv 
*bat_priv,
        res = true;
 out:
        if (router_neigh)
-               batadv_neigh_node_free_ref(router_neigh);
+               batadv_neigh_node_put(router_neigh);
        if (router_coding)
-               batadv_neigh_node_free_ref(router_coding);
+               batadv_neigh_node_put(router_coding);
        if (router_neigh_ifinfo)
                batadv_neigh_ifinfo_put(router_neigh_ifinfo);
        if (router_coding_ifinfo)
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 919f464..1f10658 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -227,10 +227,11 @@ void batadv_hardif_neigh_put(struct 
batadv_hardif_neigh_node *hardif_neigh)
 }
 
 /**
- * batadv_neigh_node_free_rcu - free the neigh_node
- * @rcu: rcu pointer of the neigh_node
+ * batadv_neigh_node_release - release neigh_node from lists and queue for
+ *  free after rcu grace period
+ * @ref: kref pointer of the neigh_node
  */
-static void batadv_neigh_node_free_rcu(struct rcu_head *rcu)
+static void batadv_neigh_node_release(struct kref *ref)
 {
        struct hlist_node *node_tmp;
        struct batadv_neigh_node *neigh_node;
@@ -238,7 +239,7 @@ static void batadv_neigh_node_free_rcu(struct rcu_head *rcu)
        struct batadv_neigh_ifinfo *neigh_ifinfo;
        struct batadv_algo_ops *bao;
 
-       neigh_node = container_of(rcu, struct batadv_neigh_node, rcu);
+       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,
@@ -257,32 +258,18 @@ static void batadv_neigh_node_free_rcu(struct rcu_head 
*rcu)
        if (bao->bat_neigh_free)
                bao->bat_neigh_free(neigh_node);
 
-       batadv_hardif_free_ref_now(neigh_node->if_incoming);
+       batadv_hardif_free_ref(neigh_node->if_incoming);
 
-       kfree(neigh_node);
+       kfree_rcu(neigh_node, rcu);
 }
 
 /**
- * batadv_neigh_node_free_ref_now - decrement the neighbors refcounter
- *  and possibly free it (without rcu callback)
+ * batadv_neigh_node_put - decrement the  neighbors refcounter and possibly 
free
  * @neigh_node: neigh neighbor to free
  */
-static void
-batadv_neigh_node_free_ref_now(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_free_rcu(&neigh_node->rcu);
-}
-
-/**
- * batadv_neigh_node_free_ref - decrement the neighbors refcounter
- *  and possibly free it
- * @neigh_node: neigh neighbor to free
- */
-void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node)
-{
-       if (atomic_dec_and_test(&neigh_node->refcount))
-               call_rcu(&neigh_node->rcu, batadv_neigh_node_free_rcu);
+       kref_put(&neigh_node->refcount, batadv_neigh_node_release);
 }
 
 /**
@@ -311,7 +298,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();
@@ -504,7 +491,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;
@@ -662,7 +649,8 @@ 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);
@@ -733,7 +721,7 @@ static void batadv_orig_ifinfo_release(struct kref *ref)
        /* 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);
 }
@@ -763,7 +751,7 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
        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_now(neigh_node);
+               batadv_neigh_node_put(neigh_node);
        }
 
        hlist_for_each_entry_safe(orig_ifinfo, node_tmp,
@@ -1047,7 +1035,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.
@@ -1082,11 +1070,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;
        }
@@ -1132,7 +1120,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();
@@ -1149,7 +1137,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();
 
diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h
index db1a65d..b0506ba 100644
--- a/net/batman-adv/originator.h
+++ b/net/batman-adv/originator.h
@@ -49,7 +49,7 @@ struct batadv_neigh_node *
 batadv_neigh_node_new(struct batadv_orig_node *orig_node,
                      struct batadv_hard_iface *hard_iface,
                      const u8 *neigh_addr);
-void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node);
+void batadv_neigh_node_put(struct batadv_neigh_node *neigh_node);
 struct batadv_neigh_node *
 batadv_orig_router_get(struct batadv_orig_node *orig_node,
                       const struct batadv_hard_iface *if_outgoing);
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 1018148..787da48 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -73,7 +73,7 @@ static void _batadv_update_route(struct batadv_priv *bat_priv,
 
        rcu_read_lock();
        curr_router = rcu_dereference(orig_ifinfo->router);
-       if (curr_router && !atomic_inc_not_zero(&curr_router->refcount))
+       if (curr_router && !kref_get_unless_zero(&curr_router->refcount))
                curr_router = NULL;
        rcu_read_unlock();
 
@@ -98,10 +98,10 @@ static void _batadv_update_route(struct batadv_priv 
*bat_priv,
        }
 
        if (curr_router)
-               batadv_neigh_node_free_ref(curr_router);
+               batadv_neigh_node_put(curr_router);
 
        /* increase refcount of new best neighbor */
-       if (neigh_node && !atomic_inc_not_zero(&neigh_node->refcount))
+       if (neigh_node && !kref_get_unless_zero(&neigh_node->refcount))
                neigh_node = NULL;
 
        spin_lock_bh(&orig_node->neigh_list_lock);
@@ -111,7 +111,7 @@ static void _batadv_update_route(struct batadv_priv 
*bat_priv,
 
        /* decrease refcount of previous best neighbor */
        if (curr_router)
-               batadv_neigh_node_free_ref(curr_router);
+               batadv_neigh_node_put(curr_router);
 }
 
 /**
@@ -138,7 +138,7 @@ void batadv_update_route(struct batadv_priv *bat_priv,
 
 out:
        if (router)
-               batadv_neigh_node_free_ref(router);
+               batadv_neigh_node_put(router);
 }
 
 /**
@@ -505,7 +505,7 @@ batadv_find_router(struct batadv_priv *bat_priv,
                if (!cand_router)
                        goto next;
 
-               if (!atomic_inc_not_zero(&cand_router->refcount)) {
+               if (!kref_get_unless_zero(&cand_router->refcount)) {
                        cand_router = NULL;
                        goto next;
                }
@@ -524,7 +524,7 @@ batadv_find_router(struct batadv_priv *bat_priv,
 
                /* mark the first possible candidate */
                if (!first_candidate) {
-                       atomic_inc(&cand_router->refcount);
+                       kref_get(&cand_router->refcount);
                        kref_get(&cand->refcount);
                        first_candidate = cand;
                        first_candidate_router = cand_router;
@@ -545,7 +545,7 @@ batadv_find_router(struct batadv_priv *bat_priv,
 next:
                /* free references */
                if (cand_router) {
-                       batadv_neigh_node_free_ref(cand_router);
+                       batadv_neigh_node_put(cand_router);
                        cand_router = NULL;
                }
                batadv_orig_ifinfo_put(cand);
@@ -562,17 +562,17 @@ next:
         * 3) there is no candidate at all, return the default router
         */
        if (next_candidate) {
-               batadv_neigh_node_free_ref(router);
+               batadv_neigh_node_put(router);
 
                /* remove references to first candidate, we don't need it. */
                if (first_candidate) {
-                       batadv_neigh_node_free_ref(first_candidate_router);
+                       batadv_neigh_node_put(first_candidate_router);
                        batadv_orig_ifinfo_put(first_candidate);
                }
                router = next_candidate_router;
                orig_node->last_bonding_candidate = next_candidate;
        } else if (first_candidate) {
-               batadv_neigh_node_free_ref(router);
+               batadv_neigh_node_put(router);
 
                /* refcounting has already been done in the loop above. */
                router = first_candidate_router;
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index c188f46..06e21fa 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -153,7 +153,7 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
 
 out:
        if (neigh_node)
-               batadv_neigh_node_free_ref(neigh_node);
+               batadv_neigh_node_put(neigh_node);
 
        return ret;
 }
diff --git a/net/batman-adv/translation-table.c 
b/net/batman-adv/translation-table.c
index 096804e..f25b533 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1548,20 +1548,20 @@ batadv_transtable_best_orig(struct batadv_priv 
*bat_priv,
                if (best_router &&
                    bao->bat_neigh_cmp(router, BATADV_IF_DEFAULT,
                                       best_router, BATADV_IF_DEFAULT) <= 0) {
-                       batadv_neigh_node_free_ref(router);
+                       batadv_neigh_node_put(router);
                        continue;
                }
 
                /* release the refcount for the "old" best */
                if (best_router)
-                       batadv_neigh_node_free_ref(best_router);
+                       batadv_neigh_node_put(best_router);
 
                best_entry = orig_entry;
                best_router = router;
        }
 
        if (best_router)
-               batadv_neigh_node_free_ref(best_router);
+               batadv_neigh_node_put(best_router);
 
        return best_entry;
 }
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index a5e4310..75e1b45 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -384,7 +384,7 @@ struct batadv_neigh_node {
        spinlock_t ifinfo_lock; /* protects ifinfo_list and its members */
        struct batadv_hard_iface *if_incoming;
        unsigned long last_seen;
-       atomic_t refcount;
+       struct kref refcount;
        struct rcu_head rcu;
 };
 
-- 
2.6.4

Reply via email to