All of lore.kernel.org
 help / color / mirror / Atom feed
* Questions on locking, snd-usb-caiaq
@ 2009-09-20 12:07 Mark Hills
  2009-09-21 13:35 ` Takashi Iwai
  0 siblings, 1 reply; 13+ messages in thread
From: Mark Hills @ 2009-09-20 12:07 UTC (permalink / raw)
  To: alsa-devel

I fixed some race issues in snd-usb-caiaq, but have some questions on the 
interface between the driver and ALSA.

First fix is a lock in pointer(), which caused snd_pcm_update_hw_ptr_pos() 
to report an out of range buffer position (even though it was sucessfully 
corrected to zero).

Second is a lock as part of trigger(). On testing, this appears to fix an 
issue where white noise could sometimes be transferred by the driver.

According to the documentation, trigger() and pointer() are called with 
local interrupts disabled. This means they should really be non-irqsave 
locks?

(http://www.alsa-project.org/~tiwai/writing-an-alsa-driver/ch05s08.html)

Even for callbacks documented as atomic, if read_completed() and 
write_completed() can be called at any time interrupts are enabled (eg. on 
another CPU) it seems that additional locking my be required. Candidates 
are:

   snd_usb_caiaq_substream_open
   snd_usb_caiaq_substream_close
   snd_usb_caiaq_pcm_hw_free
   snd_usb_caiaq_pcm_prepare

Are there any guarantees on these functions which mean the lock is not 
required?

To lock in prepare() would (I think) require demoting a 
spin_lock_irqsave() to a spin_lock() to send initialisation commands. If 
so, what is the best design for this?

Thanks,

-- 
Mark

diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 121af06..c659f81 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -62,10 +62,15 @@ static void
  activate_substream(struct snd_usb_caiaqdev *dev,
  	           struct snd_pcm_substream *sub)
  {
+	unsigned long flags;
+	spin_lock_irqsave(&dev->spinlock, flags);
+
  	if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
  		dev->sub_playback[sub->number] = sub;
  	else
  		dev->sub_capture[sub->number] = sub;
+
+	spin_unlock_irqrestore(&dev->spinlock, flags);
  }

  static void
@@ -269,16 +274,23 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
  {
  	int index = sub->number;
  	struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
+	unsigned long flags;
+	snd_pcm_uframes_t ptr;
+
+	spin_lock_irqsave(&dev->spinlock, flags);

  	if (dev->input_panic || dev->output_panic)
-		return SNDRV_PCM_POS_XRUN;
+		ptr = SNDRV_PCM_POS_XRUN;

  	if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
-		return bytes_to_frames(sub->runtime,
+		ptr = bytes_to_frames(sub->runtime,
  					dev->audio_out_buf_pos[index]);
  	else
-		return bytes_to_frames(sub->runtime,
+		ptr = bytes_to_frames(sub->runtime,
  					dev->audio_in_buf_pos[index]);
+
+	spin_unlock_irqrestore(&dev->spinlock, flags);
+	return ptr;
  }

  /* operators for both playback and capture */

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2009-10-18 17:48 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-20 12:07 Questions on locking, snd-usb-caiaq Mark Hills
2009-09-21 13:35 ` Takashi Iwai
2009-09-22  4:53   ` Daniel Mack
2009-09-22  7:14     ` Mark Hills
2009-09-25 15:22       ` [PATCH 1/4] snd-usb-caiaq: Do not disable local interrupts Mark Hills
2009-09-25 15:22         ` [PATCH 2/4] snd-usb-caiaq: Missing lock around use of buffer positions Mark Hills
2009-09-25 15:22           ` [PATCH 3/4] snd-usb-caiaq: Lock on stream start/unpause Mark Hills
2009-09-25 15:22             ` [PATCH 4/4] snd-usb-caiaq: Bump version number to 1.3.20 Mark Hills
2009-09-25 16:00         ` [PATCH 1/4] snd-usb-caiaq: Do not disable local interrupts Daniel Mack
2009-09-26 16:06           ` Mark Hills
2009-09-28  8:33             ` Takashi Iwai
2009-10-17 16:12               ` Daniel Mack
2009-10-18 17:52                 ` Mark Hills

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.