* mac80211: crash while adding interface.
@ 2007-09-25 20:06 Michael Buesch
2007-09-25 20:36 ` Johannes Berg
2007-09-25 21:31 ` [PATCH] mac80211: fix interface initialisation Johannes Berg
0 siblings, 2 replies; 10+ messages in thread
From: Michael Buesch @ 2007-09-25 20:06 UTC (permalink / raw)
To: Johannes Berg, Michael Wu; +Cc: linux-wireless
The following happened when adding an interface through sysfs
on b43, while another one was operating and transmitting data:
[42108.560015] b43-phy4 debug: Current TX power output: 14.25 dBm, Desired TX power output: 14.25 dBm
[42214.690045] b43-phy4 debug: Current TX power output: 14.25 dBm, Desired TX power output: 14.25 dBm
[42262.691175] wmaster0: STA 00:12:17:d4:95:e1 Average rate: 10 (10/1)
[42278.273723] Unable to handle kernel paging request for data at address 0x00000000
[42278.274012] Faulting instruction address: 0xc0332848
[42278.274204] Oops: Kernel access of bad area, sig: 11 [#1]
[42278.274400] PREEMPT PowerMac
[42278.274530] Modules linked in: rc80211_simple b43 ssb zd1211rw_mac80211 appletouch af_packet ecb rng_core mac80211 ohci_hcd pcmcia unix
[42278.275192] NIP: c0332848 LR: e20d410c CTR: c0332800
[42278.275376] REGS: d1257d40 TRAP: 0300 Not tainted (2.6.23-rc6-wldev)
[42278.275611] MSR: 00001032 <ME,IR,DR> CR: 24242484 XER: 00000000
[42278.275943] DAR: 00000000, DSISR: 40000000
[42278.276096] TASK = d53f6d50[30638] 'bash' THREAD: d1256000
[42278.276293] GPR00: 00000000 d1257df0 d53f6d50 c14395ec d1257e08 c1439000 c14393bc c143947c
[42278.276749] GPR08: c143947c 00000000 00009032 d1256000 00000000 100e1258 00000000 00000000
[42278.277204] GPR16: 100edd98 100e0000 100b0000 100e0000 00000000 00000000 100fae28 00000000
[42278.277660] GPR24: 00000001 00000002 00000000 c1439000 c0be11a0 df3323a0 c14393a0 00000000
[42278.278131] NIP [c0332848] skb_dequeue+0x48/0xa0
[42278.278330] LR [e20d410c] ieee80211_if_reinit+0x1c0/0x284 [mac80211]
[42278.278630] Call Trace:
[42278.278727] [d1257df0] [df3323a0] 0xdf3323a0 (unreliable)
[42278.278976] [d1257e00] [e20d410c] ieee80211_if_reinit+0x1c0/0x284 [mac80211]
[42278.279279] [d1257e30] [c033af58] register_netdevice+0x3f0/0x408
[42278.279532] [d1257e50] [e20d3e94] ieee80211_if_add+0x118/0x1d0 [mac80211]
[42278.279827] [d1257e80] [e20d5a6c] ieee80211_add_iface+0x8c/0x9c [mac80211]
[42278.280124] [d1257e90] [c0420608] _store_add_iface+0x70/0x9c
[42278.280366] [d1257eb0] [c021a704] dev_attr_store+0x28/0x40
[42278.280605] [d1257ec0] [c00c09ac] sysfs_write_file+0x13c/0x1c4
[42278.280856] [d1257ef0] [c007c56c] vfs_write+0xc0/0x164
[42278.281079] [d1257f10] [c007cbc4] sys_write+0x4c/0x8c
[42278.281298] [d1257f40] [c00128e4] ret_from_syscall+0x0/0x38
[42278.281540] --- Exception: c01 at 0xfed0c18
[42278.281714] LR = 0xfe7963c
[42278.281831] Instruction dump:
[42278.281959] 7c000124 542b0024 812b000c 39290001 912b000c 83e30000 38000000 7f9f1800
[42278.282378] 40be000c 3be00000 48000024 81230008 <817f0000> 3929ffff 91230008 91630000
[42278.282854] note: bash[30638] exited with preempt_count 1
[42278.284214] BUG: scheduling while atomic: bash/0x10000002/30638
[42278.285519] Call Trace:
[42278.286708] [d1257b80] [c00082a0] show_stack+0x50/0x184 (unreliable)
[42278.288107] [d1257ba0] [c0029d54] __schedule_bug+0x34/0x44
[42278.289443] [d1257bb0] [c04237c8] schedule+0x70/0x3e0
[42278.290765] [d1257be0] [c0029df0] __cond_resched+0x24/0x50
[42278.292080] [d1257bf0] [c0424318] cond_resched+0x40/0x54
[42278.293390] [d1257c00] [c0066c58] unmap_vmas+0x428/0x51c
[42278.294678] [d1257c70] [c006a900] exit_mmap+0x74/0x118
[42278.295951] [d1257ca0] [c002c770] mmput+0x3c/0x100
[42278.297218] [d1257cb0] [c0030a9c] exit_mm+0x10c/0x120
[42278.298516] [d1257cd0] [c0032574] do_exit+0x220/0x8c4
[42278.299788] [d1257d00] [c0010df4] kernel_bad_stack+0x0/0x4c
[42278.301067] [d1257d20] [c00164f4] bad_page_fault+0xb8/0xcc
[42278.302344] [d1257d30] [c0012d80] handle_page_fault+0x7c/0x80
[42278.303643] --- Exception: 300 at skb_dequeue+0x48/0xa0
[42278.304932] LR = ieee80211_if_reinit+0x1c0/0x284 [mac80211]
[42278.306184] [d1257df0] [df3323a0] 0xdf3323a0 (unreliable)
[42278.307459] [d1257e00] [e20d410c] ieee80211_if_reinit+0x1c0/0x284 [mac80211]
[42278.308816] [d1257e30] [c033af58] register_netdevice+0x3f0/0x408
[42278.310112] [d1257e50] [e20d3e94] ieee80211_if_add+0x118/0x1d0 [mac80211]
[42278.311455] [d1257e80] [e20d5a6c] ieee80211_add_iface+0x8c/0x9c [mac80211]
[42278.312787] [d1257e90] [c0420608] _store_add_iface+0x70/0x9c
[42278.314052] [d1257eb0] [c021a704] dev_attr_store+0x28/0x40
[42278.315289] [d1257ec0] [c00c09ac] sysfs_write_file+0x13c/0x1c4
[42278.316537] [d1257ef0] [c007c56c] vfs_write+0xc0/0x164
[42278.317761] [d1257f10] [c007cbc4] sys_write+0x4c/0x8c
[42278.318996] [d1257f40] [c00128e4] ret_from_syscall+0x0/0x38
[42278.320243] --- Exception: c01 at 0xfed0c18
[42278.321410] LR = 0xfe7963c
[42289.710017] b43-phy4 debug: Current TX power output: 14.25 dBm, Desired TX power output: 14.25 dBm
[42299.370401] wmaster0: Discarded packet with nonexistent originating device
[42305.370223] wmaster0: Discarded packet with nonexistent originating device
[42312.370226] wmaster0: Discarded packet with nonexistent originating device
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: mac80211: crash while adding interface.
2007-09-25 20:06 mac80211: crash while adding interface Michael Buesch
@ 2007-09-25 20:36 ` Johannes Berg
2007-09-25 20:45 ` Johannes Berg
2007-09-25 21:31 ` [PATCH] mac80211: fix interface initialisation Johannes Berg
1 sibling, 1 reply; 10+ messages in thread
From: Johannes Berg @ 2007-09-25 20:36 UTC (permalink / raw)
To: Michael Buesch; +Cc: Michael Wu, linux-wireless
On Tue, 2007-09-25 at 22:06 +0200, Michael Buesch wrote:
> The following happened when adding an interface through sysfs
> on b43, while another one was operating and transmitting data:
As discussed, this is because register_netdevice() didn't like the
device. Try this patch.
johannes
--- wireless-dev.orig/net/mac80211/ieee80211.c 2007-09-25 22:26:31.341579155 +0200
+++ wireless-dev/net/mac80211/ieee80211.c 2007-09-25 22:29:12.421568847 +0200
@@ -266,7 +266,6 @@ void ieee80211_if_mgmt_setup(struct net_
dev->stop = ieee80211_mgmt_stop;
dev->type = ARPHRD_IEEE80211_PRISM;
dev->hard_header_parse = header_parse_80211;
- dev->uninit = ieee80211_if_reinit;
dev->destructor = ieee80211_if_free;
}
@@ -543,7 +542,6 @@ void ieee80211_if_setup(struct net_devic
dev->change_mtu = ieee80211_change_mtu;
dev->open = ieee80211_open;
dev->stop = ieee80211_stop;
- dev->uninit = ieee80211_if_reinit;
dev->destructor = ieee80211_if_free;
}
@@ -1233,6 +1231,12 @@ int ieee80211_register_hw(struct ieee802
if (result < 0)
goto fail_dev;
+ /*
+ * Called even when register_netdevice fails, it would
+ * oops if assigned before initialising the rest.
+ */
+ local->mdev->uninit = ieee80211_if_reinit;
+
ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev));
result = ieee80211_init_rate_ctrl_alg(local, NULL);
--- wireless-dev.orig/net/mac80211/ieee80211_iface.c 2007-09-25 22:26:40.111572537 +0200
+++ wireless-dev/net/mac80211/ieee80211_iface.c 2007-09-25 22:32:27.631569281 +0200
@@ -76,6 +76,12 @@ int ieee80211_if_add(struct net_device *
if (ret)
goto fail;
+ /*
+ * Called even when register_netdevice fails, it would
+ * oops if assigned before initialising the rest.
+ */
+ ndev->uninit = ieee80211_if_reinit;
+
ieee80211_debugfs_add_netdev(sdata);
ieee80211_if_set_type(ndev, type);
@@ -127,6 +133,12 @@ int ieee80211_if_add_mgmt(struct ieee802
if (ret)
goto fail;
+ /*
+ * Called even when register_netdevice fails, it would
+ * oops if assigned before initialising the rest.
+ */
+ ndev->uninit = ieee80211_if_reinit;
+
ieee80211_debugfs_add_netdev(nsdata);
if (local->open_count > 0)
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: mac80211: crash while adding interface.
2007-09-25 20:36 ` Johannes Berg
@ 2007-09-25 20:45 ` Johannes Berg
0 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2007-09-25 20:45 UTC (permalink / raw)
To: Michael Buesch; +Cc: Michael Wu, linux-wireless
Actually, try this, it fixes another bug too.
--- wireless-dev.orig/net/mac80211/ieee80211.c 2007-09-25 22:26:31.341579155 +0200
+++ wireless-dev/net/mac80211/ieee80211.c 2007-09-25 22:43:38.681568738 +0200
@@ -266,7 +266,6 @@ void ieee80211_if_mgmt_setup(struct net_
dev->stop = ieee80211_mgmt_stop;
dev->type = ARPHRD_IEEE80211_PRISM;
dev->hard_header_parse = header_parse_80211;
- dev->uninit = ieee80211_if_reinit;
dev->destructor = ieee80211_if_free;
}
@@ -543,7 +542,6 @@ void ieee80211_if_setup(struct net_devic
dev->change_mtu = ieee80211_change_mtu;
dev->open = ieee80211_open;
dev->stop = ieee80211_stop;
- dev->uninit = ieee80211_if_reinit;
dev->destructor = ieee80211_if_free;
}
@@ -1234,6 +1232,7 @@ int ieee80211_register_hw(struct ieee802
goto fail_dev;
ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev));
+ ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP);
result = ieee80211_init_rate_ctrl_alg(local, NULL);
if (result < 0) {
--- wireless-dev.orig/net/mac80211/ieee80211_iface.c 2007-09-25 22:26:40.111572537 +0200
+++ wireless-dev/net/mac80211/ieee80211_iface.c 2007-09-25 22:41:52.251569443 +0200
@@ -127,6 +127,12 @@ int ieee80211_if_add_mgmt(struct ieee802
if (ret)
goto fail;
+ /*
+ * Called even when register_netdevice fails, it would
+ * oops if assigned before initialising the rest.
+ */
+ ndev->uninit = ieee80211_if_reinit;
+
ieee80211_debugfs_add_netdev(nsdata);
if (local->open_count > 0)
@@ -157,6 +163,12 @@ void ieee80211_if_set_type(struct net_de
dev->hard_start_xmit = ieee80211_subif_start_xmit;
+ /*
+ * Called even when register_netdevice fails, it would
+ * oops if assigned before initialising the rest.
+ */
+ dev->uninit = ieee80211_if_reinit;
+
sdata->type = type;
switch (type) {
case IEEE80211_IF_TYPE_WDS:
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] mac80211: fix interface initialisation
2007-09-25 20:06 mac80211: crash while adding interface Michael Buesch
2007-09-25 20:36 ` Johannes Berg
@ 2007-09-25 21:31 ` Johannes Berg
2007-09-25 21:32 ` Michael Buesch
` (2 more replies)
1 sibling, 3 replies; 10+ messages in thread
From: Johannes Berg @ 2007-09-25 21:31 UTC (permalink / raw)
To: Michael Buesch; +Cc: Michael Wu, linux-wireless
When an interface is registered it is still uninitialised so
ieee80211_if_reinit() can't be called on it (it will oops.)
Hence, we need to move the uninit method assignment. Also,
this patch fixes the bug that the master device is never
initialised at all.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
net/mac80211/ieee80211.c | 3 +--
net/mac80211/ieee80211_iface.c | 20 +++++++++++++++++++-
2 files changed, 20 insertions(+), 3 deletions(-)
--- wireless-dev.orig/net/mac80211/ieee80211.c 2007-09-25 22:26:31.341579155 +0200
+++ wireless-dev/net/mac80211/ieee80211.c 2007-09-25 23:28:21.581572375 +0200
@@ -266,7 +266,6 @@ void ieee80211_if_mgmt_setup(struct net_
dev->stop = ieee80211_mgmt_stop;
dev->type = ARPHRD_IEEE80211_PRISM;
dev->hard_header_parse = header_parse_80211;
- dev->uninit = ieee80211_if_reinit;
dev->destructor = ieee80211_if_free;
}
@@ -543,7 +542,6 @@ void ieee80211_if_setup(struct net_devic
dev->change_mtu = ieee80211_change_mtu;
dev->open = ieee80211_open;
dev->stop = ieee80211_stop;
- dev->uninit = ieee80211_if_reinit;
dev->destructor = ieee80211_if_free;
}
@@ -1234,6 +1232,7 @@ int ieee80211_register_hw(struct ieee802
goto fail_dev;
ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev));
+ ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP);
result = ieee80211_init_rate_ctrl_alg(local, NULL);
if (result < 0) {
--- wireless-dev.orig/net/mac80211/ieee80211_iface.c 2007-09-25 22:26:40.111572537 +0200
+++ wireless-dev/net/mac80211/ieee80211_iface.c 2007-09-25 23:28:21.651570910 +0200
@@ -127,6 +127,12 @@ int ieee80211_if_add_mgmt(struct ieee802
if (ret)
goto fail;
+ /*
+ * Called even when register_netdevice fails, it would
+ * oops if assigned before initialising the rest.
+ */
+ ndev->uninit = ieee80211_if_reinit;
+
ieee80211_debugfs_add_netdev(nsdata);
if (local->open_count > 0)
@@ -155,7 +161,19 @@ void ieee80211_if_set_type(struct net_de
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
int oldtype = sdata->type;
- dev->hard_start_xmit = ieee80211_subif_start_xmit;
+ /*
+ * We need to call this function on the master interface
+ * which already has a hard_start_xmit routine assigned
+ * which must not be changed.
+ */
+ if (!dev->hard_start_xmit)
+ dev->hard_start_xmit = ieee80211_subif_start_xmit;
+
+ /*
+ * Called even when register_netdevice fails, it would
+ * oops if assigned before initialising the rest.
+ */
+ dev->uninit = ieee80211_if_reinit;
sdata->type = type;
switch (type) {
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] mac80211: fix interface initialisation
2007-09-25 21:31 ` [PATCH] mac80211: fix interface initialisation Johannes Berg
@ 2007-09-25 21:32 ` Michael Buesch
2007-09-25 21:44 ` Johannes Berg
2007-09-26 0:02 ` Luis R. Rodriguez
2007-09-26 12:27 ` [PATCH v2] mac80211: fix interface initialisation and deinitialisation Johannes Berg
2 siblings, 1 reply; 10+ messages in thread
From: Michael Buesch @ 2007-09-25 21:32 UTC (permalink / raw)
To: Johannes Berg; +Cc: Michael Wu, linux-wireless
On Tuesday 25 September 2007 23:31:32 Johannes Berg wrote:
> When an interface is registered it is still uninitialised so
> ieee80211_if_reinit() can't be called on it (it will oops.)
> Hence, we need to move the uninit method assignment. Also,
> this patch fixes the bug that the master device is never
> initialised at all.
>
> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
I guess you should send this
To: John Linville
instead :)
Though, I tested this and ACK it.
> ---
> net/mac80211/ieee80211.c | 3 +--
> net/mac80211/ieee80211_iface.c | 20 +++++++++++++++++++-
> 2 files changed, 20 insertions(+), 3 deletions(-)
>
> --- wireless-dev.orig/net/mac80211/ieee80211.c 2007-09-25 22:26:31.341579155 +0200
> +++ wireless-dev/net/mac80211/ieee80211.c 2007-09-25 23:28:21.581572375 +0200
> @@ -266,7 +266,6 @@ void ieee80211_if_mgmt_setup(struct net_
> dev->stop = ieee80211_mgmt_stop;
> dev->type = ARPHRD_IEEE80211_PRISM;
> dev->hard_header_parse = header_parse_80211;
> - dev->uninit = ieee80211_if_reinit;
> dev->destructor = ieee80211_if_free;
> }
>
> @@ -543,7 +542,6 @@ void ieee80211_if_setup(struct net_devic
> dev->change_mtu = ieee80211_change_mtu;
> dev->open = ieee80211_open;
> dev->stop = ieee80211_stop;
> - dev->uninit = ieee80211_if_reinit;
> dev->destructor = ieee80211_if_free;
> }
>
> @@ -1234,6 +1232,7 @@ int ieee80211_register_hw(struct ieee802
> goto fail_dev;
>
> ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev));
> + ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP);
>
> result = ieee80211_init_rate_ctrl_alg(local, NULL);
> if (result < 0) {
> --- wireless-dev.orig/net/mac80211/ieee80211_iface.c 2007-09-25 22:26:40.111572537 +0200
> +++ wireless-dev/net/mac80211/ieee80211_iface.c 2007-09-25 23:28:21.651570910 +0200
> @@ -127,6 +127,12 @@ int ieee80211_if_add_mgmt(struct ieee802
> if (ret)
> goto fail;
>
> + /*
> + * Called even when register_netdevice fails, it would
> + * oops if assigned before initialising the rest.
> + */
> + ndev->uninit = ieee80211_if_reinit;
> +
> ieee80211_debugfs_add_netdev(nsdata);
>
> if (local->open_count > 0)
> @@ -155,7 +161,19 @@ void ieee80211_if_set_type(struct net_de
> struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
> int oldtype = sdata->type;
>
> - dev->hard_start_xmit = ieee80211_subif_start_xmit;
> + /*
> + * We need to call this function on the master interface
> + * which already has a hard_start_xmit routine assigned
> + * which must not be changed.
> + */
> + if (!dev->hard_start_xmit)
> + dev->hard_start_xmit = ieee80211_subif_start_xmit;
> +
> + /*
> + * Called even when register_netdevice fails, it would
> + * oops if assigned before initialising the rest.
> + */
> + dev->uninit = ieee80211_if_reinit;
>
> sdata->type = type;
> switch (type) {
>
>
>
>
--
Greetings Michael.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] mac80211: fix interface initialisation
2007-09-25 21:32 ` Michael Buesch
@ 2007-09-25 21:44 ` Johannes Berg
0 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2007-09-25 21:44 UTC (permalink / raw)
To: Michael Buesch; +Cc: Michael Wu, linux-wireless, John W. Linville
[-- Attachment #1: Type: text/plain, Size: 634 bytes --]
On Tue, 2007-09-25 at 23:32 +0200, Michael Buesch wrote:
> On Tuesday 25 September 2007 23:31:32 Johannes Berg wrote:
> > When an interface is registered it is still uninitialised so
> > ieee80211_if_reinit() can't be called on it (it will oops.)
> > Hence, we need to move the uninit method assignment. Also,
> > this patch fixes the bug that the master device is never
> > initialised at all.
> >
> > Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
>
> I guess you should send this
> To: John Linville
> instead :)
yeah, I did reply-to-all and sent before I changed it. John, please pick
up.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] mac80211: fix interface initialisation
2007-09-25 21:31 ` [PATCH] mac80211: fix interface initialisation Johannes Berg
2007-09-25 21:32 ` Michael Buesch
@ 2007-09-26 0:02 ` Luis R. Rodriguez
2007-09-26 7:04 ` Johannes Berg
2007-09-26 12:27 ` [PATCH v2] mac80211: fix interface initialisation and deinitialisation Johannes Berg
2 siblings, 1 reply; 10+ messages in thread
From: Luis R. Rodriguez @ 2007-09-26 0:02 UTC (permalink / raw)
To: Johannes Berg
Cc: Michael Buesch, Michael Wu, linux-wireless, John W. Linville
On 9/25/07, Johannes Berg <johannes@sipsolutions.net> wrote:
> --- wireless-dev.orig/net/mac80211/ieee80211_iface.c 2007-09-25 22:26:40.111572537 +0200
> +++ wireless-dev/net/mac80211/ieee80211_iface.c 2007-09-25 23:28:21.651570910 +0200
> @@ -127,6 +127,12 @@ int ieee80211_if_add_mgmt(struct ieee802
> if (ret)
> goto fail;
>
> + /*
> + * Called even when register_netdevice fails, it would
> + * oops if assigned before initialising the rest.
> + */
> + ndev->uninit = ieee80211_if_reinit;
> +
> ieee80211_debugfs_add_netdev(nsdata);
>
> if (local->open_count > 0)
What still uses ieee80211_if_add_mgmt()? I don't see anything using
it. Also, did we decide on what to do with IEEE80211_IF_TYPE_MGMT?
Luis
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] mac80211: fix interface initialisation
2007-09-26 0:02 ` Luis R. Rodriguez
@ 2007-09-26 7:04 ` Johannes Berg
0 siblings, 0 replies; 10+ messages in thread
From: Johannes Berg @ 2007-09-26 7:04 UTC (permalink / raw)
To: Luis R. Rodriguez
Cc: Michael Buesch, Michael Wu, linux-wireless, John W. Linville
[-- Attachment #1: Type: text/plain, Size: 264 bytes --]
On Tue, 2007-09-25 at 20:02 -0400, Luis R. Rodriguez wrote:
> What still uses ieee80211_if_add_mgmt()? I don't see anything using
> it. Also, did we decide on what to do with IEEE80211_IF_TYPE_MGMT?
We don't have a replacement for hostapd yet.
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2] mac80211: fix interface initialisation and deinitialisation
2007-09-25 21:31 ` [PATCH] mac80211: fix interface initialisation Johannes Berg
2007-09-25 21:32 ` Michael Buesch
2007-09-26 0:02 ` Luis R. Rodriguez
@ 2007-09-26 12:27 ` Johannes Berg
2007-09-26 14:37 ` Michael Buesch
2 siblings, 1 reply; 10+ messages in thread
From: Johannes Berg @ 2007-09-26 12:27 UTC (permalink / raw)
To: John W. Linville; +Cc: Michael Wu, linux-wireless, Michael Buesch
When an interface is registered it is still uninitialised so
ieee80211_if_reinit() can't be called on it (it will oops.)
Hence, we need to move the uninit method assignment.
Also, this patch fixes the bug that the master device is never
initialised nor deinitialised at all. Oddly, the deinit code
had an if statement to not run some code when running for the
master interface (which never happened), but that if statement
is also wrong. Fix that too.
Now that the uninit code is run for the master device, another
bug surfaced: it tries to remove all dependent interfaces and
that oopses or BUGs at some point, either because it unregisters
already unregistered interfaces (missing list_del bug) or due
to trying to iterate a list that has had other things removed.
Fix this too by handling the master interface specially.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
net/mac80211/ieee80211.c | 19 ++++++++++++++++---
net/mac80211/ieee80211_iface.c | 35 +++++++++++++++++++++++++++--------
2 files changed, 43 insertions(+), 11 deletions(-)
--- wireless-dev.orig/net/mac80211/ieee80211.c 2007-09-26 12:39:30.970162850 +0200
+++ wireless-dev/net/mac80211/ieee80211.c 2007-09-26 14:08:54.109659539 +0200
@@ -266,7 +266,6 @@ void ieee80211_if_mgmt_setup(struct net_
dev->stop = ieee80211_mgmt_stop;
dev->type = ARPHRD_IEEE80211_PRISM;
dev->hard_header_parse = header_parse_80211;
- dev->uninit = ieee80211_if_reinit;
dev->destructor = ieee80211_if_free;
}
@@ -543,7 +542,6 @@ void ieee80211_if_setup(struct net_devic
dev->change_mtu = ieee80211_change_mtu;
dev->open = ieee80211_open;
dev->stop = ieee80211_stop;
- dev->uninit = ieee80211_if_reinit;
dev->destructor = ieee80211_if_free;
}
@@ -1234,6 +1232,7 @@ int ieee80211_register_hw(struct ieee802
goto fail_dev;
ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev));
+ ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP);
result = ieee80211_init_rate_ctrl_alg(local, NULL);
if (result < 0) {
@@ -1338,8 +1337,22 @@ void ieee80211_unregister_hw(struct ieee
* because the driver cannot be handing us frames any
* more and the tasklet is killed.
*/
- list_for_each_entry_safe(sdata, tmp, &local->interfaces, list)
+
+ /*
+ * First, we remove all non-master interfaces. Do this because they
+ * may have bss pointer dependency on the master, and when we free
+ * the master these would be freed as well, breaking our list
+ * iteration completely.
+ */
+ list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
+ if (sdata->dev == local->mdev)
+ continue;
+ list_del(&sdata->list);
__ieee80211_if_del(local, sdata);
+ }
+
+ /* then, finally, remove the master interface */
+ __ieee80211_if_del(local, IEEE80211_DEV_TO_SUB_IF(local->mdev));
rtnl_unlock();
--- wireless-dev.orig/net/mac80211/ieee80211_iface.c 2007-09-26 12:39:31.050162850 +0200
+++ wireless-dev/net/mac80211/ieee80211_iface.c 2007-09-26 14:09:42.479659539 +0200
@@ -127,6 +127,12 @@ int ieee80211_if_add_mgmt(struct ieee802
if (ret)
goto fail;
+ /*
+ * Called even when register_netdevice fails, it would
+ * oops if assigned before initialising the rest.
+ */
+ ndev->uninit = ieee80211_if_reinit;
+
ieee80211_debugfs_add_netdev(nsdata);
if (local->open_count > 0)
@@ -155,12 +161,27 @@ void ieee80211_if_set_type(struct net_de
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
int oldtype = sdata->type;
- dev->hard_start_xmit = ieee80211_subif_start_xmit;
+ /*
+ * We need to call this function on the master interface
+ * which already has a hard_start_xmit routine assigned
+ * which must not be changed.
+ */
+ if (!dev->hard_start_xmit)
+ dev->hard_start_xmit = ieee80211_subif_start_xmit;
+
+ /*
+ * Called even when register_netdevice fails, it would
+ * oops if assigned before initialising the rest.
+ */
+ dev->uninit = ieee80211_if_reinit;
+ /* most have no BSS pointer */
+ sdata->bss = NULL;
sdata->type = type;
+
switch (type) {
case IEEE80211_IF_TYPE_WDS:
- sdata->bss = NULL;
+ /* nothing special */
break;
case IEEE80211_IF_TYPE_VLAN:
sdata->u.vlan.ap = NULL;
@@ -213,6 +234,7 @@ void ieee80211_if_reinit(struct net_devi
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct sta_info *sta;
+ struct sk_buff *skb;
ASSERT_RTNL();
@@ -246,12 +268,9 @@ void ieee80211_if_reinit(struct net_devi
kfree(sdata->u.ap.beacon_tail);
kfree(sdata->u.ap.generic_elem);
- if (dev != local->mdev) {
- struct sk_buff *skb;
- while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
- local->total_ps_buffered--;
- dev_kfree_skb(skb);
- }
+ while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
+ local->total_ps_buffered--;
+ dev_kfree_skb(skb);
}
break;
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] mac80211: fix interface initialisation and deinitialisation
2007-09-26 12:27 ` [PATCH v2] mac80211: fix interface initialisation and deinitialisation Johannes Berg
@ 2007-09-26 14:37 ` Michael Buesch
0 siblings, 0 replies; 10+ messages in thread
From: Michael Buesch @ 2007-09-26 14:37 UTC (permalink / raw)
To: Johannes Berg; +Cc: John W. Linville, Michael Wu, linux-wireless
On Wednesday 26 September 2007 14:27:23 Johannes Berg wrote:
> When an interface is registered it is still uninitialised so
> ieee80211_if_reinit() can't be called on it (it will oops.)
> Hence, we need to move the uninit method assignment.
>
> Also, this patch fixes the bug that the master device is never
> initialised nor deinitialised at all. Oddly, the deinit code
> had an if statement to not run some code when running for the
> master interface (which never happened), but that if statement
> is also wrong. Fix that too.
>
> Now that the uninit code is run for the master device, another
> bug surfaced: it tries to remove all dependent interfaces and
> that oopses or BUGs at some point, either because it unregisters
> already unregistered interfaces (missing list_del bug) or due
> to trying to iterate a list that has had other things removed.
> Fix this too by handling the master interface specially.
>
> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
This works fine without any crashes or problems here.
--
Greetings Michael.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2007-09-26 14:41 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-25 20:06 mac80211: crash while adding interface Michael Buesch
2007-09-25 20:36 ` Johannes Berg
2007-09-25 20:45 ` Johannes Berg
2007-09-25 21:31 ` [PATCH] mac80211: fix interface initialisation Johannes Berg
2007-09-25 21:32 ` Michael Buesch
2007-09-25 21:44 ` Johannes Berg
2007-09-26 0:02 ` Luis R. Rodriguez
2007-09-26 7:04 ` Johannes Berg
2007-09-26 12:27 ` [PATCH v2] mac80211: fix interface initialisation and deinitialisation Johannes Berg
2007-09-26 14:37 ` Michael Buesch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).