2010-04-05 13:43:46

by Tvrtko Ursulin

[permalink] [raw]
Subject: Ooops when working with USB MIDI (2.6.33.1)


Hi all,

I had TuxGuitar running and an external USB MIDI device, which I then turned off, on, and exited TuxGuitar at which point there was this oops.

See the pasted block below,

Tvrtko

[321144.695235] usb 3-3: new full speed USB device using ohci_hcd and address 3
[321144.847033] usb 3-3: New USB device found, idVendor=0499, idProduct=1030
[321144.847036] usb 3-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[321144.847038] usb 3-3: Product: YAMAHA PSR295_3
[321144.847039] usb 3-3: Manufacturer: YAMAHA Corporation
[321182.618331] BUG: unable to handle kernel paging request at 00000007000400bc
[321182.618342] IP: [<ffffffff81375d65>] _raw_spin_lock_irq+0x15/0x30
[321182.618350] PGD 3e62067 PUD 0
[321182.618354] Oops: 0002 [#1] PREEMPT SMP
[321182.618358] last sysfs file: /sys/devices/platform/it87.656/temp1_input
[321182.618362] CPU 3
[321182.618367] Pid: 8030, comm: java Not tainted 2.6.33.1 #11 M4A785TD-M EVO/System Product Name
[321182.618371] RIP: 0010:[<ffffffff81375d65>] [<ffffffff81375d65>] _raw_spin_lock_irq+0x15/0x30
[321182.618377] RSP: 0018:ffff88005c42dda0 EFLAGS: 00010002
[321182.618381] RAX: 0000000000000100 RBX: ffff88002daa6900 RCX: 0000000000000000
[321182.618385] RDX: 0000000000000032 RSI: 0000000000001000 RDI: 00000007000400bc
[321182.618389] RBP: 0000000700040008 R08: 0000000000000000 R09: 0000000000000000
[321182.618393] R10: 0000000000000000 R11: 0000000000000202 R12: 00000007000400bc
[321182.618396] R13: ffff880010e634e0 R14: ffff88011dbf3400 R15: 0000000000000032
[321182.618401] FS: 00007fccb3b38910(0000) GS:ffff8800282c0000(0000) knlGS:00000000eed53b70
[321182.618405] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[321182.618408] CR2: 00000007000400bc CR3: 0000000045e2c000 CR4: 00000000000006e0
[321182.618412] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[321182.618416] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[321182.618420] Process java (pid: 8030, threadinfo ffff88005c42c000, task ffff880112e23400)
[321182.618424] Stack:
[321182.618426] ffffffffa01e2fca 0000000000000000 ffff880112e23400 ffffffff81052260
[321182.618430] <0> ffff88005c42ddc0 ffff88005c42ddc0 00007fcc90547515 ffffea0001bac888
[321182.618435] <0> ffff88002daa6900 ffff88000ed8e000 0000000000000000 ffff880010e634e0
[321182.618442] Call Trace:
[321182.618449] [<ffffffffa01e2fca>] ? snd_usbmidi_output_drain+0x7a/0x100 [snd_usb_lib]
[321182.618455] [<ffffffff81052260>] ? autoremove_wake_function+0x0/0x30
[321182.618462] [<ffffffffa01b7699>] ? snd_rawmidi_drain_output+0x119/0x180 [snd_rawmidi]
[321182.618469] [<ffffffffa01b8625>] ? close_substream+0x35/0x100 [snd_rawmidi]
[321182.618475] [<ffffffffa01b874b>] ? rawmidi_release_priv+0x5b/0xa0 [snd_rawmidi]
[321182.618480] [<ffffffffa01b87b6>] ? snd_rawmidi_release+0x26/0x60 [snd_rawmidi]
[321182.618486] [<ffffffff810c6681>] ? __fput+0xd1/0x1f0
[321182.618491] [<ffffffff810c2ec6>] ? filp_close+0x56/0x90
[321182.618494] [<ffffffff810c2fb4>] ? sys_close+0xb4/0x110
[321182.618499] [<ffffffff810025ab>] ? system_call_fastpath+0x16/0x1b
[321182.618503] Code: c1 17 38 f2 74 06 f3 90 8a 17 eb f6 c3 66 0f 1f 84 00 00 00 00 00 fa 65 48 8b 04 25 48 b5 00 00 ff 80 44 e0 ff ff b8 00 01
00 00 <f0> 66 0f c1 07 38 e0 74 06 f3 90 8a 07 eb f6 c3 66 66 2e 0f 1f
[321182.618527] RIP [<ffffffff81375d65>] _raw_spin_lock_irq+0x15/0x30
[321182.618532] RSP <ffff88005c42dda0>
[321182.618534] CR2: 00000007000400bc
[321182.618538] ---[ end trace d9f48627b5dd1198 ]---
[321182.618542] note: java[8030] exited with preempt_count 1


2010-04-08 10:00:25

by Clemens Ladisch

[permalink] [raw]
Subject: Re: Ooops when working with USB MIDI (2.6.33.1)

Tvrtko Ursulin wrote:
> I had TuxGuitar running and an external USB MIDI device, which I then
> turned off, on, and exited TuxGuitar at which point there was this oops.
> ...
> [321182.618342] IP: [<ffffffff81375d65>] _raw_spin_lock_irq+0x15/0x30
> [321182.618449] [<ffffffffa01e2fca>] ? snd_usbmidi_output_drain+0x7a/0x100 [snd_usb_lib]
> [321182.618462] [<ffffffffa01b7699>] ? snd_rawmidi_drain_output+0x119/0x180 [snd_rawmidi]

I think that bug was introduced by this commit:
http://git.kernel.org/linus/7a17daae8ed71bf3259d905a4fc48a5b424fa935
which causes the driver to free many internal data structures when
they might still be in use by userspace.

Please try to revert it.

I think a proper fix would be to free the URBs/buffers but not the
driver's data structures.

Takashi, do you remember what the original problem was?


Regards,
Clemens

2010-04-08 12:22:39

by Takashi Iwai

[permalink] [raw]
Subject: Re: Ooops when working with USB MIDI (2.6.33.1)

At Thu, 08 Apr 2010 12:00:11 +0200,
Clemens Ladisch wrote:
>
> Tvrtko Ursulin wrote:
> > I had TuxGuitar running and an external USB MIDI device, which I then
> > turned off, on, and exited TuxGuitar at which point there was this oops.
> > ...
> > [321182.618342] IP: [<ffffffff81375d65>] _raw_spin_lock_irq+0x15/0x30
> > [321182.618449] [<ffffffffa01e2fca>] ? snd_usbmidi_output_drain+0x7a/0x100 [snd_usb_lib]
> > [321182.618462] [<ffffffffa01b7699>] ? snd_rawmidi_drain_output+0x119/0x180 [snd_rawmidi]
>
> I think that bug was introduced by this commit:
> http://git.kernel.org/linus/7a17daae8ed71bf3259d905a4fc48a5b424fa935
> which causes the driver to free many internal data structures when
> they might still be in use by userspace.
>
> Please try to revert it.
>
> I think a proper fix would be to free the URBs/buffers but not the
> driver's data structures.
>
> Takashi, do you remember what the original problem was?

Well, I have only a vague memory -- it's a similar scenario that some app
still accessing after disconnection. The URB can't be handled after
the disconnection is finished.

I think the patch below might fix in this case. You can try it
instead of reverting the commit above.


thanks,

Takashi

---
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 2c59afd..81c8d85 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -986,6 +986,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
DEFINE_WAIT(wait);
long timeout = msecs_to_jiffies(50);

+ if (ep->umidi->disconnected)
+ return;
/*
* The substream buffer is empty, but some data might still be in the
* currently active URBs, so we have to wait for those to complete.
@@ -1275,6 +1277,11 @@ void snd_usbmidi_disconnect(struct list_head* p)
snd_usbmidi_in_endpoint_delete(ep->in);
ep->in = NULL;
}
+ ep->active_urbs = 0;
+ if (ep->drain_urbs) {
+ ep->drain_urbs = 0;
+ wake_up(&ep->drain_wait);
+ }
}
del_timer_sync(&umidi->error_timer);
}

2010-04-09 06:51:43

by Tvrtko Ursulin

[permalink] [raw]
Subject: Re: Ooops when working with USB MIDI (2.6.33.1)

On Thursday 08 Apr 2010 13:22:36 Takashi Iwai wrote:
> > Takashi, do you remember what the original problem was?
>
> Well, I have only a vague memory -- it's a similar scenario that some app
> still accessing after disconnection. The URB can't be handled after
> the disconnection is finished.
>
> I think the patch below might fix in this case. You can try it
> instead of reverting the commit above.
>
>
> thanks,
>
> Takashi
>
> ---
> diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
> index 2c59afd..81c8d85 100644
> --- a/sound/usb/usbmidi.c
> +++ b/sound/usb/usbmidi.c
> @@ -986,6 +986,8 @@ static void snd_usbmidi_output_drain(struct
> snd_rawmidi_substream *substream) DEFINE_WAIT(wait);
> long timeout = msecs_to_jiffies(50);
>
> + if (ep->umidi->disconnected)
> + return;
> /*
> * The substream buffer is empty, but some data might still be in the
> * currently active URBs, so we have to wait for those to complete.
> @@ -1275,6 +1277,11 @@ void snd_usbmidi_disconnect(struct list_head* p)
> snd_usbmidi_in_endpoint_delete(ep->in);
> ep->in = NULL;
> }
> + ep->active_urbs = 0;
> + if (ep->drain_urbs) {
> + ep->drain_urbs = 0;
> + wake_up(&ep->drain_wait);
> + }
> }
> del_timer_sync(&umidi->error_timer);
> }

For the second hunk, do you think ep->out->... and so on? That would be more
in-line with code present in 2.6.33.

Tvrtko

2010-04-09 07:19:39

by Clemens Ladisch

[permalink] [raw]
Subject: Re: Ooops when working with USB MIDI (2.6.33.1)

Tvrtko Ursulin wrote:
> On Thursday 08 Apr 2010 13:22:36 Takashi Iwai wrote:
> > > Takashi, do you remember what the original problem was?
> >
> > Well, I have only a vague memory -- it's a similar scenario that some app
> > still accessing after disconnection. The URB can't be handled after
> > the disconnection is finished.
> >
> > I think the patch below might fix in this case. You can try it
> > instead of reverting the commit above.
> >
> > --- a/sound/usb/usbmidi.c
> > +++ b/sound/usb/usbmidi.c
> > @@ -986,6 +986,8 @@ static void snd_usbmidi_output_drain(struct
> > snd_rawmidi_substream *substream) DEFINE_WAIT(wait);
> > long timeout = msecs_to_jiffies(50);
> >
> > + if (ep->umidi->disconnected)
> > + return;
> > ...
> > @@ -1275,6 +1277,11 @@ void snd_usbmidi_disconnect(struct list_head* p)
> > snd_usbmidi_in_endpoint_delete(ep->in);
> > ep->in = NULL;
> > }
> > + ep->active_urbs = 0;
> > + if (ep->drain_urbs) {
> > + ep->drain_urbs = 0;
> > + wake_up(&ep->drain_wait);
> > + }
>
> For the second hunk, do you think ep->out->... and so on? That would be more
> in-line with code present in 2.6.33.

ep->out has been just freed. And in the first hunk, in _drain, the ep
pointer is the same as ep->out in _disconnect.

In _disconnect, we must not free ep->in and ep->out because those
structures might still be accessed by all the functions called from
user space.

I'll write separate disconnect functions for the endpoint structures
when I find time.


Regards,
Clemens

2010-04-09 07:29:38

by Takashi Iwai

[permalink] [raw]
Subject: Re: Ooops when working with USB MIDI (2.6.33.1)

At Fri, 9 Apr 2010 07:51:35 +0100,
Tvrtko Ursulin wrote:
>
> On Thursday 08 Apr 2010 13:22:36 Takashi Iwai wrote:
> > > Takashi, do you remember what the original problem was?
> >
> > Well, I have only a vague memory -- it's a similar scenario that some app
> > still accessing after disconnection. The URB can't be handled after
> > the disconnection is finished.
> >
> > I think the patch below might fix in this case. You can try it
> > instead of reverting the commit above.
> >
> >
> > thanks,
> >
> > Takashi
> >
> > ---
> > diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
> > index 2c59afd..81c8d85 100644
> > --- a/sound/usb/usbmidi.c
> > +++ b/sound/usb/usbmidi.c
> > @@ -986,6 +986,8 @@ static void snd_usbmidi_output_drain(struct
> > snd_rawmidi_substream *substream) DEFINE_WAIT(wait);
> > long timeout = msecs_to_jiffies(50);
> >
> > + if (ep->umidi->disconnected)
> > + return;
> > /*
> > * The substream buffer is empty, but some data might still be in the
> > * currently active URBs, so we have to wait for those to complete.
> > @@ -1275,6 +1277,11 @@ void snd_usbmidi_disconnect(struct list_head* p)
> > snd_usbmidi_in_endpoint_delete(ep->in);
> > ep->in = NULL;
> > }
> > + ep->active_urbs = 0;
> > + if (ep->drain_urbs) {
> > + ep->drain_urbs = 0;
> > + wake_up(&ep->drain_wait);
> > + }
> > }
> > del_timer_sync(&umidi->error_timer);
> > }
>
> For the second hunk, do you think ep->out->... and so on? That would be more
> in-line with code present in 2.6.33.

Ah, crap. Sorry, that's just messing up.
The revised (compiled but untested) patch is below.


thanks,

Takashi

---
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 2c59afd..9e28b20 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -986,6 +986,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
DEFINE_WAIT(wait);
long timeout = msecs_to_jiffies(50);

+ if (ep->umidi->disconnected)
+ return;
/*
* The substream buffer is empty, but some data might still be in the
* currently active URBs, so we have to wait for those to complete.
@@ -1123,14 +1125,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
* Frees an output endpoint.
* May be called when ep hasn't been initialized completely.
*/
-static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep)
+static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep)
{
unsigned int i;

for (i = 0; i < OUTPUT_URBS; ++i)
- if (ep->urbs[i].urb)
+ if (ep->urbs[i].urb) {
free_urb_and_buffer(ep->umidi, ep->urbs[i].urb,
ep->max_transfer);
+ ep->urbs[i].urb = NULL;
+ }
+}
+
+static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep)
+{
+ snd_usbmidi_out_endpoint_clear(ep);
kfree(ep);
}

@@ -1262,15 +1271,18 @@ void snd_usbmidi_disconnect(struct list_head* p)
usb_kill_urb(ep->out->urbs[j].urb);
if (umidi->usb_protocol_ops->finish_out_endpoint)
umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
+ ep->out->active_urbs = 0;
+ if (ep->out->drain_urbs) {
+ ep->out->drain_urbs = 0;
+ wake_up(&ep->out->drain_wait);
+ }
}
if (ep->in)
for (j = 0; j < INPUT_URBS; ++j)
usb_kill_urb(ep->in->urbs[j]);
/* free endpoints here; later call can result in Oops */
- if (ep->out) {
- snd_usbmidi_out_endpoint_delete(ep->out);
- ep->out = NULL;
- }
+ if (ep->out)
+ snd_usbmidi_out_endpoint_clear(ep->out);
if (ep->in) {
snd_usbmidi_in_endpoint_delete(ep->in);
ep->in = NULL;

2010-04-09 17:38:27

by Tvrtko Ursulin

[permalink] [raw]
Subject: Re: Ooops when working with USB MIDI (2.6.33.1)

On Friday 09 Apr 2010 08:29:33 Takashi Iwai wrote:
> At Fri, 9 Apr 2010 07:51:35 +0100,
>
> Tvrtko Ursulin wrote:
> > On Thursday 08 Apr 2010 13:22:36 Takashi Iwai wrote:
> > > > Takashi, do you remember what the original problem was?
> > >
> > > Well, I have only a vague memory -- it's a similar scenario that some
> > > app still accessing after disconnection. The URB can't be handled
> > > after the disconnection is finished.
> > >
> > > I think the patch below might fix in this case. You can try it
> > > instead of reverting the commit above.

A very quick test and it looks good - did not crash in the disconnect and
then exit TuxGuitar scenario. Thank you!

Tvrtko

2010-04-11 07:04:53

by Takashi Iwai

[permalink] [raw]
Subject: Re: Ooops when working with USB MIDI (2.6.33.1)

At Fri, 9 Apr 2010 18:36:50 +0100,
Tvrtko Ursulin wrote:
>
> On Friday 09 Apr 2010 08:29:33 Takashi Iwai wrote:
> > At Fri, 9 Apr 2010 07:51:35 +0100,
> >
> > Tvrtko Ursulin wrote:
> > > On Thursday 08 Apr 2010 13:22:36 Takashi Iwai wrote:
> > > > > Takashi, do you remember what the original problem was?
> > > >
> > > > Well, I have only a vague memory -- it's a similar scenario that some
> > > > app still accessing after disconnection. The URB can't be handled
> > > > after the disconnection is finished.
> > > >
> > > > I think the patch below might fix in this case. You can try it
> > > > instead of reverting the commit above.
>
> A very quick test and it looks good - did not crash in the disconnect and
> then exit TuxGuitar scenario. Thank you!

OK, now I merged thte patch. Let me know if you see any regressions.


thanks,

Takashi