At Thu, 10 Jan 2013 09:23:48 +0100,
Jens Axboe wrote:
> 
> Hi,
> 
> I have a USB DAC that I use for music. Just upgraded my workstation from
> 3.7-rc7 to 3.8-rc3 this morning, and when the DAC is switched on, I get
> an immediate oops. I have attached the picture. It's crashing here:
> 
> (gdb) l *snd_usb_pcm_prepare+0x153
> 0x161c is in snd_usb_pcm_prepare (sound/usb/pcm.c:470).
> 465           snd_pcm_format_t pcm_format)
> 466   {
> 467           int i;
> 468           int score = 0;
> 469   
> 470           if (fp->channels < 1) {
> 471                   snd_printdd("%s: (fmt @%p) no channels\n", __func__, 
> fp);
> 472                   return 0;
> 473           }
> 474   
> 
> 'fp' is clearly NULL.

Hmm... it's a function called only from a single place in
configure_sync_endpoint() and it's in list_for_each_entry():

        list_for_each_entry(fp, &sync_subs->fmt_list, list) {
                int score = match_endpoint_audioformats(fp, subs->cur_audiofmt,
                        subs->cur_rate, subs->pcm_format);

so it must be hardly NULL in normal situations.
The only scenario I can imagine right now is that the whole structure
is still uninitialized while it's called.  If so, it's a race problem,
and shouldn't be new to 3.8.  A patch like below might paper over the
problem although it's far from perfect.


> Let me know if you want a bisect.

Yeah, that'll be really helpful.

Or, at least, could you try to copy sound/usb/* from 3.7 to 3.8 and
see whether it's really a regression there?


thanks,

Takashi

---
diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index ad181d5..3bfc564 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -81,8 +81,7 @@ static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
  */
 
 static void snd_usb_init_substream(struct snd_usb_stream *as,
-                                  int stream,
-                                  struct audioformat *fp)
+                                  int stream)
 {
        struct snd_usb_substream *subs = &as->substream[stream];
 
@@ -96,6 +95,13 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
        subs->speed = snd_usb_get_speed(subs->dev);
 
        snd_usb_set_pcm_ops(as->pcm, stream);
+}
+
+static void snd_usb_add_substream_format(struct snd_usb_stream *as,
+                                  int stream,
+                                  struct audioformat *fp)
+{
+       struct snd_usb_substream *subs = &as->substream[stream];
 
        list_add_tail(&fp->list, &subs->fmt_list);
        subs->formats |= fp->formats;
@@ -342,7 +348,7 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
                err = snd_pcm_new_stream(as->pcm, stream, 1);
                if (err < 0)
                        return err;
-               snd_usb_init_substream(as, stream, fp);
+               snd_usb_add_substream_format(as, stream, fp);
                return add_chmap(as->pcm, stream, subs);
        }
 
@@ -370,7 +376,9 @@ int snd_usb_add_audio_stream(struct snd_usb_audio *chip,
        else
                strcpy(pcm->name, "USB Audio");
 
-       snd_usb_init_substream(as, stream, fp);
+       snd_usb_init_substream(as, SNDRV_PCM_STREAM_PLAYBACK);
+       snd_usb_init_substream(as, SNDRV_PCM_STREAM_CAPTURE);
+       snd_usb_add_substream_format(as, stream, fp);
 
        list_add(&as->list, &chip->pcm_list);
        chip->pcm_devs++;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to