Commit 33dc85c3 authored by Larry Finger's avatar Larry Finger Committed by Greg Kroah-Hartman

staging: r8188eu: Fix scheduling while atomic error introduced in commit fadbe0cd

In commit fadbe0cd entitled "staging:
rtl8188eu:Remove rtw_zmalloc(), wrapper for kzalloc()", the author failed
to note that the original code in the wrapper tested whether the caller
could sleep, and set the flags argument to kzalloc() appropriately.
After the patch, GFP_KERNEL is used unconditionally. Unfortunately, several
of the routines may be entered from an interrupt routine and generate
a BUG splat for every such call. Routine rtw_sitesurvey_cmd() is used in the
example below:

BUG: sleeping function called from invalid context at mm/slub.c:1240
in_atomic(): 1, irqs_disabled(): 0, pid: 756, name: wpa_supplicant
INFO: lockdep is turned off.
CPU: 2 PID: 756 Comm: wpa_supplicant Tainted: G        WC O   3.18.0-rc4+ #34
Hardware name: TOSHIBA TECRA A50-A/TECRA A50-A, BIOS Version 4.20   04/17/2014
ffffc90005557000 ffff880216fafaa8 ffffffff816b0bbf 0000000000000000
ffff8800c3b58000 ffff880216fafac8 ffffffff8107af77 0000000000000001
0000000000000010 ffff880216fafb18 ffffffff811b06ce 0000000000000000
Call Trace:
 [<ffffffff816b0bbf>] dump_stack+0x4e/0x71
 [<ffffffff8107af77>] __might_sleep+0xf7/0x120
 [<ffffffff811b06ce>] kmem_cache_alloc_trace+0x4e/0x1f0
 [<ffffffffa0888226>] ? rtw_sitesurvey_cmd+0x56/0x2a0 [r8188eu]
 [<ffffffffa0888226>] rtw_sitesurvey_cmd+0x56/0x2a0 [r8188eu]
 [<ffffffffa088f00d>] rtw_do_join+0x22d/0x370 [r8188eu]
 [<ffffffffa088f6e8>] rtw_set_802_11_ssid+0x218/0x3d0 [r8188eu]
 [<ffffffffa08c3ca5>] rtw_wx_set_essid+0x1e5/0x410 [r8188eu]
 [<ffffffffa08c3ac0>] ? rtw_wx_get_rate+0x50/0x50 [r8188eu]
 [<ffffffff816938f1>] ioctl_standard_iw_point+0x151/0x3f0
 [<ffffffff81693d52>] ioctl_standard_call+0xb2/0xe0
 [<ffffffff81597df7>] ? rtnl_lock+0x17/0x20
 [<ffffffff816945a0>] ? iw_handler_get_private+0x70/0x70
 [<ffffffff81693ca0>] ? call_commit_handler+0x40/0x40
 [<ffffffff81693256>] wireless_process_ioctl+0x176/0x1c0
 [<ffffffff81693e79>] wext_handle_ioctl+0x69/0xc0
 [<ffffffff8159fe79>] dev_ioctl+0x309/0x5e0
 [<ffffffff810be9c7>] ? call_rcu+0x17/0x20
 [<ffffffff8156a472>] sock_ioctl+0x142/0x2e0
 [<ffffffff811e0c70>] do_vfs_ioctl+0x300/0x520
 [<ffffffff81101514>] ? __audit_syscall_entry+0xb4/0x110
 [<ffffffff81101514>] ? __audit_syscall_entry+0xb4/0x110
 [<ffffffff810102bc>] ? do_audit_syscall_entry+0x6c/0x70
 [<ffffffff811e0f11>] SyS_ioctl+0x81/0xa0
 [<ffffffff816ba1d2>] system_call_fastpath+0x12/0x17

Additional routines that generate this BUG are rtw_joinbss_cmd(),
rtw_dynamic_chk_wk_cmd(), rtw_lps_ctrl_wk_cmd(), rtw_rpt_timer_cfg_cmd(),
rtw_ps_cmd(), report_survey_event(), report_join_res(), survey_timer_hdl(),
and rtw_check_bcn_info().
Signed-off-by: default avatarLarry Finger <Larry.Finger@lwfinger.net>
Cc: navin patidar <navin.patidar@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8bb9b9a0
...@@ -275,11 +275,11 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, ...@@ -275,11 +275,11 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid,
if (check_fwstate(pmlmepriv, _FW_LINKED) == true) if (check_fwstate(pmlmepriv, _FW_LINKED) == true)
rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1); rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1);
ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (ph2c == NULL) if (ph2c == NULL)
return _FAIL; return _FAIL;
psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_KERNEL); psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
if (psurveyPara == NULL) { if (psurveyPara == NULL) {
kfree(ph2c); kfree(ph2c);
return _FAIL; return _FAIL;
...@@ -405,7 +405,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) ...@@ -405,7 +405,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork)
else else
RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.Ssid)); RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.Ssid));
pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); pcmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (pcmd == NULL) { if (pcmd == NULL) {
res = _FAIL; res = _FAIL;
RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n")); RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n"));
...@@ -755,13 +755,13 @@ u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter) ...@@ -755,13 +755,13 @@ u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter)
u8 res = _SUCCESS; u8 res = _SUCCESS;
ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (ph2c == NULL) { if (ph2c == NULL) {
res = _FAIL; res = _FAIL;
goto exit; goto exit;
} }
pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC);
if (pdrvextra_cmd_parm == NULL) { if (pdrvextra_cmd_parm == NULL) {
kfree(ph2c); kfree(ph2c);
res = _FAIL; res = _FAIL;
...@@ -967,13 +967,13 @@ u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue) ...@@ -967,13 +967,13 @@ u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue)
u8 res = _SUCCESS; u8 res = _SUCCESS;
if (enqueue) { if (enqueue) {
ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (ph2c == NULL) { if (ph2c == NULL) {
res = _FAIL; res = _FAIL;
goto exit; goto exit;
} }
pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC);
if (pdrvextra_cmd_parm == NULL) { if (pdrvextra_cmd_parm == NULL) {
kfree(ph2c); kfree(ph2c);
res = _FAIL; res = _FAIL;
...@@ -1010,13 +1010,13 @@ u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 min_time) ...@@ -1010,13 +1010,13 @@ u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 min_time)
u8 res = _SUCCESS; u8 res = _SUCCESS;
ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (ph2c == NULL) { if (ph2c == NULL) {
res = _FAIL; res = _FAIL;
goto exit; goto exit;
} }
pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC);
if (pdrvextra_cmd_parm == NULL) { if (pdrvextra_cmd_parm == NULL) {
kfree(ph2c); kfree(ph2c);
res = _FAIL; res = _FAIL;
...@@ -1088,13 +1088,13 @@ u8 rtw_ps_cmd(struct adapter *padapter) ...@@ -1088,13 +1088,13 @@ u8 rtw_ps_cmd(struct adapter *padapter)
u8 res = _SUCCESS; u8 res = _SUCCESS;
ppscmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ppscmd = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (ppscmd == NULL) { if (ppscmd == NULL) {
res = _FAIL; res = _FAIL;
goto exit; goto exit;
} }
pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC);
if (pdrvextra_cmd_parm == NULL) { if (pdrvextra_cmd_parm == NULL) {
kfree(ppscmd); kfree(ppscmd);
res = _FAIL; res = _FAIL;
......
...@@ -4241,12 +4241,12 @@ void report_survey_event(struct adapter *padapter, ...@@ -4241,12 +4241,12 @@ void report_survey_event(struct adapter *padapter,
pcmdpriv = &padapter->cmdpriv; pcmdpriv = &padapter->cmdpriv;
pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (pcmd_obj == NULL) if (pcmd_obj == NULL)
return; return;
cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header)); cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
pevtcmd = kzalloc(cmdsz, GFP_KERNEL); pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
if (pevtcmd == NULL) { if (pevtcmd == NULL) {
kfree(pcmd_obj); kfree(pcmd_obj);
return; return;
...@@ -4339,12 +4339,12 @@ void report_join_res(struct adapter *padapter, int res) ...@@ -4339,12 +4339,12 @@ void report_join_res(struct adapter *padapter, int res)
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct cmd_priv *pcmdpriv = &padapter->cmdpriv; struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); pcmd_obj = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (pcmd_obj == NULL) if (pcmd_obj == NULL)
return; return;
cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header)); cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
pevtcmd = kzalloc(cmdsz, GFP_KERNEL); pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
if (pevtcmd == NULL) { if (pevtcmd == NULL) {
kfree(pcmd_obj); kfree(pcmd_obj);
return; return;
...@@ -4854,11 +4854,11 @@ void survey_timer_hdl(void *function_context) ...@@ -4854,11 +4854,11 @@ void survey_timer_hdl(void *function_context)
pmlmeext->scan_abort = false;/* reset */ pmlmeext->scan_abort = false;/* reset */
} }
ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
if (ph2c == NULL) if (ph2c == NULL)
goto exit_survey_timer_hdl; goto exit_survey_timer_hdl;
psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_KERNEL); psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
if (psurveyPara == NULL) { if (psurveyPara == NULL) {
kfree(ph2c); kfree(ph2c);
goto exit_survey_timer_hdl; goto exit_survey_timer_hdl;
......
...@@ -935,7 +935,7 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) ...@@ -935,7 +935,7 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len)
return true; return true;
} }
bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_KERNEL); bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
subtype = GetFrameSubType(pframe) >> 4; subtype = GetFrameSubType(pframe) >> 4;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment