lkml.org 
[lkml]   [2003]   [Nov]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
Subject[I810_AUDIO] 1/x: Fix wait queue race in drain_dac
From
Hi:

This is the first of a number of patches to fix DMA bugs in the
OSS i810_audio driver.

This particular one fixes a textbook race condition in drain_dac
that causes it to timeout when it shouldn't.
--
Debian GNU/Linux 3.0 is out! ( http://www.debian.org/ )
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtIndex: kernel-source-2.4/drivers/sound/i810_audio.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.4/drivers/sound/i810_audio.c,v
retrieving revision 1.8
diff -u -r1.8 i810_audio.c
--- kernel-source-2.4/drivers/sound/i810_audio.c 3 Sep 2003 10:27:11 -0000 1.8
+++ kernel-source-2.4/drivers/sound/i810_audio.c 21 Nov 2003 11:20:48 -0000
@@ -1231,6 +1231,17 @@
spin_lock_irqsave(&state->card->lock, flags);
i810_update_ptr(state);
count = dmabuf->count;
+
+ /* It seems that we have to set the current state to
+ * TASK_INTERRUPTIBLE every time to make the process
+ * really go to sleep. This also has to be *after* the
+ * update_ptr() call because update_ptr is likely to
+ * do a wake_up() which will unset this before we ever
+ * try to sleep, resuling in a tight loop in this code
+ * instead of actually sleeping and waiting for an
+ * interrupt to wake us up!
+ */
+ __set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_irqrestore(&state->card->lock, flags);

if (count <= 0)
@@ -1250,16 +1261,6 @@
break;
}

- /* It seems that we have to set the current state to
- * TASK_INTERRUPTIBLE every time to make the process
- * really go to sleep. This also has to be *after* the
- * update_ptr() call because update_ptr is likely to
- * do a wake_up() which will unset this before we ever
- * try to sleep, resuling in a tight loop in this code
- * instead of actually sleeping and waiting for an
- * interrupt to wake us up!
- */
- set_current_state(TASK_INTERRUPTIBLE);
/*
* set the timeout to significantly longer than it *should*
* take for the DAC to drain the DMA buffer
\
 
 \ /
  Last update: 2005-03-22 13:58    [from the cache]
©2003-2011 Jasper Spaans