Hi,
During debugging some potential problems I hit a race bug in the
brcmfmac. It calls wiphy_register() before it's ready to handle all the
cfg80211 callbacks correctly.
In brcmf_cfg80211_attach() there is a wiphy_register() call performed
before setting "config" in the struct brcmf_pub. So if:
1) User tries to create interface *right* after wiphy appears
2) brcmf_cfg80211_add_iface() gets executed quickly enough
3) Firmware sends BRCMF_E_IF event
Then brcmf_notify_vif_event() will crash the kernel:
[ 32.071904] [00000300] *pgd=00000000
[ 32.075562] Internal error: Oops: 17 [#1] SMP ARM
[ 32.080277] Modules linked in: pppoe ppp_async l2tp_ppp iptable_nat brcmfmac
pptp pppox ppp_mppe ppp_generic nf_nat_ipv4 nf_conntrack_ipv6 nf_conntrack_ipv4
ipt_REJECT ipt_MASQUERADE cfg80211 xt_time xt_tcpudp xt_tcpmss xt_statistic
xt_state xt_recent xt_policy xt_na0
[ 32.178487] ip_set_hash_ipportip ip_set_hash_ipport ip_set_hash_ipmark
ip_set_hash_ip ip_set_bitmap_port ip_set_bitmap_ipmac ip_set_bitmap_ip ip_set
nfnetlink ip6t_REJECT nf_reject_ipv6 nf_log_ipv6 nf_log_common ip6table_mangle
ip6table_filter ip6_tables x_tables msc
[ 32.274776] CPU: 1 PID: 12 Comm: kworker/1:0 Not tainted 4.4.167 #0
[ 32.281054] Hardware name: BCM5301X
[ 32.284580] Workqueue: events brcmf_fweh_event_worker [brcmfmac]
[ 32.290604] task: c7845980 ti: c7872000 task.ti: c7872000
[ 32.296017] PC is at _raw_spin_lock+0x10/0x4c
[ 32.300388] LR is at brcmf_notify_vif_event+0x6c/0x1a4 [brcmfmac]
[ 32.306489] pc : [<c0012098>] lr : [<bf5387dc>] psr: 60000013
[ 32.306489] sp : c7873e18 ip : c7873e28 fp : c7873e24
[ 32.317995] r10: c7873eaa r9 : c7873ea4 r8 : c59c8000
[ 32.323227] r7 : c535e948 r6 : c4d50480 r5 : 00000000 r4 : 00000300
[ 32.329763] r3 : 00000000 r2 : c7873e24 r1 : bf54f7b3 r0 : 00000300
[ 32.336301] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
[ 32.343445] Control: 10c5387d Table: 04cf004a DAC: 00000051
[ 32.349199] Process kworker/1:0 (pid: 12, stack limit = 0xc7872190)
[ 32.355474] Stack: (0xc7873e18 to 0xc7874000)
[ 32.359836] 3e00:
c7873e54 c7873e28
[ 32.368029] 3e20: bf5387dc c0012094 00000000 00000001 00000002 c7873e2c
bf538770 c59ca138
[ 32.376228] 3e40: c4d50480 00000000 c7873e6c c7873e58 bf53c1e8 bf53877c
c535e900 c59ca138
[ 32.384426] 3e60: c7873eec c7873e70 bf53c578 bf53c1b8 c7873eaa c7873ea4
00000000 00000001
[ 32.392617] 3e80: 72ed795e c04e03c8 00000089 00000002 00000036 00000000
00000000 00000000
[ 32.400816] 3ea0: 00000005 6a4e13a4 6c77b80b 00322e30 00000000 00000000
02010000 dc8ba6a7
[ 32.409007] 3ec0: c7a2eec0 c78333c0 c6bda300 c59ca138 c78333d8 00000000
c6bdd700 00000008
[ 32.417206] 3ee0: c7873f2c c7873ef0 c0034458 bf53c27c c6bda300 c6bda300
c78333d8 00000000
[ 32.425405] 3f00: 00000000 c78333c0 c6bda300 c6bda300 c78333d8 c6bda314
00000000 00000008
[ 32.433604] 3f20: c7873f5c c7873f30 c0035234 c0034284 c7845980 c7832700
00000000 c78333c0
[ 32.441803] 3f40: c0034f40 00000000 00000000 00000000 c7873fac c7873f60
c003984c c0034f4c
[ 32.449994] 3f60: 00000000 00000000 00000000 c78333c0 00000000 00000000
c7873f78 c7873f78
[ 32.458184] 3f80: 00000000 00000000 c7873f88 c7873f88 c7832700 c003974c
00000000 00000000
[ 32.466383] 3fa0: 00000000 c7873fb0 c00097d0 c0039758 00000000 00000000
00000000 00000000
[ 32.474573] 3fc0: 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000
[ 32.482764] 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
00000000 00000000
[ 32.490950] Backtrace:
[ 32.493420] [<c0012088>] (_raw_spin_lock) from [<bf5387dc>]
(brcmf_notify_vif_event+0x6c/0x1a4 [brcmfmac])
[ 32.503112] [<bf538770>] (brcmf_notify_vif_event [brcmfmac]) from
[<bf53c1e8>] (brcmf_fil_bsscfg_int_get+0x78/0xb0 [brcmfmac])
[ 32.514521] r7:00000000 r6:c4d50480 r5:c59ca138 r4:bf538770
[ 32.520240] [<bf53c1ac>] (brcmf_fil_bsscfg_int_get [brcmfmac]) from
[<bf53c578>] (brcmf_fweh_event_worker+0x308/0x3d4 [brcmfmac])
[ 32.531912] r5:c59ca138 r4:c535e900
[ 32.535524] [<bf53c270>] (brcmf_fweh_event_worker [brcmfmac]) from
[<c0034458>] (process_one_work+0x1e0/0x318)
[ 32.545543] r10:00000008 r9:c6bdd700 r8:00000000 r7:c78333d8 r6:c59ca138
r5:c6bda300
[ 32.553428] r4:c78333c0
[ 32.555975] [<c0034278>] (process_one_work) from [<c0035234>]
(worker_thread+0x2f4/0x448)
[ 32.564169] r10:00000008 r9:00000000 r8:c6bda314 r7:c78333d8 r6:c6bda300
r5:c6bda300
[ 32.572055] r4:c78333c0
[ 32.574607] [<c0034f40>] (worker_thread) from [<c003984c>]
(kthread+0x100/0x114)
[ 32.582012] r10:00000000 r9:00000000 r8:00000000 r7:c0034f40 r6:c78333c0
r5:00000000
[ 32.589898] r4:c7832700 r3:c7845980
[ 32.593499] [<c003974c>] (kthread) from [<c00097d0>]
(ret_from_fork+0x14/0x24)
[ 32.600735] r7:00000000 r6:00000000 r5:c003974c r4:c7832700
[ 32.606440] Code: e1a0c00d e92dd800 e24cb004 f590f000 (e1902f9f)
[ 32.612609] ---[ end trace 68af7a0bd4231f2f ]---
I think it was meant to be avoided by call brcmf_fweh_activate_events()
being executed late enough but it doesn't seem to work. Firmware seems
to generate BRCMF_E_IF even before driver /allows/ it to do so.
I'm not very similiar with all the init path so could someone take a
look at this, please?
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -738,6 +738,7 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct
wiphy *wiphy,
struct wireless_dev *wdev;
int err;
+ wiphy_info(wiphy, "%s: name:%s\n", __func__, name);
/*
* There is a bug with in-firmware BSS management. When adding virtual
* interface brcmfmac first tells firmware to create new BSS and then
@@ -5766,6 +5767,7 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
const struct brcmf_event_msg *e, void *data)
{
struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
+ BUG_ON(!cfg);
struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
struct brcmf_cfg80211_vif *vif;
@@ -7110,6 +7115,8 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct
brcmf_pub *drvr,
brcmf_err("Could not register wiphy device (%d)\n", err);
goto priv_out;
}
+ wiphy_warn(wiphy, "wiphy registered - add interface NOW to crash the
kernel\n");
+ msleep(30000);
err = brcmf_setup_wiphybands(wiphy);
if (err) {