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

Reply via email to