Le 24.12.2004 22:22, Alan Stern a écrit :
Thanks to both of you for reporting the "Badness in uhci_map_status" warnings and for sending your disassembled listings. It turns out the problem is caused not by a compiler bug, but by the compiler doing generating unexpected code.
The actual error might have occurred at any of several places, but the mechanism is the same in each case. In uhci_result_control are some lines
that say:
status = uhci_status_bits(td_status(td)); if (status & TD_CTRL_ACTIVE) return -EINPROGRESS;
The corresponding disassembled code from Ivars is:
25cf: 8b 59 04 mov 0x4(%ecx),%ebx 25d2: 81 e3 00 00 f6 00 and $0xf60000,%ebx 25d8: f6 41 06 80 testb $0x80,0x6(%ecx) 25dc: 0f 85 c7 00 00 00 jne 26a9 <uhci_result_control+0x119>
Laurent's code is similar. (And by the way, both are different from the code I get because I'm using an older version of gcc.)
In case you're not familiar with x86 assembler, the first two lines compute uhci_status_bits(td_status(td)) by loading the memory address offset by 4 from the address stored in the ecx register and then masking the value with 0xf60000. The third line computes (status & TD_CTRL_ACTIVE) not by testing the value just computed, as you might expect, but by testing the original location in memory.
The problem arises because the UHCI controller can modify the value in memory between the time it is first loaded and the time of the test. So the TD_CTRL_ACTIVE bit actually is set in the value stored in "status" but it is not set in the value stored in memory. This accounts for the warning messages.
Alan, congratulations on having found the source of this problem. It was far from being obvious.
Doing the test in this unexpected way is a valid compiler optimization, but in this case we want to prevent it. Please try using the patch below. In fact, please post the disassembly listing for uhci-hcd.o after applying the patch; it's the best way to make sure the compiled code does what we want. (There's no need to include the listing for the entire module. To cut down on email traffic, you can send just the portion corresponding to the uhci_result_control routine.)
Alan Stern
Please see attached listing (kernel 2.6.10-rc3-mm1 compiled with -Os). Here is a few relevant lines (I guess) :
1f6a: 8b 46 04 mov 0x4(%esi),%eax 1f6d: 89 c1 mov %eax,%ecx 1f6f: 81 e1 00 00 f6 00 and $0xf60000,%ecx 1f75: a9 00 00 80 00 test $0x800000,%eax 1f7a: 0f 85 86 00 00 00 jne 2006 <uhci_result_control+0x116>
I must say the badness never occured again since nov. 15th (kernel 2.6.10-rc1-mm5). And now It will be difficult to trigger since I do not use an USB ADSL modem anymore (I received a new _ethernet_ ADSL modem 3 weeks ago). Maybe with my brand new USB webcam...
--- a/drivers/usb/host/uhci-hcd.c Mon Dec 20 09:45:03 2004
+++ b/drivers/usb/host/uhci-hcd.c Fri Dec 24 15:35:22 2004
@@ -236,11 +236,11 @@
{
struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
struct uhci_td *td;
- u32 *plink;
+ __le32 *plink;
/* Ordering isn't important here yet since the QH hasn't been */
/* inserted into the schedule yet */
- plink = &qh->element;
+ plink = (__le32 *) &qh->element;
list_for_each_entry(td, &urbp->td_list, list) {
*plink = cpu_to_le32(td->dma_handle) | breadth;
plink = &td->link;
--- a/drivers/usb/host/uhci-hcd.h Mon Dec 20 09:45:03 2004
+++ b/drivers/usb/host/uhci-hcd.h Fri Dec 24 15:31:16 2004
@@ -106,7 +106,7 @@
struct uhci_qh {
/* Hardware fields */
__le32 link; /* Next queue */
- __le32 element; /* Queue element pointer */
+ volatile __le32 element; /* Queue element pointer */
/* Software fields */
dma_addr_t dma_handle;
@@ -186,7 +186,7 @@
struct uhci_td {
/* Hardware fields */
__le32 link;
- __le32 status;
+ volatile __le32 status;
__le32 token;
__le32 buffer;
-- laurent
00001ef0 <uhci_result_control>: 1ef0: 55 push %ebp 1ef1: 89 e5 mov %esp,%ebp 1ef3: 57 push %edi 1ef4: 56 push %esi 1ef5: 53 push %ebx 1ef6: 83 ec 0c sub $0xc,%esp 1ef9: 89 55 ec mov %edx,0xffffffec(%ebp) 1efc: 89 45 f0 mov %eax,0xfffffff0(%ebp) 1eff: 8b 42 04 mov 0x4(%edx),%eax 1f02: ba ea ff ff ff mov $0xffffffea,%edx 1f07: 89 c7 mov %eax,%edi 1f09: 89 45 e8 mov %eax,0xffffffe8(%ebp) 1f0c: 8b 40 10 mov 0x10(%eax),%eax 1f0f: 83 c7 10 add $0x10,%edi 1f12: 39 f8 cmp %edi,%eax 1f14: 0f 84 8c 01 00 00 je 20a6 <uhci_result_control+0x1b6> 1f1a: 8b 4d e8 mov 0xffffffe8(%ebp),%ecx 1f1d: f6 41 18 08 testb $0x8,0x18(%ecx) 1f21: 74 08 je 1f2b <uhci_result_control+0x3b> 1f23: 8b 5f 04 mov 0x4(%edi),%ebx 1f26: e9 b1 00 00 00 jmp 1fdc <uhci_result_control+0xec> 1f2b: 8d 70 e4 lea 0xffffffe4(%eax),%esi 1f2e: 89 c3 mov %eax,%ebx 1f30: ba 8d ff ff ff mov $0xffffff8d,%edx 1f35: 8b 46 04 mov 0x4(%esi),%eax 1f38: 89 c1 mov %eax,%ecx 1f3a: 81 e1 00 00 f6 00 and $0xf60000,%ecx 1f40: a9 00 00 80 00 test $0x800000,%eax 1f45: 0f 85 5b 01 00 00 jne 20a6 <uhci_result_control+0x1b6> 1f4b: 85 c9 test %ecx,%ecx 1f4d: 0f 85 c4 00 00 00 jne 2017 <uhci_result_control+0x127> 1f53: 8b 45 ec mov 0xffffffec(%ebp),%eax 1f56: c7 40 38 00 00 00 00 movl $0x0,0x38(%eax) 1f5d: 8b 1b mov (%ebx),%ebx 1f5f: eb 77 jmp 1fd8 <uhci_result_control+0xe8> 1f61: 39 3b cmp %edi,(%ebx) 1f63: 74 77 je 1fdc <uhci_result_control+0xec> 1f65: 8d 73 e4 lea 0xffffffe4(%ebx),%esi 1f68: 8b 1b mov (%ebx),%ebx 1f6a: 8b 46 04 mov 0x4(%esi),%eax 1f6d: 89 c1 mov %eax,%ecx 1f6f: 81 e1 00 00 f6 00 and $0xf60000,%ecx 1f75: a9 00 00 80 00 test $0x800000,%eax 1f7a: 0f 85 86 00 00 00 jne 2006 <uhci_result_control+0x116> 1f80: 8b 46 04 mov 0x4(%esi),%eax 1f83: 8b 55 ec mov 0xffffffec(%ebp),%edx 1f86: 40 inc %eax 1f87: 25 ff 07 00 00 and $0x7ff,%eax 1f8c: 01 42 38 add %eax,0x38(%edx) 1f8f: 85 c9 test %ecx,%ecx 1f91: 0f 85 80 00 00 00 jne 2017 <uhci_result_control+0x127> 1f97: 8b 4e 08 mov 0x8(%esi),%ecx 1f9a: 8b 56 04 mov 0x4(%esi),%edx 1f9d: 89 c8 mov %ecx,%eax 1f9f: 42 inc %edx 1fa0: c1 e8 15 shr $0x15,%eax 1fa3: 81 e2 ff 07 00 00 and $0x7ff,%edx 1fa9: 40 inc %eax 1faa: 25 ff 07 00 00 and $0x7ff,%eax 1faf: 39 c2 cmp %eax,%edx 1fb1: 73 25 jae 1fd8 <uhci_result_control+0xe8> 1fb3: 8b 45 ec mov 0xffffffec(%ebp),%eax 1fb6: f6 40 28 01 testb $0x1,0x28(%eax) 1fba: 75 54 jne 2010 <uhci_result_control+0x120> 1fbc: 31 d2 xor %edx,%edx 1fbe: 80 f9 69 cmp $0x69,%cl 1fc1: 0f 85 df 00 00 00 jne 20a6 <uhci_result_control+0x1b6> 1fc7: 89 c2 mov %eax,%edx 1fc9: 8b 45 f0 mov 0xfffffff0(%ebp),%eax 1fcc: 8d 65 f4 lea 0xfffffff4(%ebp),%esp 1fcf: 5b pop %ebx 1fd0: 5e pop %esi 1fd1: 5f pop %edi 1fd2: c9 leave 1fd3: e9 f8 fe ff ff jmp 1ed0 <usb_control_retrigger_status> 1fd8: 39 fb cmp %edi,%ebx 1fda: 75 85 jne 1f61 <uhci_result_control+0x71> 1fdc: 8d 73 e4 lea 0xffffffe4(%ebx),%esi 1fdf: ba 8d ff ff ff mov $0xffffff8d,%edx 1fe4: 8b 4e 04 mov 0x4(%esi),%ecx 1fe7: 81 e1 00 00 f6 00 and $0xf60000,%ecx 1fed: 89 c8 mov %ecx,%eax 1fef: c1 e8 17 shr $0x17,%eax 1ff2: 85 c0 test %eax,%eax 1ff4: 0f 85 ac 00 00 00 jne 20a6 <uhci_result_control+0x1b6> 1ffa: 31 d2 xor %edx,%edx 1ffc: 85 c9 test %ecx,%ecx 1ffe: 0f 84 a2 00 00 00 je 20a6 <uhci_result_control+0x1b6> 2004: eb 11 jmp 2017 <uhci_result_control+0x127> 2006: ba 8d ff ff ff mov $0xffffff8d,%edx 200b: e9 96 00 00 00 jmp 20a6 <uhci_result_control+0x1b6> 2010: bf 87 ff ff ff mov $0xffffff87,%edi 2015: eb 12 jmp 2029 <uhci_result_control+0x139> 2017: 31 d2 xor %edx,%edx 2019: 80 7e 08 69 cmpb $0x69,0x8(%esi) 201d: 89 c8 mov %ecx,%eax 201f: 0f 95 c2 setne %dl 2022: e8 13 fc ff ff call 1c3a <uhci_map_status> 2027: 89 c7 mov %eax,%edi 2029: 8b 0d 00 00 00 00 mov 0x0,%ecx 202f: 83 f9 01 cmp $0x1,%ecx 2032: 0f 94 c2 sete %dl 2035: 31 c0 xor %eax,%eax 2037: 83 ff e0 cmp $0xffffffe0,%edi 203a: 0f 95 c0 setne %al 203d: 85 c2 test %eax,%edx 203f: 75 03 jne 2044 <uhci_result_control+0x154> 2041: 49 dec %ecx 2042: 7e 60 jle 20a4 <uhci_result_control+0x1b4> 2044: 8b 15 08 00 00 00 mov 0x8,%edx 204a: 85 d2 test %edx,%edx 204c: 74 56 je 20a4 <uhci_result_control+0x1b4> 204e: 8b 4d e8 mov 0xffffffe8(%ebp),%ecx 2051: 8b 41 0c mov 0xc(%ecx),%eax 2054: 6a 00 push $0x0 2056: b9 00 80 00 00 mov $0x8000,%ecx 205b: e8 c4 e5 ff ff call 624 <uhci_show_qh> 2060: 8b 15 08 00 00 00 mov 0x8,%edx 2066: 59 pop %ecx 2067: 85 d2 test %edx,%edx 2069: 74 39 je 20a4 <uhci_result_control+0x1b4> 206b: b8 0a 00 00 00 mov $0xa,%eax 2070: 89 d6 mov %edx,%esi 2072: 88 c4 mov %al,%ah 2074: ac lods %ds:(%esi),%al 2075: 38 e0 cmp %ah,%al 2077: 74 09 je 2082 <uhci_result_control+0x192> 2079: 84 c0 test %al,%al 207b: 75 f7 jne 2074 <uhci_result_control+0x184> 207d: be 01 00 00 00 mov $0x1,%esi 2082: 89 f0 mov %esi,%eax 2084: 48 dec %eax 2085: 85 c0 test %eax,%eax 2087: 89 c3 mov %eax,%ebx 2089: 74 03 je 208e <uhci_result_control+0x19e> 208b: c6 00 00 movb $0x0,(%eax) 208e: 52 push %edx 208f: 68 5f 07 00 00 push $0x75f 2094: e8 fc ff ff ff call 2095 <uhci_result_control+0x1a5> 2099: 85 db test %ebx,%ebx 209b: 58 pop %eax 209c: 5a pop %edx 209d: 89 da mov %ebx,%edx 209f: 74 03 je 20a4 <uhci_result_control+0x1b4> 20a1: 42 inc %edx 20a2: eb c5 jmp 2069 <uhci_result_control+0x179> 20a4: 89 fa mov %edi,%edx 20a6: 8d 65 f4 lea 0xfffffff4(%ebp),%esp 20a9: 89 d0 mov %edx,%eax 20ab: 5b pop %ebx 20ac: 5e pop %esi 20ad: 5f pop %edi 20ae: c9 leave 20af: c3 ret
signature.asc
Description: OpenPGP digital signature