[linux-next] LinuxNextTracking branch, master, updated. next-20110624

batman at open-mesh.org batman at open-mesh.org
Fri Jun 24 16:08:51 CEST 2011


The following commit has been merged in the master branch:
commit 1181e1daace88018b2ff66592aa10a4791d705ff
Author: Sven Eckelmann <sven at narfation.org>
Date:   Fri Jan 28 18:34:07 2011 +0100

    batman-adv: Make vis info stack traversal threadsafe
    
    The batman-adv vis server has to a stack which stores all information
    about packets which should be send later. This stack is protected
    with a spinlock that is used to prevent concurrent write access to it.
    
    The send_vis_packets function has to take all elements from the stack
    and send them to other hosts over the primary interface. The send will
    be initiated without the lock which protects the stack.
    
    The implementation using list_for_each_entry_safe has the problem that
    it stores the next element as "safe ptr" to allow the deletion of the
    current element in the list. The list may be modified during the
    unlock/lock pair in the loop body which may make the safe pointer
    not pointing to correct next element.
    
    It is safer to remove and use the first element from the stack until no
    elements are available. This does not need reduntant information which
    would have to be validated each time the lock was removed.
    
    Reported-by: Russell Senior <russell at personaltelco.net>
    Signed-off-by: Sven Eckelmann <sven at narfation.org>

diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index 988296c..de1022c 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -816,7 +816,7 @@ static void send_vis_packets(struct work_struct *work)
 		container_of(work, struct delayed_work, work);
 	struct bat_priv *bat_priv =
 		container_of(delayed_work, struct bat_priv, vis_work);
-	struct vis_info *info, *temp;
+	struct vis_info *info;
 
 	spin_lock_bh(&bat_priv->vis_hash_lock);
 	purge_vis_packets(bat_priv);
@@ -826,8 +826,9 @@ static void send_vis_packets(struct work_struct *work)
 		send_list_add(bat_priv, bat_priv->my_vis_info);
 	}
 
-	list_for_each_entry_safe(info, temp, &bat_priv->vis_send_list,
-				 send_list) {
+	while (!list_empty(&bat_priv->vis_send_list)) {
+		info = list_first_entry(&bat_priv->vis_send_list,
+					typeof(*info), send_list);
 
 		kref_get(&info->refcount);
 		spin_unlock_bh(&bat_priv->vis_hash_lock);

-- 
LinuxNextTracking


More information about the linux-merge mailing list