2.6: spinlock bug in sound/oss/dmabuf.c
Hi all,
I think I found a bug in sound/oss/dmabuf.c
DMAbuf_getrdbuffer holds a spinlock and possibly calls dma_reset_input. The dma_reset_input tries to hold that spinlock again:
int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
{
struct audio_operations *adev = audio_devs[dev];
unsigned long flags;
int err = 0, n = 0;
struct dma_buffparms *dmap = adev->dmap_in;
[...]
spin_lock_irqsave(&dmap->lock,flags);
if (!timeout) {
/* FIXME: include device name */
err = -EIO;
printk(KERN_WARNING "Sound: DMA (input) timed out..
dma_reset_input(dev);[...]
static void dma_reset_input(int dev)
{
struct audio_operations *adev = audio_devs[dev];
unsigned long flags;
struct dma_buffparms *dmap = adev->dmap_in;
spin_lock_irqsave(&dmap->lock,flags);Any opinions?
cheers
Christian
Quoted 5 lines · Christian Borntraeger
I think I found a bug in
sound/oss/dmabuf.c
DMAbuf_getrdbufferholds a spinlock and possibly callsdma_reset_input. Thedma_reset_inputtries to hold that spinlock again:
yup, thanks.
sound/oss/dmabuf.c renamed from sound/oss/dmabuf.c~oss-dmabuf-deadlock-fix +1 -1
@@ -587,7 +587,6 @@ int DMAbuf_getrdbuffer(int dev, char **bspin_unlock_irqrestore (&dmap->lock,flags); timeout =interruptible_sleep_on_timeout (&adev->in_sleeper, timeout); -spin_lock_irqsave (&dmap->lock,flags);if (!timeout) {/* FIXME: include device name */ err = -EIO ;
@@ -595,6 +594,7 @@ int DMAbuf_getrdbuffer(int dev, char **bdma_reset_input (dev); }else err = -EINTR ; +spin_lock_irqsave (&dmap->lock,flags); }spin_unlock_irqrestore (&dmap->lock,flags);
_