From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linuxfoundation.org ([140.211.169.12]:39074 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750701AbdAJUkF (ORCPT ); Tue, 10 Jan 2017 15:40:05 -0500 Date: Tue, 10 Jan 2017 21:40:24 +0100 From: Greg Kroah-Hartman To: Dmitry Osipenko Cc: Larry Finger , linux-kernel@vger.kernel.org, stable@vger.kernel.org, Ping-Ke Shih , Kalle Valo Subject: Re: [PATCH 4.9 003/116] rtlwifi: Fix enter/exit power_save Message-ID: <20170110204024.GA5274@kroah.com> References: <20170106213908.681421800@linuxfoundation.org> <20170106213908.862747180@linuxfoundation.org> <18ad247d-470c-8cfb-e455-7fc11abcc6b0@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <18ad247d-470c-8cfb-e455-7fc11abcc6b0@gmail.com> Sender: stable-owner@vger.kernel.org List-ID: On Tue, Jan 10, 2017 at 08:40:28PM +0300, Dmitry Osipenko wrote: > Hello, this patch causes a kernel panic with the rtl8192cu driver. Ick, not good! Does this cause a problem in Linus's tree as well? thanks, greg k-h > > <6>[ 20.847025] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready > <1>[ 21.699551] BUG: unable to handle kernel NULL pointer dereference at > 0000000000000048 > <1>[ 21.699626] IP: [] rtl_lps_leave+0x13/0x40 [rtlwifi] > <4>[ 21.699681] PGD 20cf47067 > <4>[ 21.699702] PUD 20cf42067 > <4>[ 21.699725] PMD 0 > <4>[ 21.699732] > <4>[ 21.699759] Oops: 0000 [#1] PREEMPT SMP > <4>[ 21.699794] Modules linked in: rtl8192cu rtl_usb rtl8192c_common rtlwifi > snd_hda_codec_realtek snd_hda_codec_generic snd_hda_intel snd_hda_codec > snd_hwdep snd_hda_core dm_mod thermal > <4>[ 21.699985] CPU: 0 PID: 2656 Comm: ntpdate Not tainted 4.9.2 #1 > <4>[ 21.700036] Hardware name: Gigabyte Technology Co., Ltd. To be filled by > O.E.M./Z77-DS3H, BIOS F11a 11/13/2013 > <4>[ 21.700118] task: ffff9ce2509ca4c0 task.stack: ffffa41003eac000 > <4>[ 21.700168] RIP: 0010:[] [] > rtl_lps_leave+0x13/0x40 [rtlwifi] > <4>[ 21.700250] RSP: 0018:ffffa41003eaf520 EFLAGS: 00010206 > <4>[ 21.700296] RAX: 0000000080000802 RBX: ffff9ce251371420 RCX: ffff9ce254ff4640 > <4>[ 21.700356] RDX: 0000000000000806 RSI: ffff9ce25137afb8 RDI: 0000000000000000 > <4>[ 21.700416] RBP: ffff9ce25137afb8 R08: ffffffffc0382d00 R09: ffff9ce254e38c31 > <4>[ 21.700475] R10: 0000000000000000 R11: ffff9ce251370700 R12: 0000000000000000 > <4>[ 21.700535] R13: 0000000000000000 R14: ffff9ce251371420 R15: ffff9ce254e38c00 > <4>[ 21.700595] FS: 00007f22f6da8700(0000) GS:ffff9ce25f200000(0000) > knlGS:0000000000000000 > <4>[ 21.700662] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > <4>[ 21.700711] CR2: 0000000000000048 CR3: 000000020cf65000 CR4: 00000000001406f0 > <4>[ 21.700770] Stack: > <4>[ 21.700790] ffffffffc0375088 0000000000000008 ffff9ce251370700 > 0000000000000001 > <4>[ 21.700867] ffffffffc03751c7 0100000000000000 ffffa41003eaf618 > ffff9ce252b5a800 > <4>[ 21.700944] 0000000000000000 ffff9ce251371420 0000000000000000 > ffff9ce254e38c00 > <4>[ 21.701021] Call Trace: > <4>[ 21.701048] [] ? setup_arp_tx.isra.20+0x48/0x60 [rtlwifi] > <4>[ 21.701110] [] ? rtl_is_special_data+0x127/0x210 [rtlwifi] > <4>[ 21.701171] [] ? rtl_get_rate+0x97/0x210 [rtlwifi] > <4>[ 21.701228] [] ? rate_control_get_rate+0xb6/0x140 > <4>[ 21.701283] [] ? ieee80211_tx_h_rate_ctrl+0x1e0/0x3f0 > <4>[ 21.701340] [] ? invoke_tx_handlers_early+0x222/0x5a0 > <4>[ 21.701397] [] ? ieee80211_tx+0x6e/0x130 > <4>[ 21.701446] [] ? __ieee80211_subif_start_xmit+0x4d1/0x9d0 > <4>[ 21.701506] [] ? nf_conntrack_tuple_taken+0x1c4/0x1d0 > <4>[ 21.701565] [] ? get_unique_tuple+0xe9/0x510 > <4>[ 21.701617] [] ? ieee80211_subif_start_xmit+0xc/0x10 > <4>[ 21.701675] [] ? dev_hard_start_xmit+0x9a/0x210 > <4>[ 21.701729] [] ? sch_direct_xmit+0xd6/0x1a0 > <4>[ 21.701780] [] ? __dev_queue_xmit+0x422/0x620 > <4>[ 21.701832] [] ? arp_xmit+0x9f/0xb0 > <4>[ 21.701878] [] ? arp_create+0x250/0x250 > <4>[ 21.701926] [] ? arp_solicit+0xee/0x240 > <4>[ 21.701974] [] ? mod_timer+0x1ad/0x360 > <4>[ 21.702022] [] ? neigh_probe+0x42/0x60 > <4>[ 21.702071] [] ? __neigh_event_send+0x1e2/0x230 > <4>[ 21.702124] [] ? neigh_resolve_output+0x120/0x1b0 > <4>[ 21.702179] [] ? ip_finish_output2+0x127/0x300 > <4>[ 21.702231] [] ? ip_output+0x64/0x100 > <4>[ 21.702277] [] ? > __ip_flush_pending_frames.isra.46+0x80/0x80 > <4>[ 21.702339] [] ? ip_send_skb+0x15/0x40 > <4>[ 21.702386] [] ? udp_send_skb+0x15f/0x240 > <4>[ 21.702436] [] ? udp_sendmsg+0x2b6/0x840 > <4>[ 21.702485] [] ? __local_bh_enable_ip+0x8a/0x90 > <4>[ 21.702538] [] ? ip_finish_output2+0x13a/0x300 > <4>[ 21.702592] [] ? rw_copy_check_uvector+0x53/0x110 > <4>[ 21.702648] [] ? import_iovec+0x27/0xc0 > <4>[ 21.702698] [] ? ___sys_sendmsg+0x111/0x2a0 > <4>[ 21.702749] [] ? poll_select_copy_remaining+0x130/0x130 > <4>[ 21.702808] [] ? udp_sendmsg+0x2c5/0x840 > <4>[ 21.702857] [] ? __ip_dev_find+0x111/0x130 > <4>[ 21.702908] [] ? __ip_route_output_key_hash+0x2c5/0x870 > <4>[ 21.702968] [] ? __sys_sendmmsg+0x89/0x160 > <4>[ 21.703018] [] ? SYSC_connect+0x50/0xa0 > <4>[ 21.703066] [] ? sock_alloc_file+0x9a/0x110 > <4>[ 21.703119] [] ? SyS_sendmmsg+0xe/0x20 > <4>[ 21.703166] [] ? entry_SYSCALL_64_fastpath+0x1a/0xa9 > <4>[ 21.703222] Code: 05 e9 32 ff ff ff e9 2d fe ff ff 0f 1f 00 66 2e 0f 1f 84 > 00 00 00 00 00 0f 1f 44 00 00 65 8b 05 24 f4 c8 3f a9 00 ff 1f 00 74 23 <48> 8b > 57 48 bf 40 00 00 00 48 8b 35 3d ba b7 da c6 82 ad a2 00 > <1>[ 21.709488] RIP [] rtl_lps_leave+0x13/0x40 [rtlwifi] > <4>[ 21.712533] RSP > <4>[ 21.715589] CR2: 0000000000000048 > <4>[ 21.735721] ---[ end trace f6ce402401b0b86a ]--- > > > 4.9-stable review patch. If anyone has any objections, please let me know. > > > > ------------------ > > > > From: Larry Finger > > > > commit ba9f93f82abafe2552eac942ebb11c2df4f8dd7f upstream. > > > > In commit a5ffbe0a1993 ("rtlwifi: Fix scheduling while atomic bug") and > > commit a269913c52ad ("rtlwifi: Rework rtl_lps_leave() and rtl_lps_enter() > > to use work queue"), an error was introduced in the power-save routines > > due to the fact that leaving PS was delayed by the use of a work queue. > > > > This problem is fixed by detecting if the enter or leave routines are > > in interrupt mode. If so, the workqueue is used to place the request. > > If in normal mode, the enter or leave routines are called directly. > > > > Fixes: a269913c52ad ("rtlwifi: Rework rtl_lps_leave() and rtl_lps_enter() to use work queue") > > Reported-by: Ping-Ke Shih > > Signed-off-by: Larry Finger > > Signed-off-by: Kalle Valo > > Signed-off-by: Greg Kroah-Hartman > > > > --- > > drivers/net/wireless/realtek/rtlwifi/base.c | 8 +++--- > > drivers/net/wireless/realtek/rtlwifi/core.c | 9 ++----- > > drivers/net/wireless/realtek/rtlwifi/pci.c | 14 +++------- > > drivers/net/wireless/realtek/rtlwifi/ps.c | 36 +++++++++++++++++++++------- > > 4 files changed, 40 insertions(+), 27 deletions(-) > > > > --- a/drivers/net/wireless/realtek/rtlwifi/base.c > > +++ b/drivers/net/wireless/realtek/rtlwifi/base.c > > @@ -1303,12 +1303,13 @@ EXPORT_SYMBOL_GPL(rtl_action_proc); > > > > static void setup_arp_tx(struct rtl_priv *rtlpriv, struct rtl_ps_ctl *ppsc) > > { > > + struct ieee80211_hw *hw = rtlpriv->hw; > > + > > rtlpriv->ra.is_special_data = true; > > if (rtlpriv->cfg->ops->get_btc_status()) > > rtlpriv->btcoexist.btc_ops->btc_special_packet_notify( > > rtlpriv, 1); > > - rtlpriv->enter_ps = false; > > - schedule_work(&rtlpriv->works.lps_change_work); > > + rtl_lps_leave(hw); > > ppsc->last_delaylps_stamp_jiffies = jiffies; > > } > > > > @@ -1381,8 +1382,7 @@ u8 rtl_is_special_data(struct ieee80211_ > > > > if (is_tx) { > > rtlpriv->ra.is_special_data = true; > > - rtlpriv->enter_ps = false; > > - schedule_work(&rtlpriv->works.lps_change_work); > > + rtl_lps_leave(hw); > > ppsc->last_delaylps_stamp_jiffies = jiffies; > > } > > > > --- a/drivers/net/wireless/realtek/rtlwifi/core.c > > +++ b/drivers/net/wireless/realtek/rtlwifi/core.c > > @@ -1150,10 +1150,8 @@ static void rtl_op_bss_info_changed(stru > > } else { > > mstatus = RT_MEDIA_DISCONNECT; > > > > - if (mac->link_state == MAC80211_LINKED) { > > - rtlpriv->enter_ps = false; > > - schedule_work(&rtlpriv->works.lps_change_work); > > - } > > + if (mac->link_state == MAC80211_LINKED) > > + rtl_lps_leave(hw); > > if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE) > > rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); > > mac->link_state = MAC80211_NOLINK; > > @@ -1431,8 +1429,7 @@ static void rtl_op_sw_scan_start(struct > > } > > > > if (mac->link_state == MAC80211_LINKED) { > > - rtlpriv->enter_ps = false; > > - schedule_work(&rtlpriv->works.lps_change_work); > > + rtl_lps_leave(hw); > > mac->link_state = MAC80211_LINKED_SCANNING; > > } else { > > rtl_ips_nic_on(hw); > > --- a/drivers/net/wireless/realtek/rtlwifi/pci.c > > +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c > > @@ -663,11 +663,9 @@ tx_status_ok: > > } > > > > if (((rtlpriv->link_info.num_rx_inperiod + > > - rtlpriv->link_info.num_tx_inperiod) > 8) || > > - (rtlpriv->link_info.num_rx_inperiod > 2)) { > > - rtlpriv->enter_ps = false; > > - schedule_work(&rtlpriv->works.lps_change_work); > > - } > > + rtlpriv->link_info.num_tx_inperiod) > 8) || > > + (rtlpriv->link_info.num_rx_inperiod > 2)) > > + rtl_lps_leave(hw); > > } > > > > static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw, > > @@ -918,10 +916,8 @@ new_trx_end: > > } > > if (((rtlpriv->link_info.num_rx_inperiod + > > rtlpriv->link_info.num_tx_inperiod) > 8) || > > - (rtlpriv->link_info.num_rx_inperiod > 2)) { > > - rtlpriv->enter_ps = false; > > - schedule_work(&rtlpriv->works.lps_change_work); > > - } > > + (rtlpriv->link_info.num_rx_inperiod > 2)) > > + rtl_lps_leave(hw); > > skb = new_skb; > > no_new: > > if (rtlpriv->use_new_trx_flow) { > > --- a/drivers/net/wireless/realtek/rtlwifi/ps.c > > +++ b/drivers/net/wireless/realtek/rtlwifi/ps.c > > @@ -407,8 +407,8 @@ void rtl_lps_set_psmode(struct ieee80211 > > } > > } > > > > -/*Enter the leisure power save mode.*/ > > -void rtl_lps_enter(struct ieee80211_hw *hw) > > +/* Interrupt safe routine to enter the leisure power save mode.*/ > > +static void rtl_lps_enter_core(struct ieee80211_hw *hw) > > { > > struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); > > struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); > > @@ -444,10 +444,9 @@ void rtl_lps_enter(struct ieee80211_hw * > > > > spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); > > } > > -EXPORT_SYMBOL(rtl_lps_enter); > > > > -/*Leave the leisure power save mode.*/ > > -void rtl_lps_leave(struct ieee80211_hw *hw) > > +/* Interrupt safe routine to leave the leisure power save mode.*/ > > +static void rtl_lps_leave_core(struct ieee80211_hw *hw) > > { > > struct rtl_priv *rtlpriv = rtl_priv(hw); > > struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); > > @@ -477,7 +476,6 @@ void rtl_lps_leave(struct ieee80211_hw * > > } > > spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); > > } > > -EXPORT_SYMBOL(rtl_lps_leave); > > > > /* For sw LPS*/ > > void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) > > @@ -670,12 +668,34 @@ void rtl_lps_change_work_callback(struct > > struct rtl_priv *rtlpriv = rtl_priv(hw); > > > > if (rtlpriv->enter_ps) > > - rtl_lps_enter(hw); > > + rtl_lps_enter_core(hw); > > else > > - rtl_lps_leave(hw); > > + rtl_lps_leave_core(hw); > > } > > EXPORT_SYMBOL_GPL(rtl_lps_change_work_callback); > > > > +void rtl_lps_enter(struct ieee80211_hw *hw) > > +{ > > + struct rtl_priv *rtlpriv = rtl_priv(hw); > > + > > + if (!in_interrupt()) > > + return rtl_lps_enter_core(hw); > > + rtlpriv->enter_ps = true; > > + schedule_work(&rtlpriv->works.lps_change_work); > > +} > > +EXPORT_SYMBOL_GPL(rtl_lps_enter); > > + > > +void rtl_lps_leave(struct ieee80211_hw *hw) > > +{ > > + struct rtl_priv *rtlpriv = rtl_priv(hw); > > + > > + if (!in_interrupt()) > > + return rtl_lps_leave_core(hw); > > + rtlpriv->enter_ps = false; > > + schedule_work(&rtlpriv->works.lps_change_work); > > +} > > +EXPORT_SYMBOL_GPL(rtl_lps_leave); > > + > > void rtl_swlps_wq_callback(void *data) > > { > > struct rtl_works *rtlworks = container_of_dwork_rtl(data, > > > > > > > -- > Dmitry