From patchwork Tue Dec 15 23:31:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Eckelmann X-Patchwork-Id: 4815 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=79.140.41.39; helo=v3-1039.vlinux.de; envelope-from=sven@narfation.org; receiver=b.a.t.m.a.n@lists.open-mesh.org Authentication-Results: open-mesh.org; dkim=pass reason="1024-bit key; unprotected key" header.d=narfation.org header.i=@narfation.org header.b=Oi9vfaM3; dkim-adsp=pass; dkim-atps=neutral Received: from v3-1039.vlinux.de (narfation.org [79.140.41.39]) by open-mesh.org (Postfix) with ESMTPS id 854A881954 for ; Wed, 16 Dec 2015 00:32:32 +0100 (CET) Received: from sven-desktop.home.narfation.org (unknown [IPv6:2a02:3100:260c:3afd:2066:82e6:79c1:88d8]) by v3-1039.vlinux.de (Postfix) with ESMTPSA id 5E51A110116; Wed, 16 Dec 2015 00:32:31 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=narfation.org; s=20121; t=1450222351; bh=3SF/F6qu1nWN87lExPttvrFJpP0Y4AU4+jF+AHupyLY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Oi9vfaM3j30j8D/kTem3L0pZLsFMjiD3T1dP2k/7AP9KXqzcG4YI/R16NpJBOLlOO lx6oJFvku+AyWGGU70x2uJFJcPn0H0eR2yT85nFmahPpBcw/lcMvsFaxd1ovH6Gtn4 ax+8VzX9xLRO+C5Ht21gY7LT4U3hG+LRZk+ghnkM= From: Sven Eckelmann To: b.a.t.m.a.n@lists.open-mesh.org Date: Wed, 16 Dec 2015 00:31:51 +0100 Message-Id: <1450222316-1764-18-git-send-email-sven@narfation.org> X-Mailer: git-send-email 2.6.4 In-Reply-To: <1450222316-1764-1-git-send-email-sven@narfation.org> References: <1450222316-1764-1-git-send-email-sven@narfation.org> Subject: [B.A.T.M.A.N.] [PATCH 18/23] batman-adv: Convert batadv_neigh_node to kref X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Dec 2015 23:32:34 -0000 So switch to kref instead of using the self-made, atomic_t-based implementation. Signed-off-by: Sven Eckelmann --- 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 #include #include +#include #include #include #include @@ -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; };