On Sun, 2014-04-20 at 11:41 +0400, Dmitry Semyonov wrote: > On 19 April 2014 17:48, Ben Hutchings wrote: > > > Does this patch fix it? > > Thanks! It fixes the crash but wlan0 has to be brought down, and up > again to make it work after initial bring up attempt: [...] I assume this is a regression, i.e. this problem did not exist in 3.2.54-2? In that case, please test the attached patch instead of the previous one. This simply reverts the most recent change to the driver. Ben. -- Ben Hutchings Make three consecutive correct guesses and you will be considered an expert.
From: Ben Hutchings <ben@decadent.org.uk> Date: Sun, 20 Apr 2014 14:57:56 +0100 Subject: Revert "rtlwifi: rtl8192ce: Fix too long disable of IRQs" This reverts commit 2de2c2e956dbf164c5acb1dca16e9a3c1938096e, which was commit f78bccd79ba3cd9d9664981b501d57bdb81ab8a4 upstream. Dmitry Semyonov reported that after upgrading from 3.2.54 to 3.2.57 the rtl8192ce driver will crash when its interface is brought up. The oops message shows: [ 1833.611397] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 [ 1833.611455] IP: [<ffffffffa0410c6a>] rtl92ce_update_hal_rate_tbl+0x29/0x4db [rtl8192ce] ... [ 1833.613326] Call Trace: [ 1833.613346] [<ffffffffa02ad9c6>] ? rtl92c_dm_watchdog+0xd0b/0xec9 [rtl8192c_common] [ 1833.613391] [<ffffffff8105b5cf>] ? process_one_work+0x161/0x269 [ 1833.613425] [<ffffffff8105c598>] ? worker_thread+0xc2/0x145 [ 1833.613458] [<ffffffff8105c4d6>] ? manage_workers.isra.25+0x15b/0x15b [ 1833.613496] [<ffffffff8105f6d9>] ? kthread+0x76/0x7e [ 1833.613527] [<ffffffff81356b74>] ? kernel_thread_helper+0x4/0x10 [ 1833.613563] [<ffffffff8105f663>] ? kthread_worker_fn+0x139/0x139 [ 1833.613598] [<ffffffff81356b70>] ? gs_change+0x13/0x13 Disassembly of rtl92ce_update_hal_rate_tbl() shows that the 'sta' parameter was null. I believe this is caused by a race condition that was was unmasked by commit f78bccd79ba3 ('rtlwifi: rtl8192ce: Fix too long disable of IRQs'). rtl92c_dm_watchdog() calls rtl92ce_update_hal_rate_tbl() via rtl92c_dm_refresh_rate_adaptive_mask(), which does not appear in the call trace as it was inlined. That function has been completely removed upstream which may explain why this crash wasn't seen there. I'm not sure that it is sensible to completely remove rtl92c_dm_refresh_rate_adaptive_mask() without making other compensating changes elsewhere, and I don't know what those would be. Adding a null pointer in rtl92c_dm_refresh_rate_adaptive_mask() and then skipping the call to rtl92ce_update_hal_rate_tbl() avoided the crash, but interfaces still don't work when first brought up. Signed-off-by: Ben Hutchings <ben@decadent.org.uk> --- --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -905,26 +905,14 @@ int rtl92ce_hw_init(struct ieee80211_hw bool is92c; int err; u8 tmp_u1b; - unsigned long flags; rtlpci->being_init_adapter = true; - - /* Since this function can take a very long time (up to 350 ms) - * and can be called with irqs disabled, reenable the irqs - * to let the other devices continue being serviced. - * - * It is safe doing so since our own interrupts will only be enabled - * in a subsequent step. - */ - local_save_flags(flags); - local_irq_enable(); - rtlpriv->intf_ops->disable_aspm(hw); rtstatus = _rtl92ce_init_mac(hw); if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n")); err = 1; - goto exit; + return err; } err = rtl92c_download_fw(hw); @@ -934,7 +922,7 @@ int rtl92ce_hw_init(struct ieee80211_hw "without FW now..\n")); err = 1; rtlhal->fw_ready = false; - goto exit; + return err; } else { rtlhal->fw_ready = true; } @@ -997,8 +985,6 @@ int rtl92ce_hw_init(struct ieee80211_hw RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("under 1.5V\n")); } rtl92c_dm_init(hw); -exit: - local_irq_restore(flags); rtlpci->being_init_adapter = false; return err; }
Attachment:
signature.asc
Description: This is a digitally signed message part