sysfs_del_hardif invokes kobject_put, which might sleep. However, we are not allowed to sleep during a call_rcu. There is also no need to do the removal with an atomic call_rcu, as kobject_put only frees the kobject when there is no more reference to it anyway.
This commit basically revokes 7f32f2e8d97150ba5b80410dda86b01b0879fe8d, despite not reintroducing the synchronize_rcu, our rcu_barrier should handle this.
Signed-off-by: Linus Lüssing linus.luessing@web.de --- hard-interface.c | 14 +++----------- 1 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/hard-interface.c b/hard-interface.c index 37f0f8b..5c6ce3f 100644 --- a/hard-interface.c +++ b/hard-interface.c @@ -36,16 +36,6 @@ /* 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); - sysfs_del_hardif(&batman_if->hardif_obj); - 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; @@ -470,7 +460,9 @@ static void hardif_remove_interface(struct batman_if *batman_if)
/* caller must take if_list_lock */ list_del_rcu(&batman_if->list); - call_rcu(&batman_if->rcu, hardif_free_rcu); + sysfs_del_hardif(&batman_if->hardif_obj); + dev_put(batman_if->net_dev); + kref_put(&batman_if->refcount, hardif_free_ref); }
void hardif_remove_interfaces(void)