* USB Audio initialization race
@ 2013-09-13 19:56 David Henningsson
2013-09-13 20:39 ` Alan Stern
0 siblings, 1 reply; 11+ messages in thread
From: David Henningsson @ 2013-09-13 19:56 UTC (permalink / raw)
To: alsa-devel; +Cc: clemens, stern, zonque
I'm sometimes seeing that USB audio devices are not initialized
correctly by PulseAudio, but I can't reproduce this myself.
I have, however, spotted what I think is a race condition in the driver
code, if a device has more than one interface. snd_card_register is
called once for every interface, which means that it will be shown to
userspace after the first interface has been probed. So the race could
look like:
1) The first interface is probed, which might contain the mixer controls
2) snd_card_register is called, which sends a signal to userspace
3) PulseAudio probes the device and notices that it has no PCMs, so it
ignores the device
4) The second interface is probed, which adds the PCMs
5) snd_card_register is again called, which is a no-op since the card
already exist
6) User is unhappy because his plugged in sound card did not show up in
PulseAudio.
So, assuming all this is right, it seems like we need some type of
callback from the usb driver when all the interfaces for the sound card
has been probed, so we can call snd_card_register at that point instead.
Thoughts?
--
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: USB Audio initialization race
2013-09-13 19:56 USB Audio initialization race David Henningsson
@ 2013-09-13 20:39 ` Alan Stern
2013-09-13 20:53 ` David Henningsson
2013-09-13 20:55 ` Clemens Ladisch
0 siblings, 2 replies; 11+ messages in thread
From: Alan Stern @ 2013-09-13 20:39 UTC (permalink / raw)
To: David Henningsson; +Cc: alsa-devel, clemens, zonque
On Fri, 13 Sep 2013, David Henningsson wrote:
> I'm sometimes seeing that USB audio devices are not initialized
> correctly by PulseAudio, but I can't reproduce this myself.
>
> I have, however, spotted what I think is a race condition in the driver
> code, if a device has more than one interface. snd_card_register is
> called once for every interface, which means that it will be shown to
> userspace after the first interface has been probed. So the race could
> look like:
>
> 1) The first interface is probed, which might contain the mixer controls
> 2) snd_card_register is called, which sends a signal to userspace
> 3) PulseAudio probes the device and notices that it has no PCMs, so it
> ignores the device
> 4) The second interface is probed, which adds the PCMs
> 5) snd_card_register is again called, which is a no-op since the card
> already exist
> 6) User is unhappy because his plugged in sound card did not show up in
> PulseAudio.
>
> So, assuming all this is right, it seems like we need some type of
> callback from the usb driver when all the interfaces for the sound card
> has been probed, so we can call snd_card_register at that point instead.
> Thoughts?
The driver probably doesn't know when all the interfaces have been
probed. Maybe it would be better to send a signal to userspace each
time snd_card_register is called, even if nothing is done.
Alternatively, when the first interface is probed, the driver could
claim all the other interfaces belonging to the same association.
Alan Stern
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: USB Audio initialization race
2013-09-13 20:39 ` Alan Stern
@ 2013-09-13 20:53 ` David Henningsson
2013-09-13 21:06 ` Alan Stern
2013-09-13 20:55 ` Clemens Ladisch
1 sibling, 1 reply; 11+ messages in thread
From: David Henningsson @ 2013-09-13 20:53 UTC (permalink / raw)
To: Alan Stern; +Cc: alsa-devel, clemens, zonque
2013-09-13 16:39, Alan Stern skrev:
> On Fri, 13 Sep 2013, David Henningsson wrote:
>
>> I'm sometimes seeing that USB audio devices are not initialized
>> correctly by PulseAudio, but I can't reproduce this myself.
>>
>> I have, however, spotted what I think is a race condition in the driver
>> code, if a device has more than one interface. snd_card_register is
>> called once for every interface, which means that it will be shown to
>> userspace after the first interface has been probed. So the race could
>> look like:
>>
>> 1) The first interface is probed, which might contain the mixer controls
>> 2) snd_card_register is called, which sends a signal to userspace
>> 3) PulseAudio probes the device and notices that it has no PCMs, so it
>> ignores the device
>> 4) The second interface is probed, which adds the PCMs
>> 5) snd_card_register is again called, which is a no-op since the card
>> already exist
>> 6) User is unhappy because his plugged in sound card did not show up in
>> PulseAudio.
>>
>> So, assuming all this is right, it seems like we need some type of
>> callback from the usb driver when all the interfaces for the sound card
>> has been probed, so we can call snd_card_register at that point instead.
>> Thoughts?
> The driver probably doesn't know when all the interfaces have been
> probed.
I'm unsure if you mean "the usb driver" or "the usb audio driver" in the
sentence above, but the USB driver would enumerate all interfaces and
call the usb audio driver for every interface, and so the USB driver
would know when all the interfaces have been probed, right?
Is there a way the USB audio driver can subscribe, or get an additional
callback of some sort, when that happens?
> Maybe it would be better to send a signal to userspace each
> time snd_card_register is called, even if nothing is done.
That sounds very suboptimal, given that PulseAudio's probing mechanism
can be quite heavy (depending on the device).
>
> Alternatively, when the first interface is probed, the driver could
> claim all the other interfaces belonging to the same association.
Not sure how well that would work out with "composite" devices, e g
headset with volume up/down buttons?
--
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: USB Audio initialization race
2013-09-13 20:39 ` Alan Stern
2013-09-13 20:53 ` David Henningsson
@ 2013-09-13 20:55 ` Clemens Ladisch
1 sibling, 0 replies; 11+ messages in thread
From: Clemens Ladisch @ 2013-09-13 20:55 UTC (permalink / raw)
To: Alan Stern; +Cc: alsa-devel, David Henningsson, zonque
Alan Stern wrote:
>> 1) The first interface is probed, which might contain the mixer controls
>> 2) snd_card_register is called, which sends a signal to userspace
>> 3) PulseAudio probes the device and notices that it has no PCMs, so it
>> ignores the device
>> 4) The second interface is probed, which adds the PCMs
>> 5) snd_card_register is again called, which is a no-op since the card
>> already exist
>> 6) User is unhappy because his plugged in sound card did not show up in
>> PulseAudio.
>>
>> So, assuming all this is right, it seems like we need some type of
>> callback from the usb driver when all the interfaces for the sound card
>> has been probed, so we can call snd_card_register at that point instead.
>> Thoughts?
>
> The driver probably doesn't know when all the interfaces have been
> probed. Maybe it would be better to send a signal to userspace each
> time snd_card_register is called, even if nothing is done.
New devices will result in a signal because they result in new device
nodes.
> Alternatively, when the first interface is probed, the driver could
> claim all the other interfaces belonging to the same association.
The driver already does this.
Regards,
Clemens
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: USB Audio initialization race
2013-09-13 20:53 ` David Henningsson
@ 2013-09-13 21:06 ` Alan Stern
2013-09-13 23:47 ` David Henningsson
0 siblings, 1 reply; 11+ messages in thread
From: Alan Stern @ 2013-09-13 21:06 UTC (permalink / raw)
To: David Henningsson; +Cc: alsa-devel, clemens, zonque
On Fri, 13 Sep 2013, David Henningsson wrote:
> 2013-09-13 16:39, Alan Stern skrev:
> > On Fri, 13 Sep 2013, David Henningsson wrote:
> >
> >> I'm sometimes seeing that USB audio devices are not initialized
> >> correctly by PulseAudio, but I can't reproduce this myself.
> >>
> >> I have, however, spotted what I think is a race condition in the driver
> >> code, if a device has more than one interface. snd_card_register is
> >> called once for every interface, which means that it will be shown to
> >> userspace after the first interface has been probed. So the race could
> >> look like:
> >>
> >> 1) The first interface is probed, which might contain the mixer controls
> >> 2) snd_card_register is called, which sends a signal to userspace
> >> 3) PulseAudio probes the device and notices that it has no PCMs, so it
> >> ignores the device
> >> 4) The second interface is probed, which adds the PCMs
> >> 5) snd_card_register is again called, which is a no-op since the card
> >> already exist
> >> 6) User is unhappy because his plugged in sound card did not show up in
> >> PulseAudio.
> >>
> >> So, assuming all this is right, it seems like we need some type of
> >> callback from the usb driver when all the interfaces for the sound card
> >> has been probed, so we can call snd_card_register at that point instead.
> >> Thoughts?
> > The driver probably doesn't know when all the interfaces have been
> > probed.
> I'm unsure if you mean "the usb driver" or "the usb audio driver" in the
> sentence above, but the USB driver would enumerate all interfaces and
> call the usb audio driver for every interface, and so the USB driver
> would know when all the interfaces have been probed, right?
I'm not sure what you mean by "the USB driver". The USB core registers
all the interfaces, which causes them to be probed. The USB core does
know when all the interfaces have been registered.
> Is there a way the USB audio driver can subscribe, or get an additional
> callback of some sort, when that happens?
No, not currently.
> > Maybe it would be better to send a signal to userspace each
> > time snd_card_register is called, even if nothing is done.
>
> That sounds very suboptimal, given that PulseAudio's probing mechanism
> can be quite heavy (depending on the device).
> >
> > Alternatively, when the first interface is probed, the driver could
> > claim all the other interfaces belonging to the same association.
> Not sure how well that would work out with "composite" devices, e g
> headset with volume up/down buttons?
Presumably the HID interface (with the button controls) would not be in
the audio interface association. Anyway, the audio driver wouldn't
claim anything that wasn't an audio interface.
Alan Stern
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: USB Audio initialization race
2013-09-13 21:06 ` Alan Stern
@ 2013-09-13 23:47 ` David Henningsson
2013-09-14 13:44 ` Alan Stern
0 siblings, 1 reply; 11+ messages in thread
From: David Henningsson @ 2013-09-13 23:47 UTC (permalink / raw)
To: Alan Stern; +Cc: alsa-devel, clemens, zonque
2013-09-13 17:06, Alan Stern skrev:
> On Fri, 13 Sep 2013, David Henningsson wrote:
>
>> 2013-09-13 16:39, Alan Stern skrev:
>>> On Fri, 13 Sep 2013, David Henningsson wrote:
>>>
>>>> I'm sometimes seeing that USB audio devices are not initialized
>>>> correctly by PulseAudio, but I can't reproduce this myself.
>>>>
>>>> I have, however, spotted what I think is a race condition in the driver
>>>> code, if a device has more than one interface. snd_card_register is
>>>> called once for every interface, which means that it will be shown to
>>>> userspace after the first interface has been probed. So the race could
>>>> look like:
>>>>
>>>> 1) The first interface is probed, which might contain the mixer controls
>>>> 2) snd_card_register is called, which sends a signal to userspace
>>>> 3) PulseAudio probes the device and notices that it has no PCMs, so it
>>>> ignores the device
>>>> 4) The second interface is probed, which adds the PCMs
>>>> 5) snd_card_register is again called, which is a no-op since the card
>>>> already exist
>>>> 6) User is unhappy because his plugged in sound card did not show up in
>>>> PulseAudio.
>>>>
>>>> So, assuming all this is right, it seems like we need some type of
>>>> callback from the usb driver when all the interfaces for the sound card
>>>> has been probed, so we can call snd_card_register at that point instead.
>>>> Thoughts?
>>> The driver probably doesn't know when all the interfaces have been
>>> probed.
>> I'm unsure if you mean "the usb driver" or "the usb audio driver" in the
>> sentence above, but the USB driver would enumerate all interfaces and
>> call the usb audio driver for every interface, and so the USB driver
>> would know when all the interfaces have been probed, right?
> I'm not sure what you mean by "the USB driver". The USB core registers
> all the interfaces, which causes them to be probed. The USB core does
> know when all the interfaces have been registered.
Ok.
>> Is there a way the USB audio driver can subscribe, or get an additional
>> callback of some sort, when that happens?
> No, not currently.
Given the use case we have here, do you think that would be a reasonable
solution to the problem?
>
>>> Maybe it would be better to send a signal to userspace each
>>> time snd_card_register is called, even if nothing is done.
>> That sounds very suboptimal, given that PulseAudio's probing mechanism
>> can be quite heavy (depending on the device).
As Clemens said, there are device nodes being added, but having a look
at how this is handled in udev's 78-sound-card.rules [1], the rule has a
big comment section in the beginning. This comment claims that |"||The
control device node creation can be used as synchronization point". I
understand this will happen on the first call to snd_card_register, and
only then.|
>>> Alternatively, when the first interface is probed, the driver could
>>> claim all the other interfaces belonging to the same association.
>> Not sure how well that would work out with "composite" devices, e g
>> headset with volume up/down buttons?
> Presumably the HID interface (with the button controls) would not be in
> the audio interface association. Anyway, the audio driver wouldn't
> claim anything that wasn't an audio interface.
Ok, I'll trust you to know this better than me. :-)
I'm not sure exactly what "claim all the other interfaces belonging to
the same association" means, but if it means it can enumerate all those
interfaces it has claimed but not yet probed, maybe the USB audio driver
can use this information to avoid calling snd_card_register until after
probing the last interface?
--
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic
[1] http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/rules/78-sound-card.rules?id=19c5f19d69bb5f520fa7213239490c55de06d99d
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: USB Audio initialization race
2013-09-13 23:47 ` David Henningsson
@ 2013-09-14 13:44 ` Alan Stern
2013-09-14 19:33 ` Clemens Ladisch
0 siblings, 1 reply; 11+ messages in thread
From: Alan Stern @ 2013-09-14 13:44 UTC (permalink / raw)
To: David Henningsson; +Cc: alsa-devel, clemens, zonque
On Fri, 13 Sep 2013, David Henningsson wrote:
> 2013-09-13 17:06, Alan Stern skrev:
> > On Fri, 13 Sep 2013, David Henningsson wrote:
> >
> >> 2013-09-13 16:39, Alan Stern skrev:
> >>> On Fri, 13 Sep 2013, David Henningsson wrote:
> >>>
> >>>> I'm sometimes seeing that USB audio devices are not initialized
> >>>> correctly by PulseAudio, but I can't reproduce this myself.
> >>>>
> >>>> I have, however, spotted what I think is a race condition in the driver
> >>>> code, if a device has more than one interface. snd_card_register is
> >>>> called once for every interface, which means that it will be shown to
> >>>> userspace after the first interface has been probed. So the race could
> >>>> look like:
> >>>>
> >>>> 1) The first interface is probed, which might contain the mixer controls
> >>>> 2) snd_card_register is called, which sends a signal to userspace
> >>>> 3) PulseAudio probes the device and notices that it has no PCMs, so it
> >>>> ignores the device
> >>>> 4) The second interface is probed, which adds the PCMs
> >>>> 5) snd_card_register is again called, which is a no-op since the card
> >>>> already exist
> >>>> 6) User is unhappy because his plugged in sound card did not show up in
> >>>> PulseAudio.
> >>>>
> >>>> So, assuming all this is right, it seems like we need some type of
> >>>> callback from the usb driver when all the interfaces for the sound card
> >>>> has been probed, so we can call snd_card_register at that point instead.
> >>>> Thoughts?
> >>> The driver probably doesn't know when all the interfaces have been
> >>> probed.
> >> I'm unsure if you mean "the usb driver" or "the usb audio driver" in the
> >> sentence above, but the USB driver would enumerate all interfaces and
> >> call the usb audio driver for every interface, and so the USB driver
> >> would know when all the interfaces have been probed, right?
> > I'm not sure what you mean by "the USB driver". The USB core registers
> > all the interfaces, which causes them to be probed. The USB core does
> > know when all the interfaces have been registered.
> Ok.
> >> Is there a way the USB audio driver can subscribe, or get an additional
> >> callback of some sort, when that happens?
> > No, not currently.
>
> Given the use case we have here, do you think that would be a reasonable
> solution to the problem?
I'd prefer to look at other solutions.
> >>> Maybe it would be better to send a signal to userspace each
> >>> time snd_card_register is called, even if nothing is done.
> >> That sounds very suboptimal, given that PulseAudio's probing mechanism
> >> can be quite heavy (depending on the device).
>
> As Clemens said, there are device nodes being added, but having a look
> at how this is handled in udev's 78-sound-card.rules [1], the rule has a
> big comment section in the beginning. This comment claims that |"||The
> control device node creation can be used as synchronization point". I
> understand this will happen on the first call to snd_card_register, and
> only then.|
>
> >>> Alternatively, when the first interface is probed, the driver could
> >>> claim all the other interfaces belonging to the same association.
> >> Not sure how well that would work out with "composite" devices, e g
> >> headset with volume up/down buttons?
> > Presumably the HID interface (with the button controls) would not be in
> > the audio interface association. Anyway, the audio driver wouldn't
> > claim anything that wasn't an audio interface.
> Ok, I'll trust you to know this better than me. :-)
>
> I'm not sure exactly what "claim all the other interfaces belonging to
> the same association" means, but if it means it can enumerate all those
> interfaces it has claimed but not yet probed, maybe the USB audio driver
> can use this information to avoid calling snd_card_register until after
> probing the last interface?
A driver claims an interface when it wants to be bound to that
interface right away, without waiting for a probe. Thus, when the
first audio interface in a USB device is probed, the audio driver takes
the opportunity to claim all the other audio interfaces associated with
it.
In this case, it sounds like the control interface (A) gets probed,
which causes the sound card to be registered. A little later, the PCM
interface (B) is probed. The sound driver recognizes that interface B
is connected with interface A and adds this information to the sound
card, but it's already too late.
So here's my question: If the sound driver recognizes that interface B
is connected with interface A when B is probed, why can't it recognize
this fact when A is probed? It could claim B while A's probe is
running. Then the sound card would be registered with the PCM
component already in place.
Alan Stern
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: USB Audio initialization race
2013-09-14 13:44 ` Alan Stern
@ 2013-09-14 19:33 ` Clemens Ladisch
2013-09-15 1:35 ` Alan Stern
0 siblings, 1 reply; 11+ messages in thread
From: Clemens Ladisch @ 2013-09-14 19:33 UTC (permalink / raw)
To: Alan Stern; +Cc: alsa-devel, David Henningsson, zonque
Alan Stern wrote:
> So here's my question: If the sound driver recognizes that interface B
> is connected with interface A when B is probed, why can't it recognize
> this fact when A is probed? It could claim B while A's probe is
> running. Then the sound card would be registered with the PCM
> component already in place.
The sound driver already does this.
Regards,
Clemens
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: USB Audio initialization race
2013-09-14 19:33 ` Clemens Ladisch
@ 2013-09-15 1:35 ` Alan Stern
2013-09-15 8:49 ` Clemens Ladisch
0 siblings, 1 reply; 11+ messages in thread
From: Alan Stern @ 2013-09-15 1:35 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: alsa-devel, David Henningsson, zonque
On Sat, 14 Sep 2013, Clemens Ladisch wrote:
> Alan Stern wrote:
> > So here's my question: If the sound driver recognizes that interface B
> > is connected with interface A when B is probed, why can't it recognize
> > this fact when A is probed? It could claim B while A's probe is
> > running. Then the sound card would be registered with the PCM
> > component already in place.
>
> The sound driver already does this.
It does? Why does the comment preceding snd_usb_audio_probe() say:
* thus we check the usb device pointer and creates the card instance
* only at the first time. the successive calls of this function will
* append the pcm interface to the corresponding card.
Is the comment out of date?
Anyway, since the driver does this, it means the scenario envisioned by
David can't happen. Not unless the device's descriptors are buggy.
Alan Stern
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: USB Audio initialization race
2013-09-15 1:35 ` Alan Stern
@ 2013-09-15 8:49 ` Clemens Ladisch
2013-09-16 22:21 ` David Henningsson
0 siblings, 1 reply; 11+ messages in thread
From: Clemens Ladisch @ 2013-09-15 8:49 UTC (permalink / raw)
To: Alan Stern; +Cc: alsa-devel, David Henningsson, zonque
Alan Stern wrote:
> On Sat, 14 Sep 2013, Clemens Ladisch wrote:
>> Alan Stern wrote:
>>> So here's my question: If the sound driver recognizes that interface B
>>> is connected with interface A when B is probed, why can't it recognize
>>> this fact when A is probed? It could claim B while A's probe is
>>> running. Then the sound card would be registered with the PCM
>>> component already in place.
>>
>> The sound driver already does this.
>
> It does? Why does the comment preceding snd_usb_audio_probe() say:
>
> * thus we check the usb device pointer and creates the card instance
> * only at the first time. the successive calls of this function will
> * append the pcm interface to the corresponding card.
For UAC devices with correct descriptors, and for devices with multi-
interface quirks, the driver claims all interfaces at once. But it is
still possible to have devices with zero or two audio control interfaces.
Regards,
Clemens
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: USB Audio initialization race
2013-09-15 8:49 ` Clemens Ladisch
@ 2013-09-16 22:21 ` David Henningsson
0 siblings, 0 replies; 11+ messages in thread
From: David Henningsson @ 2013-09-16 22:21 UTC (permalink / raw)
To: Clemens Ladisch; +Cc: alsa-devel, Alan Stern, zonque
On 09/15/2013 10:49 AM, Clemens Ladisch wrote:
> Alan Stern wrote:
>> On Sat, 14 Sep 2013, Clemens Ladisch wrote:
>>> Alan Stern wrote:
>>>> So here's my question: If the sound driver recognizes that interface B
>>>> is connected with interface A when B is probed, why can't it recognize
>>>> this fact when A is probed? It could claim B while A's probe is
>>>> running. Then the sound card would be registered with the PCM
>>>> component already in place.
>>>
>>> The sound driver already does this.
>>
>> It does? Why does the comment preceding snd_usb_audio_probe() say:
>>
>> * thus we check the usb device pointer and creates the card instance
>> * only at the first time. the successive calls of this function will
>> * append the pcm interface to the corresponding card.
>
> For UAC devices with correct descriptors, and for devices with multi-
> interface quirks, the driver claims all interfaces at once. But it is
> still possible to have devices with zero or two audio control interfaces.
So, indeed there is some claiming being done in the usb audio driver, so
maybe this is not as much of a problem as I thought, but I think this
comment is wrong:
/* we are allowed to call snd_card_register() many times */
...because it implies that it is okay to change the card and then call
snd_card_register again, and it is not, because userspace cannot handle
that correctly. It would be more appropriate to print a warning if this
happens.
Also, I wonder if it makes sense to also claim control interfaces
(USB_SUBCLASS_AUDIOCONTROL) in snd_usb_create_stream, in case the audio
streaming interface is probed before the control interface?
Anyway, I'm waiting for the (latest) bug reporter to return back to me
with "lsusb -v" and some more info, so I can verify if this could
actually be the problem or not.
--
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2013-09-16 22:21 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-13 19:56 USB Audio initialization race David Henningsson
2013-09-13 20:39 ` Alan Stern
2013-09-13 20:53 ` David Henningsson
2013-09-13 21:06 ` Alan Stern
2013-09-13 23:47 ` David Henningsson
2013-09-14 13:44 ` Alan Stern
2013-09-14 19:33 ` Clemens Ladisch
2013-09-15 1:35 ` Alan Stern
2013-09-15 8:49 ` Clemens Ladisch
2013-09-16 22:21 ` David Henningsson
2013-09-13 20:55 ` Clemens Ladisch
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.