On Thu, 17 Jun 2004, Nicolas DET wrote:
> Sven Luther wrote:
>
> >>This requires a lot of care to do right. Remember that on PC systems
> >>interrupts can be substantially posted. A "stop_interrupt" may prevent
> >>IRQ issue but if an IRQ is already on the PC APIC bus it will kill you
> >>later on because the IRQ delivery and PCI bus access on the PC class
> >>machines are totally asynchronous
> >
>
> I think this part could be interresting to apply if the Kernel team is
> sure that it won't hurt other platform.
No, I don't want to use it. It's too complicated for the relatively small
advantage it offers.
> I don't think the problem is alignement nor cache cohenry.
> In fact, I'm pretty sure that cache cohenrency on this platform is reliable.
> It's a really weird.
>
> If I modify the structure to :
>
> struct uhci_qh {
> /* Hardware fields */
> u32 link; /* Next queue */
> u32 element; /* Queue element pointer */
>
> /* Software fields */
> dma_addr_t dma_handle;
>
> struct usb_device *dev;
> struct urb_priv *urbp;
>
> struct list_head remove_list; /* P: uhci->remove_list_lock */
> struct list_head list; /* P: uhci->frame_list_lock */
> } __attribute__((aligned(16)));
>
> Then it works (tested 2 hours where as the original one hangs within the
> minute with 2 USB keys). I just changed the position on the remove_list
> field!
>
> The hangs is in fact an endless loop inside free_pendings_qhs, because
> one of the node of the list point to itself ( node->next = node).
>
> I add dummy fields and move them a bit everywhere in the structure.
> Theses fields are set on alloc_qh, modify on remove_qh. Then in
> free_pending_qhs I check if the value set in remove_qh is "still there".
> And it is all the time.
> I try to put the dummies field at the place of the remove_list too: No
> problem.
>
> I have no idea why it works but it does...
This all sounds very strange. Here's an idea. Add
unsigned char unused[32];
struct list_head remove_list_copy;
to the end of the uhci_qh structure. The remove_list_copy field will lie
on a different cache line from the rest of the structure. Whenever the
code uses or changes the value of remove_list, check first to see that
remove_list_copy is equal to remove_list and then copy the new value of
remove_list into it. Also, in free_pending_qhs() check whether
remove_list.next points to itself.
Depending on what you see, we may be able to determine whether the problem
lies in the hardware or in the software.
Alan Stern
-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel