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 | |
| 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>
| -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)  	batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_MCAST, 1);  	batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_MCAST, 1); +	spin_lock_bh(&bat_priv->tt.commit_lock);  	batadv_mcast_mla_tt_retract(bat_priv, NULL); +	spin_unlock_bh(&bat_priv->tt.commit_lock);  }  /** 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)  	hardif_neigh = container_of(rcu, struct batadv_hardif_neigh_node, rcu); -	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_now(hardif_neigh->if_incoming);  	kfree(hardif_neigh);  } @@ -227,8 +223,13 @@ static void batadv_hardif_neigh_free_rcu(struct rcu_head *rcu)  static void  batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh)  { -	if (atomic_dec_and_test(&hardif_neigh->refcount)) +	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); +  		batadv_hardif_neigh_free_rcu(&hardif_neigh->rcu); +	}  }  /** @@ -238,8 +239,13 @@ batadv_hardif_neigh_free_now(struct batadv_hardif_neigh_node *hardif_neigh)   */  void batadv_hardif_neigh_free_ref(struct batadv_hardif_neigh_node *hardif_neigh)  { -	if (atomic_dec_and_test(&hardif_neigh->refcount)) +	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); +	}  }  /**  | 
