Author: marek Date: 2009-09-27 02:21:54 +0000 (Sun, 27 Sep 2009) New Revision: 1439
Modified: trunk/batman-adv-kernelland/hard-interface.c trunk/batman-adv-kernelland/routing.c Log: [batman-adv] fixing race condition while handling lots of data
The callback batman_data_ready() set the variable data_ready_cond to true before waking up the packet handling thread. When the thread has completed its work it will sleep and sets the variable back to false. When the system has to handle large quantities of traffic the callback might be called several times while the packet handling thread runs. The status variable will be overwritten once the thread is done which might leave packets in the socket buffer. If the socket buffer is full no more packets are accepted and the callback won't be triggered. Therefore the packet receive thread has to reset the variable at the very beginning.
Modified: trunk/batman-adv-kernelland/hard-interface.c =================================================================== --- trunk/batman-adv-kernelland/hard-interface.c 2009-09-15 19:24:14 UTC (rev 1438) +++ trunk/batman-adv-kernelland/hard-interface.c 2009-09-27 02:21:54 UTC (rev 1439) @@ -148,7 +148,7 @@ active_ifs--;
debug_log(LOG_TYPE_NOTICE, "Interface deactivated: %s\n", - batman_if->dev); + batman_if->dev); }
/* (re)activate given interface. */ @@ -209,6 +209,9 @@ if (batman_if->if_num == 0) set_main_if_addr(batman_if->net_dev->dev_addr);
+ debug_log(LOG_TYPE_NOTICE, "Interface activated: %s\n", + batman_if->dev); + return;
bind_err:
Modified: trunk/batman-adv-kernelland/routing.c =================================================================== --- trunk/batman-adv-kernelland/routing.c 2009-09-15 19:24:14 UTC (rev 1438) +++ trunk/batman-adv-kernelland/routing.c 2009-09-27 02:21:54 UTC (rev 1439) @@ -625,6 +625,8 @@
wait_event_interruptible(thread_wait, (atomic_read(&data_ready_cond) || atomic_read(&exit_cond)));
+ atomic_set(&data_ready_cond, 0); + if (kthread_should_stop() || atomic_read(&exit_cond)) break;
@@ -950,8 +952,6 @@ } rcu_read_unlock();
- atomic_set(&data_ready_cond, 0); - } kfree(packet_buff);