I have loaded SMC Ultra ethernet module successfully with 2 different computers. When I try to remove them with rmmod, there's a kernel oops (eth0's are epic100's on the both computers): ------ Sep 6 15:36:35 test11 kernel: smc-ultra.c: Presently autoprobing (not recommended) for a single card. Sep 6 15:36:35 test11 kernel: smc-ultra.c:v2.02 2/3/98 Donald Becker (becker.nasa.gov) Sep 6 15:36:35 test11 kernel: eth1: SMC Ultra at 0x300, 00 00 C0 7E 9D A1, IRQ 10 memory 0xcc000-0xcffff. Sep 6 15:36:52 test11 kernel: Unable to handle kernel NULL pointer dereference at virtual address 00000030 Sep 6 15:36:52 test11 kernel: current->tss.cr3 = 06377000, %cr3 = 06377000 Sep 6 15:36:52 test11 kernel: *pde = 00000000 Sep 6 15:36:52 test11 kernel: Oops: 0000 Sep 6 15:36:52 test11 kernel: CPU: 0 Sep 6 15:36:52 test11 kernel: EIP: 0010:[__rta_fill+86/108] Sep 6 15:36:52 test11 kernel: EFLAGS: 00010206 Sep 6 15:36:52 test11 kernel: eax: 00000007 ebx: 0000005c ecx: 00000017 edx: 00000060 Sep 6 15:36:52 test11 kernel: esi: 00000030 edi: c65e105c ebp: 00000060 esp: c6379eec Sep 6 15:36:52 test11 kernel: ds: 0018 es: 0018 ss: 0018 Sep 6 15:36:52 test11 kernel: Process rmmod (pid: 525, process nr: 24, stackpage=c6379000) Sep 6 15:36:52 test11 kernel: Stack: 00000ef8 c882dc00 c015077a c5dbbaa0 00000007 0000005c 00000030 c5dbbaa0 Sep 6 15:36:52 test11 kernel: c882dc00 00000000 c882dc00 c0203a48 00000005 000005dc c015092e c5dbbaa0 Sep 6 15:36:52 test11 kernel: c882dc00 00000011 00000000 00000000 c02039c0 c0150e18 00000011 c882dc00 Sep 6 15:36:52 test11 kernel: Call Trace: [<c882dc00>] [rtnetlink_fill_ifinfo+590/652] [<c882dc00>] [<c882dc00>] [rtmsg_ifinfo+42/104] [<c882dc00>] [rtnetlink_event+24/32] Sep 6 15:36:52 test11 kernel: [<c882dc00>] [unregister_netdevice+60/192] [<c882dc00>] [<c882dc00>] [unregister_netdev+16/32] [<c 882dc00>] [<c882d98d>] [<c882dc00>] Sep 6 15:36:52 test11 kernel: [<c882d000>] [<c882d000>] [free_module+32/148] [<c882d000>] [sys_delete_module+298/464] [<c882d000 >] [system_call+52/56] Sep 6 15:36:52 test11 kernel: Code: f3 a5 f6 c3 02 74 02 66 a5 f6 c3 01 74 01 a4 5b 5e 5f 5d c3 ------- After that, weird things happen: ----- [root@test11 /root]# lsmod Module Size Used by lsmod: QM_INFO: No such file or directory ----- Any ideas? ------- Additional Comments From 09/29/99 17:01 ------- 1) Module loads fine. "ifconfig" behaves as expected. "ping" to self succeeds. "ping" to other machine fails w/ 100% packet loss. 2) Compiling into the kernel (ie non-module) doesn't help. 3) Also happens on eth0. 4) "wd" also affected. No segfault on rmmod, though. 5) Other modules dependent on 8390 (eg "ne") behave as expected. Notes: 3 different SMC Ultra (16bit/ISA) and 1 smc ?? (works with "wd" module in RH5.x) cards tested in 2 machines.
I emailed this to linux-net.edu mailing list, and Paul Gortmaker <p_gortmaker> supplied a patch for it. His message: -------- The disallocation of resources wasn't ordered properly. (I'm sure they [8390-based] all were at some point...) Anyways this should fix it. I'll go and have a look to make sure the others (2.2 & 2.3) are ordered properly as well. Paul. --- drivers/net/smc-ultra.c~ Thu Sep 30 04:11:31 1999 +++ drivers/net/smc-ultra.c Thu Sep 30 04:26:05 1999 @@ -480,14 +480,14 @@ for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) { struct device *dev = &dev_ultra[this_dev]; if (dev->priv != NULL) { - /* NB: ultra_close_card() does free_irq + irq2dev */ + /* NB: ultra_close_card() does free_irq */ int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; - kfree(dev->priv); - release_region(ioaddr, ULTRA_IO_EXTENT); unregister_netdev(dev); - dev->priv = NULL; + release_region(ioaddr, ULTRA_IO_EXTENT); + kfree(dev->priv); } } + unlock_8390_module(); } #endif /* MODULE */ -----------
*** Bug 6452 has been marked as a duplicate of this bug. *** Description Network driver lance.o unconditionaly oops on rmmod or auto unloading. The same was true with RH6.0 Conclusion. The following patch works for me. --- drivers/net/lance.c.orig Mon Aug 9 23:04:39 1999 +++ drivers/net/lance.c Wed Oct 27 22:07:16 1999 @@ -349,11 +349,11 @@ for (this_dev = 0; this_dev < MAX_CARDS; this_dev++) { struct device *dev = &dev_lance[this_dev]; if (dev->priv != NULL) { - kfree(dev->priv); - dev->priv = NULL; free_dma(dev->dma); release_region(dev->base_addr, LANCE_TOTAL_SIZE); unregister_netdev(dev); + kfree(dev->priv); + dev->priv = NULL; } } }
Assigned to dledford
Fixed in the current kernel in Raw Hide.