On Wed, Aug 1, 2012 at 11:39 AM, Johannes Berg <johannes@xxxxxxxxxxxxxxxx> wrote: > The strange thing is that we call __cfg80211_disconnect() from the > netdev notifier with NETDEV_GOING_DOWN. This will allocate and queue the > work item as you found. The next thing that happens should be > NETDEV_DOWN, which will cause us to dev_hold() the device and then queue > the cleanup work. The cleanup work must run for us to dev_put() the > device, so that it can only be unregistered after that runs. Then, > finally, we get NETDEV_UNREGISTER which removes it from the list. > > Now note that the work item we queue in __cfg80211_disconnect() is > queued *before* the cleanup work, therefore it should also run before > the cleanup work since the workqueue is singlethreaded. Here is what happens: NETDEV_GOING_DOWN cfg80211_disconnected() called, disconnect event work queued NETDEV_DOWN cleanup work queued NETDEV_UNREGISTER *** cfg80211_netdev_notifier_call now calls: list_del_rcu(&wdev->list); disconnect even work runs, calls cfg80211_process_rdev_events() but the wdev is already removed from rdev->netdev_list as above cleanup work runs The bit I marked with *** is what is causing the difficulties - it runs before the work items do. Daniel -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html