nc_worker accesses the originator table during its periodic work, but since the originator table is freed before stopping the worker this leads to a global protection fault.
Fix this by killing the worker (in nc_free) before freeing the originator table.
Moreover tidy up the entire clean up routine by running all the subcomponents freeing procedures first and then killing the TT and the originator tables at the end.
Signed-off-by: Antonio Quartulli ordex@autistici.org ---
v2: - based on top of maint - commit message reworded
main.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/main.c b/main.c index 9c620cd..6fefcb1 100644 --- a/main.c +++ b/main.c @@ -163,14 +163,22 @@ void batadv_mesh_free(struct net_device *soft_iface) batadv_vis_quit(bat_priv);
batadv_gw_node_purge(bat_priv); - batadv_originator_free(bat_priv); batadv_nc_free(bat_priv); + batadv_dat_free(bat_priv); + batadv_bla_free(bat_priv);
+ /* free the TT and the originator tables only after having terminated all + * the other minor components which may use these structures for their + * purposes + */ batadv_tt_free(bat_priv);
- batadv_bla_free(bat_priv); - - batadv_dat_free(bat_priv); + /* since the originator clean up routine is the one accessing the TT + * tables as well, invoke it as last step so that any race condition is + * avoided when the RCU callbacks scheduled by this function access the + * TT data + */ + batadv_originator_free(bat_priv);
free_percpu(bat_priv->bat_counters);