Re: 2.6.19-rc6-rt8
From: Ingo Molnar
Date: Wed Nov 29 2006 - 02:10:42 EST
* Karsten Wiese <fzu@xxxxxxxxxxxxxxxxxxxxx> wrote:
> After estimated 15 minutes more it bugged again.
> Related dmesg translates to linux error
> -EXDEV
> propably caused by the following lines:
>
> <snip>
> static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb)
hm. Below are all the USB changes done by -rt. Maybe one of them has
some side-effect?
Ingo
Index: linux/drivers/usb/core/devio.c
===================================================================
--- linux.orig/drivers/usb/core/devio.c
+++ linux/drivers/usb/core/devio.c
@@ -309,10 +309,11 @@ static void async_completed(struct urb *
struct async *as = urb->context;
struct dev_state *ps = as->ps;
struct siginfo sinfo;
+ unsigned long flags;
- spin_lock(&ps->lock);
- list_move_tail(&as->asynclist, &ps->async_completed);
- spin_unlock(&ps->lock);
+ spin_lock_irqsave(&ps->lock, flags);
+ list_move_tail(&as->asynclist, &ps->async_completed);
+ spin_unlock_irqrestore(&ps->lock, flags);
if (as->signr) {
sinfo.si_signo = as->signr;
sinfo.si_errno = as->urb->status;
Index: linux/drivers/usb/core/hcd.c
===================================================================
--- linux.orig/drivers/usb/core/hcd.c
+++ linux/drivers/usb/core/hcd.c
@@ -517,13 +517,11 @@ error:
}
/* any errors get returned through the urb completion */
- local_irq_save (flags);
- spin_lock (&urb->lock);
+ spin_lock_irqsave(&urb->lock, flags);
if (urb->status == -EINPROGRESS)
urb->status = status;
- spin_unlock (&urb->lock);
+ spin_unlock_irqrestore(&urb->lock, flags);
usb_hcd_giveback_urb (hcd, urb);
- local_irq_restore (flags);
return 0;
}
@@ -551,8 +549,7 @@ void usb_hcd_poll_rh_status(struct usb_h
if (length > 0) {
/* try to complete the status urb */
- local_irq_save (flags);
- spin_lock(&hcd_root_hub_lock);
+ spin_lock_irqsave(&hcd_root_hub_lock, flags);
urb = hcd->status_urb;
if (urb) {
spin_lock(&urb->lock);
@@ -568,14 +565,13 @@ void usb_hcd_poll_rh_status(struct usb_h
spin_unlock(&urb->lock);
} else
length = 0;
- spin_unlock(&hcd_root_hub_lock);
+ spin_unlock_irqrestore(&hcd_root_hub_lock, flags);
/* local irqs are always blocked in completions */
if (length > 0)
usb_hcd_giveback_urb (hcd, urb);
else
hcd->poll_pending = 1;
- local_irq_restore (flags);
}
/* The USB 2.0 spec says 256 ms. This is close enough and won't
@@ -647,17 +643,15 @@ static int usb_rh_urb_dequeue (struct us
} else { /* Status URB */
if (!hcd->uses_new_polling)
del_timer (&hcd->rh_timer);
- local_irq_save (flags);
- spin_lock (&hcd_root_hub_lock);
+ spin_lock_irqsave(&hcd_root_hub_lock, flags);
if (urb == hcd->status_urb) {
hcd->status_urb = NULL;
urb->hcpriv = NULL;
} else
urb = NULL; /* wasn't fully queued */
- spin_unlock (&hcd_root_hub_lock);
+ spin_unlock_irqrestore(&hcd_root_hub_lock, flags);
if (urb)
usb_hcd_giveback_urb (hcd, urb);
- local_irq_restore (flags);
}
return 0;
@@ -1311,11 +1305,9 @@ void usb_hcd_endpoint_disable (struct us
WARN_ON (!HC_IS_RUNNING (hcd->state) && hcd->state != HC_STATE_HALT &&
udev->state != USB_STATE_NOTATTACHED);
- local_irq_disable ();
-
/* ep is already gone from udev->ep_{in,out}[]; no more submits */
rescan:
- spin_lock (&hcd_data_lock);
+ spin_lock_irq(&hcd_data_lock);
list_for_each_entry (urb, &ep->urb_list, urb_list) {
int tmp;
@@ -1323,13 +1315,13 @@ rescan:
if (urb->status != -EINPROGRESS)
continue;
usb_get_urb (urb);
- spin_unlock (&hcd_data_lock);
+ spin_unlock_irq(&hcd_data_lock);
- spin_lock (&urb->lock);
+ spin_lock_irq(&urb->lock);
tmp = urb->status;
if (tmp == -EINPROGRESS)
urb->status = -ESHUTDOWN;
- spin_unlock (&urb->lock);
+ spin_unlock_irq(&urb->lock);
/* kick hcd unless it's already returning this */
if (tmp == -EINPROGRESS) {
@@ -1352,8 +1344,7 @@ rescan:
/* list contents may have changed */
goto rescan;
}
- spin_unlock (&hcd_data_lock);
- local_irq_enable ();
+ spin_unlock_irq(&hcd_data_lock);
/* synchronize with the hardware, so old configuration state
* clears out immediately (and will be freed).
Index: linux/drivers/usb/core/message.c
===================================================================
--- linux.orig/drivers/usb/core/message.c
+++ linux/drivers/usb/core/message.c
@@ -249,8 +249,9 @@ static void sg_clean (struct usb_sg_requ
static void sg_complete (struct urb *urb)
{
struct usb_sg_request *io = urb->context;
+ unsigned long flags;
- spin_lock (&io->lock);
+ spin_lock_irqsave (&io->lock, flags);
/* In 2.5 we require hcds' endpoint queues not to progress after fault
* reports, until the completion callback (this!) returns. That lets
@@ -284,7 +285,7 @@ static void sg_complete (struct urb *urb
* unlink pending urbs so they won't rx/tx bad data.
* careful: unlink can sometimes be synchronous...
*/
- spin_unlock (&io->lock);
+ spin_unlock_irqrestore (&io->lock, flags);
for (i = 0, found = 0; i < io->entries; i++) {
if (!io->urbs [i] || !io->urbs [i]->dev)
continue;
@@ -299,7 +300,7 @@ static void sg_complete (struct urb *urb
} else if (urb == io->urbs [i])
found = 1;
}
- spin_lock (&io->lock);
+ spin_lock_irqsave (&io->lock, flags);
}
urb->dev = NULL;
@@ -309,7 +310,7 @@ static void sg_complete (struct urb *urb
if (!io->count)
complete (&io->complete);
- spin_unlock (&io->lock);
+ spin_unlock_irqrestore (&io->lock, flags);
}
@@ -571,7 +572,7 @@ void usb_sg_cancel (struct usb_sg_reques
dev_warn (&io->dev->dev, "%s, unlink --> %d\n",
__FUNCTION__, retval);
}
- spin_lock (&io->lock);
+ spin_lock_irqsave (&io->lock, flags);
}
spin_unlock_irqrestore (&io->lock, flags);
}
Index: linux/drivers/usb/net/usbnet.c
===================================================================
--- linux.orig/drivers/usb/net/usbnet.c
+++ linux/drivers/usb/net/usbnet.c
@@ -898,6 +898,8 @@ static void tx_complete (struct urb *urb
urb->dev = NULL;
entry->state = tx_done;
+ spin_lock_rt(&dev->txq.lock);
+ spin_unlock_rt(&dev->txq.lock);
defer_bh(dev, skb, &dev->txq);
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/