Included changes:
- fix global protection fault by avoiding double call_rcu -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABCAAGBQJRleOoAAoJEADl0hg6qKeOsUUP/A2l5HchUZ0J3+L/Y7sjMKi6 6k7LC7ThEtJ2f4d6vDDZeaS3/HA9PZPkH19D5+4baE9BbNssakutBVwE85DzrEfC 5nromT/UKC0MbzBkBcvrNV6KDlq7SRN5N3xq6O+/IxS27rgKzetIA2AHaVrNbdTs 8s6HZRz9n/sWWdzIr4eGCZ2/uyM3ik6fUvlztHCtTRX0SPwmiv8kRHhOtBQXQbo5 B/rtNItBnP+wk17MM7/Tr6tfP65qcCBO2VAj3hEHbGzojfh1sIe59UG/JL701Ttn fjkkSmIEZ0KwjhaJSMj40gdfuIlbLPS+ZoxXCIxzCKF0k1/lrnyZ+LErlreMu2Ws PmmRsPYfGzhcUbNwteJ0u7T3C/5XlrMcdoBx9MQKmFROWN4W6h3borM/0SKLmwgc m7gLYKlC/z+v8qcSK+Rq4Jv75MclhVhd8NDpD6SWj6T0U2XqyIGgiAtl6b+p4JOp 99Cho5+1kwBOMYWXi5RXZcrxxDV1bqhpurMuwyw0S3EnJ2j9EI9Pb5rup759mMhb RxA9GNzIbKhgCf3qvwMU7NkGJB9kKN8qZltzD+Dsh0rD7EPj9w/oaSjKYEtsUAXA CUqaIyqnBXxIMx/aKHzcACbTjH1mSSmTL3x16yBeb6SOF+lZ++f3UZsOArph1nhZ FIOj7FncrREBElhFs1XX =rTpK -----END PGP SIGNATURE----- Merge tag 'batman-adv-fix-for-davem' of git://git.open-mesh.org/linux-merge Included changes: - fix global protection fault by avoiding double call_rcu Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
7ffc37fc35
@ -156,12 +156,28 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
|
||||
kfree(orig_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_orig_node_free_ref - decrement the orig node refcounter and possibly
|
||||
* schedule an rcu callback for freeing it
|
||||
* @orig_node: the orig node to free
|
||||
*/
|
||||
void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node)
|
||||
{
|
||||
if (atomic_dec_and_test(&orig_node->refcount))
|
||||
call_rcu(&orig_node->rcu, batadv_orig_node_free_rcu);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_orig_node_free_ref_now - decrement the orig node refcounter and
|
||||
* possibly free it (without rcu callback)
|
||||
* @orig_node: the orig node to free
|
||||
*/
|
||||
void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node)
|
||||
{
|
||||
if (atomic_dec_and_test(&orig_node->refcount))
|
||||
batadv_orig_node_free_rcu(&orig_node->rcu);
|
||||
}
|
||||
|
||||
void batadv_originator_free(struct batadv_priv *bat_priv)
|
||||
{
|
||||
struct batadv_hashtable *hash = bat_priv->orig_hash;
|
||||
|
@ -26,6 +26,7 @@ int batadv_originator_init(struct batadv_priv *bat_priv);
|
||||
void batadv_originator_free(struct batadv_priv *bat_priv);
|
||||
void batadv_purge_orig_ref(struct batadv_priv *bat_priv);
|
||||
void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node);
|
||||
void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node);
|
||||
struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
|
||||
const uint8_t *addr);
|
||||
struct batadv_neigh_node *
|
||||
|
@ -144,7 +144,12 @@ static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
|
||||
struct batadv_tt_orig_list_entry *orig_entry;
|
||||
|
||||
orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu);
|
||||
batadv_orig_node_free_ref(orig_entry->orig_node);
|
||||
|
||||
/* We are in an rcu callback here, therefore we cannot use
|
||||
* batadv_orig_node_free_ref() and its call_rcu():
|
||||
* An rcu_barrier() wouldn't wait for that to finish
|
||||
*/
|
||||
batadv_orig_node_free_ref_now(orig_entry->orig_node);
|
||||
kfree(orig_entry);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user