On Tue, 24 Feb 2004 viro@parcelfarce.linux.theplanet.co.uk wrote:
> On Mon, Feb 23, 2004 at 10:49:50PM -0500, Pavel Roskin wrote:
> > orinoco_plx. I've put the current snapshot here:
> > http://www.red-bean.com/~proski/tmp/orinoco-oops.tar.gz
>
> What happens with the version in Linus' tree?
The version in the Linux source doesn't crash because it doesn't call
netif_carrier_off(). The CVS version of the Orinoco driver calls
netif_carrier_off() after the device is allocated. The idea is to set
carrier to on only when the firmware associates and indicates it by
passing an informational frame to the driver.
The second version of the dummy patch is attached. It models the problem
much better.
# modprobe dummy
Unable to handle kernel paging request at virtual address 6b6b6b77
printing eip:
c02d0d88
*pde = 00000000
Oops: 0000 [#1]
CPU: 0
EIP: 0060:[<c02d0d88>] Not tainted
EFLAGS: 00010216
EIP is at rtnetlink_fill_ifinfo+0x278/0x430
eax: 6b6b6b6b ebx: cf51f9a0 ecx: 00000a5c edx: cd975504
esi: 00000000 edi: cd97548c ebp: c12b9ed8 esp: c12b9eb4
ds: 007b es: 007b ss: 0068
Process events/0 (pid: 3, threadinfo=c12b8000 task=c12bcc80)
Stack: c12b9ec8 00000a5c 00000f40 cd975000 cf0cd68c 6b6b6b6b cf0cd68c
00000000
00000010 c12b9efc c02d11b6 00000000 00000000 00000000 cf51f9a0
cf51f9a0
c12b9f20 c12b9f20 c12b9f34 c02d1a67 00000001 00000003 c036d100
ee8f4eb7
Call Trace:
[<c02d11b6>] rtmsg_ifinfo+0x46/0xb0
[<c02d1a67>] linkwatch_run_queue+0x147/0x1f0
[<c02d1b52>] linkwatch_event+0x42/0x70
[<c01363b4>] worker_thread+0x1f4/0x3e0
[<c0119f67>] recalc_task_prio+0x97/0x1c0
[<c02d1b10>] linkwatch_event+0x0/0x70
[<c011b6e0>] default_wake_function+0x0/0x10
[<c011b6e0>] default_wake_function+0x0/0x10
[<c013b105>] kthread+0x95/0xa0
[<c01361c0>] worker_thread+0x0/0x3e0
[<c013b070>] kthread+0x0/0xa0
[<c0107019>] kernel_thread_helper+0x5/0xc
Code: 8b 50 0c b9 ff ff ff ff 31 c0 83 c2 08 89 d7 f2 ae f7 d1 49
--
Regards,
Pavel Roskin
--- linux.orig/drivers/net/dummy.c
+++ linux/drivers/net/dummy.c
@@ -91,6 +91,11 @@ static struct net_device **dummies;
/* Number of dummy devices to be set up by this module. */
module_param(numdummies, int, 0);
+static int dummy_bad_init(struct net_device *dev)
+{
+ return -EBUSY;
+}
+
static int __init dummy_init_one(int index)
{
struct net_device *dev_dummy;
@@ -98,10 +103,12 @@ static int __init dummy_init_one(int ind
dev_dummy = alloc_netdev(sizeof(struct net_device_stats),
"dummy%d", dummy_setup);
+ netif_carrier_off(dev_dummy);
if (!dev_dummy)
return -ENOMEM;
+ dev_dummy->init = dummy_bad_init;
if ((err = register_netdev(dev_dummy))) {
free_netdev(dev_dummy);
dev_dummy = NULL;
@@ -127,6 +134,7 @@ static int __init dummy_init_module(void
for (i = 0; i < numdummies && !err; i++)
err = dummy_init_one(i);
if (err) {
+ i--;
while (--i >= 0)
dummy_free_one(i);
}