diff options
author | David S. Miller <davem@davemloft.net> | 2016-01-13 14:57:42 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-01-13 14:57:42 -0500 |
commit | 1adbfc435f0897101443975fdbd20e8817ad5fd9 (patch) | |
tree | ab74fffe33fb8ebb0b586c99ca2027a80a04ba35 /net | |
parent | e752991a2e6a1dc33271a6299d5c1c8688f35f95 (diff) | |
parent | bab7c6c3deac70966a3000402c0ea6d0c20edd15 (diff) |
Merge tag 'batman-adv-fix-for-davem' of git://git.open-mesh.org/linux-merge
Antonio Quartulli says:
====================
net: batman-adv 20160114
Included bugfixes:
- avoid freeing batadv_hardif_neigh_node when still in use in other contexts
- prevent lockdep splat in mcast_free during shutdown
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/batman-adv/multicast.c | 2 | ||||
-rw-r--r-- | net/batman-adv/originator.c | 18 |
2 files changed, 14 insertions, 6 deletions
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c index eb76386f8d4b..75fa5013af72 100644 --- a/net/batman-adv/multicast.c +++ b/net/batman-adv/multicast.c | |||
@@ -802,7 +802,9 @@ void batadv_mcast_free(struct batadv_priv *bat_priv) | |||
802 | batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 1); | 802 | batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 1); |
803 | batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 1); | 803 | batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 1); |
804 | 804 | ||
805 | spin_lock_bh(&bat_priv->tt.commit_lock); | ||
805 | batadv_mcast_mla_tt_retract(bat_priv, NULL); | 806 | batadv_mcast_mla_tt_retract(bat_priv, NULL); |
807 | spin_unlock_bh(&bat_priv->tt.commit_lock); | ||
806 | } | 808 | } |
807 | 809 | ||
808 | /** | 810 | /** |
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 3c782a33bdac..ae6d18cafc5a 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -211,10 +211,6 @@ static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu) | |||
211 | 211 | ||
212 | hardif_neigh = container_of(rcu, struct batadv_hardif_neigh_node, rcu); | 212 | hardif_neigh = container_of(rcu, struct batadv_hardif_neigh_node, rcu); |
213 | 213 | ||
214 | spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock); | ||
215 | hlist_del_init_rcu(&hardif_neigh->list); | ||
216 | spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock); | ||
217 | |||
218 | batadv_hardif_free_ref_now(hardif_neigh->if_incoming); | 214 | batadv_hardif_free_ref_now(hardif_neigh->if_incoming); |
219 | kfree(hardif_neigh); | 215 | kfree(hardif_neigh); |
220 | } | 216 | } |
@@ -227,8 +223,13 @@ static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu) | |||
227 | static void | 223 | static void |
228 | batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh) | 224 | batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh) |
229 | { | 225 | { |
230 | if (atomic_dec_and_test(&hardif_neigh->refcount)) | 226 | if (atomic_dec_and_test(&hardif_neigh->refcount)) { |
227 | spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock); | ||
228 | hlist_del_init_rcu(&hardif_neigh->list); | ||
229 | spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock); | ||
230 | |||
231 | batadv_hardif_neigh_free_rcu(&hardif_neigh->rcu); | 231 | batadv_hardif_neigh_free_rcu(&hardif_neigh->rcu); |
232 | } | ||
232 | } | 233 | } |
233 | 234 | ||
234 | /** | 235 | /** |
@@ -238,8 +239,13 @@ batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh) | |||
238 | */ | 239 | */ |
239 | void batadv_hardif_neigh_free_ref(struct batadv_hardif_neigh_node *hardif_neigh) | 240 | void batadv_hardif_neigh_free_ref(struct batadv_hardif_neigh_node *hardif_neigh) |
240 | { | 241 | { |
241 | if (atomic_dec_and_test(&hardif_neigh->refcount)) | 242 | if (atomic_dec_and_test(&hardif_neigh->refcount)) { |
243 | spin_lock_bh(&hardif_neigh->if_incoming->neigh_list_lock); | ||
244 | hlist_del_init_rcu(&hardif_neigh->list); | ||
245 | spin_unlock_bh(&hardif_neigh->if_incoming->neigh_list_lock); | ||
246 | |||
242 | call_rcu(&hardif_neigh->rcu, batadv_hardif_neigh_free_rcu); | 247 | call_rcu(&hardif_neigh->rcu, batadv_hardif_neigh_free_rcu); |
248 | } | ||
243 | } | 249 | } |
244 | 250 | ||
245 | /** | 251 | /** |