Just a ping in case this was forgotton in the flood[1]: if I open a ub
device, remove the drive, and then continue accessing the device, the
next request oopses.
I'm still seeing this oops with 2.6.11-rc4-bk8 (updated oops attached).
I've been using the attached patch, but judging by the comments after
the removed code, it may not be correct.
(From the warnings, I wonder if Debian's ksymoops is too old; anyway, I
think this is easily reproducable.)
[1]
https://lists.one-eyed-alien.net/pipermail/usb-storage/2004-December/001237.html
--
Glenn Maynard
ksymoops 2.4.9 on i686 2.6.11-rc4-bk8. Options used
-V (default)
-k /proc/ksyms (default)
-l /proc/modules (default)
-o /lib/modules/2.6.11-rc4-bk8/ (default)
-m /boot/System.map-2.6.11-rc4-bk8 (specified)
Error (regular_file): read_ksyms stat /proc/ksyms failed
No modules in ksyms, skipping objects
No ksyms, skipping lsmod
<1>Unable to handle kernel paging request at virtual address 7665644b
<4>c027a5ee
<1>*pde = 00000000
<1>Oops: 0000 [#1]
<4>CPU: 0
<4>EIP: 0060:[<c027a5ee>] Tainted: P VLI
Using defaults from ksymoops -t elf32-i386 -a i386
<4>EFLAGS: 00010086 (2.6.11-rc4-bk8)
<4>eax: 7665642f ebx: 00000000 ecx: 00000001 edx: c15b3030
<4>esi: c15b3030 edi: 00000000 ebp: ded27bdc esp: ded27bd8
<4>ds: 007b es: 007b ss: 0068
<4>Stack: 00000050 ded27c14 c027d993 c15b3030 ded27c20 ded1cfbc dffe7d80
000001dd
<4> 00000000 00000001 00000001 ded27c3c c15b3030 df95d100 ded27c40
ded27c98
<4> c027e1f2 c15b3030 dffd0900 c013a46e 00000050 00000000 df3c50a0
c0128390
<4>Call Trace:
<4> [<c0102bff>] show_stack+0x7f/0xa0
<4> [<c0102da6>] show_registers+0x156/0x1c0
<4> [<c0102fba>] die+0xea/0x190
<4> [<c010de86>] do_page_fault+0x326/0x6a2
<4> [<c0102857>] error_code+0x2b/0x30
<4> [<c027d993>] __make_request+0x83/0x4c0
<4> [<c027e1f2>] generic_make_request+0x152/0x210
<4> [<c027e310>] submit_bio+0x60/0x100
<4> [<c01557d5>] submit_bh+0xe5/0x140
<4> [<c015378a>] __bread_slow+0x4a/0x80
<4> [<c0153aa8>] __bread+0x38/0x40
<4> [<c0197770>] fat__get_entry+0xa0/0x17e
<4> [<c019460e>] fat_get_short_entry+0x9e/0xb0
<4> [<c01947c7>] fat_scan+0x57/0xa0
<4> [<c0197d01>] msdos_find+0x71/0xc0
<4> [<c0197eca>] msdos_lookup+0x5a/0xe0
<4> [<c015ef0c>] real_lookup+0xbc/0xe0
<4> [<c015f1b6>] do_lookup+0x86/0xa0
<4> [<c015f8f8>] link_path_walk+0x728/0xe10
<4> [<c016029a>] path_lookup+0x9a/0x1c0
<4> [<c0160a06>] open_namei+0x86/0x690
<4> [<c014fe7c>] filp_open+0x3c/0x60
<4> [<c0150306>] sys_open+0x46/0xa0
<4> [<c01026af>] syscall_call+0x7/0xb
<4>Code: 00 00 00 00 eb d9 8d b4 26 00 00 00 00 ff 82 54 01 00 00 eb c5 90 8d
b4 26 00 00 00 00 55 89 e5 83 ec 04 8b 55 08 8b 42 0c 8b 00 <8b> 48 1c 85 c9 75
0b 31 c0 39 12 0f 94 c0 89 ec 5d c3 89 14 24
>>EIP; c027a5ee <elv_queue_empty+e/30> <=====
>>edx; c15b3030 <pg0+10cb030/3fb16400>
>>esi; c15b3030 <pg0+10cb030/3fb16400>
>>ebp; ded27bdc <pg0+1e83fbdc/3fb16400>
>>esp; ded27bd8 <pg0+1e83fbd8/3fb16400>
Trace; c0102bff <show_stack+7f/a0>
Trace; c0102da6 <show_registers+156/1c0>
Trace; c0102fba <die+ea/190>
Trace; c010de86 <do_page_fault+326/6a2>
Trace; c0102857 <error_code+2b/30>
Trace; c027d993 <__make_request+83/4c0>
Trace; c027e1f2 <generic_make_request+152/210>
Trace; c027e310 <submit_bio+60/100>
Trace; c01557d5 <submit_bh+e5/140>
Trace; c015378a <__bread_slow+4a/80>
Trace; c0153aa8 <__bread+38/40>
Trace; c0197770 <fat__get_entry+a0/17e>
Trace; c019460e <fat_get_short_entry+9e/b0>
Trace; c01947c7 <fat_scan+57/a0>
Trace; c0197d01 <msdos_find+71/c0>
Trace; c0197eca <msdos_lookup+5a/e0>
Trace; c015ef0c <real_lookup+bc/e0>
Trace; c015f1b6 <do_lookup+86/a0>
Trace; c015f8f8 <link_path_walk+728/e10>
Trace; c016029a <path_lookup+9a/1c0>
Trace; c0160a06 <open_namei+86/690>
Trace; c014fe7c <filp_open+3c/60>
Trace; c0150306 <sys_open+46/a0>
Trace; c01026af <syscall_call+7/b>
This architecture has variable length instructions, decoding before eip
is unreliable, take these instructions with a pinch of salt.
Code; c027a5c3 <elv_remove_request+43/60>
00000000 <_EIP>:
Code; c027a5c3 <elv_remove_request+43/60>
0: 00 00 add %al,(%eax)
Code; c027a5c5 <elv_remove_request+45/60>
2: 00 00 add %al,(%eax)
Code; c027a5c7 <elv_remove_request+47/60>
4: eb d9 jmp ffffffdf <_EIP+0xffffffdf>
Code; c027a5c9 <elv_remove_request+49/60>
6: 8d b4 26 00 00 00 00 lea 0x0(%esi,1),%esi
Code; c027a5d0 <elv_remove_request+50/60>
d: ff 82 54 01 00 00 incl 0x154(%edx)
Code; c027a5d6 <elv_remove_request+56/60>
13: eb c5 jmp ffffffda <_EIP+0xffffffda>
Code; c027a5d8 <elv_remove_request+58/60>
15: 90 nop
Code; c027a5d9 <elv_remove_request+59/60>
16: 8d b4 26 00 00 00 00 lea 0x0(%esi,1),%esi
Code; c027a5e0 <elv_queue_empty+0/30>
1d: 55 push %ebp
Code; c027a5e1 <elv_queue_empty+1/30>
1e: 89 e5 mov %esp,%ebp
Code; c027a5e3 <elv_queue_empty+3/30>
20: 83 ec 04 sub $0x4,%esp
Code; c027a5e6 <elv_queue_empty+6/30>
23: 8b 55 08 mov 0x8(%ebp),%edx
Code; c027a5e9 <elv_queue_empty+9/30>
26: 8b 42 0c mov 0xc(%edx),%eax
Code; c027a5ec <elv_queue_empty+c/30>
29: 8b 00 mov (%eax),%eax
This decode from eip onwards should be reliable
Code; c027a5ee <elv_queue_empty+e/30>
00000000 <_EIP>:
Code; c027a5ee <elv_queue_empty+e/30> <=====
0: 8b 48 1c mov 0x1c(%eax),%ecx <=====
Code; c027a5f1 <elv_queue_empty+11/30>
3: 85 c9 test %ecx,%ecx
Code; c027a5f3 <elv_queue_empty+13/30>
5: 75 0b jne 12 <_EIP+0x12>
Code; c027a5f5 <elv_queue_empty+15/30>
7: 31 c0 xor %eax,%eax
Code; c027a5f7 <elv_queue_empty+17/30>
9: 39 12 cmp %edx,(%edx)
Code; c027a5f9 <elv_queue_empty+19/30>
b: 0f 94 c0 sete %al
Code; c027a5fc <elv_queue_empty+1c/30>
e: 89 ec mov %ebp,%esp
Code; c027a5fe <elv_queue_empty+1e/30>
10: 5d pop %ebp
Code; c027a5ff <elv_queue_empty+1f/30>
11: c3 ret
Code; c027a600 <elv_queue_empty+20/30>
12: 89 14 24 mov %edx,(%esp,1)
1 error issued. Results may not be reliable.
--- ub.c.orig 2005-02-20 23:52:36.000000000 -0500
+++ ub.c 2005-02-21 00:11:31.000000000 -0500
@@ -505,6 +505,10 @@
* The sd.c is blatantly racy in this area.
*/
/* disk->private_data = NULL; */
+ request_queue_t *q = sc->disk->queue;
+ if (q)
+ blk_cleanup_queue(q);
+
put_disk(sc->disk);
sc->disk = NULL;
@@ -2056,7 +2060,6 @@
{
struct ub_dev *sc = usb_get_intfdata(intf);
struct gendisk *disk = sc->disk;
- request_queue_t *q = disk->queue;
unsigned long flags;
/*
@@ -2099,8 +2102,6 @@
*/
if (disk->flags & GENHD_FL_UP)
del_gendisk(disk);
- if (q)
- blk_cleanup_queue(q);
/*
* We really expect blk_cleanup_queue() to wait, so no amount