On Sun, 2009-07-19 at 22:33 +0200, Martin Dauskardt wrote:
> I can reproduce a kernel crash when I do the following:
>
> modprobe ivtvfb
>
> r...@ubuntuvdr:~# cat /proc/fb
> 0 cx23415 TV out
>
> Then I start vdr and its pvr350 plugin. It opens /dev/fb0
>
> After stopping vdr, I unload ivtvfb:
>
> r...@ubuntuvdr:~# rmmod ivtvfb
>
> It still shows the fb:
> r...@ubuntuvdr:~# cat /proc/fb
> 0 cx23415 TV out
>
> ivtvfb is really unloaded:
> r...@ubuntuvdr:~# rmmod ivtvfb
> ERROR: Module ivtvfb does not exist in /proc/modules
> r...@ubuntuvdr:~# cat /proc/fb
> 0 cx23415 TV out
>
> After loading ivtvfb again *) , a second fb appears:
>
> r...@ubuntuvdr:~# modprobe ivtvfb
> r...@ubuntuvdr:~# cat /proc/fb
> 0 cx23415 TV out
> 1 cx23415 TV out
>
> When I start vdr again, the kernel crashes when the pvr350 plugin trys to
> open
> the fb device.
Obviously ivtvfb or the kernel's fb system isn't cleaning up
properly....
> *) Sometimes it is not possible to load ivtvfb at this point:
> r...@ubuntuvdr:~# modprobe ivtvfb
> FATAL: Error inserting ivtvfb
> (/lib/modules/2.6.29/kernel/drivers/media/video/ivtv/ivtvfb.ko): No such
> device
>
> The I need to unload ivtv. After this, I can reload ivtvfb. (Very strange,
> should be vice versa)
>
> I often had problems when the PVR350 is the only fb device. I already put
> this
> in my menu.lst:
> fbcon=map:2
> This should prevent the console from using the PVR350. (?)
>
>
> Jul 19 21:59:26 ubuntuvdr vdr: [3628] initializing plugin: pvr350
> (2009-06-29): Ein Ausgabegerät für die PVR350
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.401538] BUG: unable to handle kernel
> paging request at d0c94320
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.401706] IP: [<c0360534>]
> fb_open+0x44/0x120
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.401816] *pde = 0f81f067 *pte =
> 00000000
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.401834] Oops: 0000 [#1] PREEMPT SMP
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.401984] last sysfs
> file: /sys/devices/pci0000:00/0000:00:1e.0/modalias
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] Modules linked in: budget_ci
> budget_core dvb_core saa7146 ttpci_eeprom ir_common lirc_serial lirc_dev
> video output lp parport tda827x tda10023 tuner_simple tuner_types tda9887
> ipv6 tda8290 snd_intel8x0 snd_ac97_codec ac97_bus tuner snd_pcm_oss
> snd_mixer_oss msp3400 snd_pcm saa7127 snd_seq_oss snd_seq_midi saa7115
> snd_rawmidi snd_seq_midi_event stv0297 snd_seq ivtv usbhid i2c_algo_bit
> cx2341x 8139too snd_timer v4l2_common snd_seq_device videodev v4l1_compat
> 8139cp 8250_pnp tveeprom ehci_hcd ohci_hcd mii 8250 serial_core snd soundcore
> pcspkr snd_page_alloc uhci_hcd evdev [last unloaded: ir_common]
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027]
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] Pid: 3628, comm: vdr Not
> tainted (2.6.29 #3)
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] EIP: 0060:[<c0360534>]
> EFLAGS: 00010246 CPU: 0
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] EIP is at fb_open+0x44/0x120
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] EAX: d0c94320 EBX: 00000000
> ECX: c03604f0 EDX: cc821100
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] ESI: cfb9dc34 EDI: cd283de0
> EBP: cd185e70 ESP: cd185e54
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] DS: 007b ES: 007b FS: 00d8
> GS: 0033 SS: 0068
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] Process vdr (pid: 3628,
> ti=cd184000 task=cca06700 task.ti=cd184000)
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] Stack:
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] cf8094c0 cd185e70 cfb9dc3c
> cc821100 cf8094c0 00000000 cd283de0 cd185e8c
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] c0184fe0 cc821100 cd185e8c
> cc821100 00000000 cd283de0 cd185ea8 c0180a4b
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] cfb6d680 cf6ba088 cc821100
> cd185f04 00000000 cd185ec4 c0181c92 cc821100
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] Call Trace:
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] [<c0184fe0>] ?
> chrdev_open+0xc0/0x190
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] [<c0180a4b>] ?
> __dentry_open+0xeb/0x270
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] [<c0181c92>] ?
> nameidata_to_filp+0x52/0x60
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] [<c0184f20>] ?
> chrdev_open+0x0/0x190
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] [<c018d1d5>] ?
> do_filp_open+0x175/0x720
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] [<c018e558>] ?
> vfs_ioctl+0x28/0x80
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] [<c018e96d>] ?
> do_vfs_ioctl+0x2cd/0x4e0
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] [<c0180819>] ?
> do_sys_open+0x49/0xe0
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] [<c0180919>] ?
> sys_open+0x29/0x40
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] [<c01033f2>] ?
> syscall_call+0x7/0xb
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] Code: 0f 00 83 fb 1f 0f 8f
> cc
> 00 00 00 8b 34 9d e0 ff 69 c0 85 f6 0f 84 98 00 00 00 8d 46 08 89 45 ec e8 d2
> 6e 1a 00 8b 86 a8 02 00 00 <8b> 10 85 d2 74 46 89 e0 25 00 e0 ff ff 83 40 14
> 01 64 8b 0d 04
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] EIP: [<c0360534>]
> fb_open+0x44/0x120 SS:ESP 0068:cd185e54
> Jul 19 21:59:26 ubuntuvdr kernel: [ 101.402027] ---[ end trace
> d5eb5ba229eafda6 ]---
This crash happens in linux/drivers/video/fbmem.c:fb_open():
static int
fb_open(struct inode *inode, struct file *file)
__acquires(&info->lock)
__releases(&info->lock)
{
int fbidx = iminor(inode);
struct fb_info *info;
int res = 0;
if (fbidx >= FB_MAX)
return -ENODEV;
info = registered_fb[fbidx];
if (!info)
request_module("fb%d", fbidx);
info = registered_fb[fbidx];
if (!info)
return -ENODEV;
mutex_lock(&info->lock);
if (!try_module_get(info->fbops->owner)) { <-------- Ooops
res = -ENODEV;
goto out;
}
[...]
The code dump disassembles to:
1b: 83 fb 1f cmp $0x1f,%ebx ; if (fbidx >= FB_MAX)
1e: 0f 8f cc 00 00 00 jg 0xf0 ; return -ENODEV
24: 8b 34 9d e0 ff 69 c0 mov -0x3f960020(,%ebx,4),%esi; info =
registered_fb[fbidx];
2b: 85 f6 test %esi,%esi; if (!info)
2d: 0f 84 98 00 00 00 je 0xcb ; jump somewhere to call
request_module()
33: 8d 46 08 lea 0x8(%esi),%eax; %eax = &info->lock;
36: 89 45 ec mov %eax,-0x14(%ebp)
39: e8 d2 6e 1a 00 call 0x1a6f10 ; mutex_lock(&info->lock);
3e: 8b 86 a8 02 00 00 mov 0x2a8(%esi),%eax; %eax = info->fbops
44: 8b 10 mov (%eax),%edx; %edx = fbops->owner
<------ Oops
46: 85 d2 test %edx,%edx
48: 74 46 je 0x90
4a: 89 e0 mov %esp,%eax
4c: 25 00 e0 ff ff and $0xffffe000,%eax
51: 83 40 14 01 addl $0x1,0x14(%eax)
The oops happens because fbops->owner points to a module that obviously
has been unloaded and it's vmalloc() allocation destroyed.
The registered_fb[] array must have stale data in it.
I don't have 2.6.29 kernel source in front of me (the snippet above I
pulled from an LXR website) and the fb kernel code has obviously changed
since my 2.6.27 kernel source I have on hand.
What i do find surprising in my 2.6.27 source code is that
linux/drivers/video/fbmem.c:unregister_framebuffer() can actually
*fail*, leaving the stale information in the registered_fb[] array when
a module like ivtvfb unloads.
This is a fb infrastructure problem in my opinion. Maybe ivtvfb is
doing something wrong which causes unregister_framebuffer() to fail, but
unregister_framebuffer() shouldn't be leaving its internal data
structures in an inconsistent state upon failure. Module unloading
simply shouldn't fail or cause kernel corruption, IMO. I assume ivtvfb
emitted "Framebuffer 0 is in use, cannot unload" in one of your logs.
Regards,
Andy
_______________________________________________
ivtv-devel mailing list
[email protected]
http://ivtvdriver.org/mailman/listinfo/ivtv-devel