Bug 215826 - kernel BUG at net/core/dev.c:2936! Unloading of custom virtual device driver causes kernel oops.
kernel BUG at net/core/dev.c:2936! Unloading of custom virtual device driver ...
Status: CLOSED NOTABUG
Product: Red Hat Enterprise Linux 4
Classification: Red Hat
Component: kernel (Show other bugs)
4.0
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Kernel Maintainer List
Brian Brock
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2006-11-15 17:15 EST by Jacek Materna
Modified: 2007-11-30 17:07 EST (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2006-12-04 17:17:06 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:


Attachments (Terms of Use)

  None (edit)
Description Jacek Materna 2006-11-15 17:15:51 EST
Description of problem:

Network Device virtual device driver custom module hooking to physical device
driver causes kernel oops upon module unregistration.

via:

>modprobe -r <module>

Here is the process to load the module:

/sbin/depmod -a
/sbin/modprobe <module>

/sbin/ifconfig <module> up

Runtime ......

Now shutdown

/sbin/ifconfig <module> down
/sbin/modprobe -r <module>

Some details while unloading:
<module> interface down'd succesfully
unregister_netdev successfull
./shutdown_<module>.sh: line 5:  3661 Segmentation fault      /sbin/modprobe -r
<module>

which cause oops in dmesg

kernel BUG at net/core/dev.c:2936!
invalid operand: 0000 [#1]
Modules linked in: voiceHIPS(U) autofs4 i2c_dev i2c_core sunrpc button battery
ac md5 ipv6 uhci_hcd snd_intel8x0 snd_ac97_codec snd_pcm_oss snd_mixer_oss
snd_pcm snd_timer snd_page_alloc snd_mpu401_uart snd_rawmidi snd_seq_device snd
soundcore 3c59x floppy dm_snapshot dm_zero dm_mirror ext3 jbd dm_mod
CPU:    0
EIP:    0060:[<c02a891b>]    Tainted: P      VLI
EFLAGS: 00010202   (2.6.9-5.EL)
EIP is at free_netdev+0x1a/0x36
eax: d5371000   ebx: e09f2c00   ecx: 00000000   edx: 00000005
esi: c034f1c0   edi: 00000000   ebp: c93dc000   esp: c93dcf68
ds: 007b   es: 007b   ss: 0068
Process modprobe (pid: 3661, threadinfo=c93dc000 task=d62be130)
Stack: e09f0b7e c0139481 00000000 63696f76 50494865 00000053 00000000 c16ee380
       b7fff000 b8000000 c01549dc c16ee380 dad7d5b8 c0154d8b dad7d120 c16ee380
       096e65c0 00000004 c0119234 096e60c0 00000000 096e60c0 c0301bfb 096e60c0
Call Trace:
 [<e09f0b7e>] throttle_spec_exit_module+0x8e/0xac [voiceHIPS]
 [<c0139481>] sys_delete_module+0x132/0x179
 [<c01549dc>] unmap_vma_list+0xe/0x17
 [<c0154d8b>] do_munmap+0x1c8/0x1d2
 [<c0119234>] do_page_fault+0x0/0x4dc
 [<c0301bfb>] syscall_call+0x7/0xb
Code: 05 60 f6 36 c0 0f 8e a7 03 00 00 5e 5f 5b 5e 5f c3 8b 90 a0 01 00 00 85 d2
75 0b 2b 80 6c 02 00 00 e9 a1 20 ea ff 83 fa 04 74 08 <0f> 0b 78 0b c6 23 33 c0
c7 80 a0 01 00 00 05 00 00 00 05 10 02


Here is some snippets of code of loading, unloading,

LOADING
-------
static struct net_device *throttle_spec_dev;
....
alloc_size = sizeof(struct net_device);

throttle_spec_dev = kmalloc(alloc_size, GFP_KERNEL);
if (!throttle_spec_dev)
return -ENOMEM;
	
memset(throttle_spec_dev, 0, alloc_size);

snprintf(name, IFNAMSIZ, "name");
dev = alloc_netdev(sizeof(struct vthrottle), name, throttle_spec_setup);


UNLOADING
--------
unregister_netdev(throttle_spec_dev);
			
if (throttle_spec_dev->reg_state != NETREG_UNREGISTERED) {
	print_string("throttle_spec_dev->reg_state != NETREG_UNREGISTERED");
}
		
print_string("unregister_netdev successfull");
free_netdev(throttle_spec_dev); // KERNEL OOPS occurs here,
print_string("free_netdev successful");	

Example from GPL kernel 2.6.17
-------------------
3117  *      free_netdev - free network device
3118  *      @dev: device
3119  *
3120  *      This function does the last stage of destroying an allocated device 
3121  *      interface. The reference to the device object is released.  
3122  *      If this is the last reference then it will be freed.
3123  */
3124 void free_netdev(struct net_device *dev)
3125 {
3126 #ifdef CONFIG_SYSFS
3127         /*  Compatibility with error handling in drivers */
3128         if (dev->reg_state == NETREG_UNINITIALIZED) {
3129                 kfree((char *)dev - dev->padded);
3130                 return;
3131         }
3132 
3133         BUG_ON(dev->reg_state != NETREG_UNREGISTERED);
3134         dev->reg_state = NETREG_RELEASED;
3135 
3136         /* will free via class release */
3137         class_device_put(&dev->class_dev);
3138 #else
3139         kfree((char *)dev - dev->padded);
3140 #endif
3141 }



Version-Release number of selected component (if applicable):

Kernel Version 2.6.9-5-EL

How reproducible:

Alwyays

Steps to Reproduce:
1. Load module
2. After some time, unload via modprobe -r
  
Actual results:

The module is never unloaded due to segmentation fault and running

<lsmod | grep <module> shows it still loaded!.

 Subsequent attempt to modprobe (add) the module) results in:

[root@pc-00052 throttle]# modprobe -rf voiceHIPS
FATAL: Error removing
<module>(/lib/modules/2.6.9-5.EL/kernel/drivers/net/<module>.ko): Device or
resource busy

Expected results:

Successfull unloading of module

Additional info:
Comment 1 Jacek Materna 2006-11-20 12:10:44 EST
This is not a bug. It was reverified with the same kernel on a fresh install and
everything was alright. It could have been a configuration issue.

Note You need to log in before you can comment on or make changes to this bug.