I found a regression where my EEE hangs at boot time, if the battery is present. I'm confident it's a regression because it disappears if I revert Arjan's asynchronous battery initialisation. However, the evidence points to a deadlock in the wireless stack which has simply been uncovered by timing changes. If I leave the system long enough, I get a series of hung task warnings. They suggest the following deadlock: - ieee80211_wep_init(), which is called with rtnl_lock() held, is blocked in request_module() [waiting for modprobe to load a crypto module]. - modprobe is blocked in a call to flush_workqueue(), caused by closing a TTY. - worker_thread is blocked because the workqueue item linkwatch_event() is blocked on rtnl_lock. I've hacked up a test patch to move wep_init() outside of rtnl_lock, and it solved the problem. My one caveat is that it would probably be cleaner to move it after rtnl_unlock(), instead of before rtnl_lock(). I just wasn't 100% sure if that would be safe. Here's the patch: ---8<--- diff --git a/net/mac80211/main.c b/net/mac80211/main.c index fbcbed6..fffa7f9 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -909,6 +909,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (result < 0) goto fail_sta_info; + result = ieee80211_wep_init(local); + if (result < 0) { + printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n", + wiphy_name(local->hw.wiphy), result); + goto fail_wep; + } + rtnl_lock(); result = dev_alloc_name(local->mdev, local->mdev->name); if (result < 0) @@ -930,14 +937,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) goto fail_rate; } - result = ieee80211_wep_init(local); - - if (result < 0) { - printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n", - wiphy_name(local->hw.wiphy), result); - goto fail_wep; - } - /* add one default STA interface if supported */ if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { result = ieee80211_if_add(local, "wlan%d", NULL, @@ -967,13 +966,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) return 0; -fail_wep: - rate_control_deinitialize(local); fail_rate: unregister_netdevice(local->mdev); local->mdev = NULL; fail_dev: rtnl_unlock(); +fail_wep: sta_info_stop(local); fail_sta_info: debugfs_hw_del(local); -- 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