Hi Lunus, On 21/05/18 22:48, Linus Lüssing wrote: > On Fri, May 18, 2018 at 09:47:53AM +0800, Marek Lindner wrote: >> +/** >> + * batadv_v_elp_tp_start() - start a tp meter session for a neighbor >> + * @neigh: neighbor to run tp meter on >> + */ >> +static void batadv_v_elp_tp_start(struct batadv_hardif_neigh_node *neigh) >> +{ >> + struct batadv_hard_iface *hard_iface = neigh->if_incoming; >> + struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); >> + >> + neigh->bat_v.tp_meter_running = true; >> + batadv_tp_start(bat_priv, neigh->addr, neigh, 10, NULL, BATADV_TP_ELP); >> +} > > This seems racy here? We have no ordering constraints between > the assigment and batadv_tp_start() which might lead to... > >> @@ -152,6 +192,25 @@ static u32 batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh) >> return throughput * 10; >> } >> >> +fallback_throughput: >> + last_tp_run_jiffies = jiffies - neigh->bat_v.last_tp_meter_run; >> + last_tp_run_msecs = jiffies_to_msecs(last_tp_run_jiffies); >> + >> + /* check the tp_meter_running flag before checking the timestamp to >> + * avoid a race condition where a new tp meter session is scheduled >> + * right after the previous tp meter session has completed >> + */ >> + if (!neigh->bat_v.tp_meter_running && >> + last_tp_run_msecs > BATADV_ELP_TP_RUN_INTERVAL) >> + batadv_v_elp_tp_start(neigh); > > ...multiple instances potentially being started at the same time here? > - batadv_tp_start() is only invoked by batadv_v_elp_get_throughput(); - batadv_v_elp_get_throughput() is only invoked by batadv_v_elp_throughput_metric_update(); - batadv_v_elp_throughput_metric_update() is a periodic function executed by a timer and we can't have concurrent executions (unless we use crazy interval values). Maybe we should add a comment to make this more clear? -- Antonio Quartulli