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/