Staging: batman-adv: use rcu callbacks when freeing batman_if
authorMarek Lindner <lindner_marek@yahoo.de>
Sun, 21 Nov 2010 23:55:44 +0000 (00:55 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 29 Nov 2010 19:09:09 +0000 (11:09 -0800)
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/batman-adv/hard-interface.c
drivers/staging/batman-adv/hard-interface.h
drivers/staging/batman-adv/types.h

index 6d5b748..c2ff294 100644 (file)
 /* protect update critical side of if_list - but not the content */
 static DEFINE_SPINLOCK(if_list_lock);
 
+static void hardif_free_rcu(struct rcu_head *rcu)
+{
+       struct batman_if *batman_if;
+
+       batman_if = container_of(rcu, struct batman_if, rcu);
+       dev_put(batman_if->net_dev);
+       kref_put(&batman_if->refcount, hardif_free_ref);
+}
+
 struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev)
 {
        struct batman_if *batman_if;
@@ -462,9 +471,8 @@ static void hardif_remove_interface(struct batman_if *batman_if)
                return;
 
        batman_if->if_status = IF_TO_BE_REMOVED;
-       synchronize_rcu();
        sysfs_del_hardif(&batman_if->hardif_obj);
-       kref_put(&batman_if->refcount, hardif_free_ref);
+       call_rcu(&batman_if->rcu, hardif_free_rcu);
 }
 
 void hardif_remove_interfaces(void)
index 1d1cd9f..30ec3b8 100644 (file)
@@ -47,7 +47,6 @@ static inline void hardif_free_ref(struct kref *refcount)
        struct batman_if *batman_if;
 
        batman_if = container_of(refcount, struct batman_if, refcount);
-       dev_put(batman_if->net_dev);
        kfree(batman_if);
 }
 
index d89ec70..8f6ba1c 100644 (file)
@@ -46,6 +46,7 @@ struct batman_if {
        struct kref refcount;
        struct packet_type batman_adv_ptype;
        struct net_device *soft_iface;
+       struct rcu_head rcu;
 };
 
 /**