diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 78fd4eab2169fc197967c2fa8805905213a97907..0b7ab38e74fc1ed276366e1ccda4d16b5a7519c5 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -202,50 +202,30 @@ void batadv_neigh_ifinfo_free_ref(struct batadv_neigh_ifinfo *neigh_ifinfo) } /** - * batadv_hardif_neigh_free_rcu - free the hardif neigh_node - * @rcu: rcu pointer of the neigh_node - */ -static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu) -{ - struct batadv_hardif_neigh_node *hardif_neigh; - - hardif_neigh = container_of(rcu, struct batadv_hardif_neigh_node, rcu); - - batadv_hardif_free_ref_now(hardif_neigh->if_incoming); - kfree(hardif_neigh); -} - -/** - * batadv_hardif_neigh_free_now - decrement the hardif neighbors refcounter - * and possibly free it (without rcu callback) + * 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 */ static void -batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh) +batadv_hardif_neigh_release(struct batadv_hardif_neigh_node *hardif_neigh) { - if (atomic_dec_and_test(&hardif_neigh->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); + 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_neigh_free_rcu(&hardif_neigh->rcu); - } + batadv_hardif_free_ref(hardif_neigh->if_incoming); + kfree_rcu(hardif_neigh, rcu); } /** * batadv_hardif_neigh_free_ref - decrement the hardif neighbors refcounter - * and possibly free it + * and possibly release it * @hardif_neigh: hardif neigh neighbor to free */ void batadv_hardif_neigh_free_ref(struct batadv_hardif_neigh_node *hardif_neigh) { - if (atomic_dec_and_test(&hardif_neigh->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); - - call_rcu(&hardif_neigh->rcu, batadv_hardif_neigh_free_rcu); - } + if (atomic_dec_and_test(&hardif_neigh->refcount)) + batadv_hardif_neigh_release(hardif_neigh); } /** @@ -272,8 +252,8 @@ static void batadv_neigh_node_free_rcu(struct rcu_head *rcu) neigh_node->addr); if (hardif_neigh) { /* batadv_hardif_neigh_get() increases refcount too */ - batadv_hardif_neigh_free_now(hardif_neigh); - batadv_hardif_neigh_free_now(hardif_neigh); + batadv_hardif_neigh_free_ref(hardif_neigh); + batadv_hardif_neigh_free_ref(hardif_neigh); } if (bao->bat_neigh_free)