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.txt
    Index: 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    [W:0.024 / U:8.016 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site