V4L/DVB (10572): Revert commit dda06a8e4610757def753ee3a541a0b1a1feb36b
Mauro Carvalho Chehab [Mon, 16 Feb 2009 18:27:44 +0000 (15:27 -0300)]
On Mon, 02 Feb 2009, Hartmut wrote:

This change set is wrong. The affected functions cannot be called from
an interrupt context, because they may process large buffers. In this
case, interrupts are disabled for a long time. Functions, like
dvb_dmx_swfilter_packets(), could be called only from a tasklet.

This change set does hide some strong design bugs in dm1105.c and
au0828-dvb.c.

Please revert this change set and do fix the bugs in dm1105.c and
au0828-dvb.c (and other files).

On Sun, 15 Feb 2009, Oliver Endriss wrote:

This changeset _must_ be reverted! It breaks all kernels since 2.6.27
for applications which use DVB and require a low interrupt latency.

It is a very bad idea to call the demuxer to process data buffers with
interrupts disabled!

On Mon, 16 Feb 2009, Trent Piepho wrote:

I agree, this is bad.  The demuxer is far too much work to be done with
IRQs off.  IMHO, even doing it under a spin-lock is excessive.  It should
be a mutex.  Drivers should use a work-queue to feed the demuxer.

Thank you for testing this changeset and discovering the issues on it.

Cc: Trent Piepho <xyzzy@speakeasy.org>
Cc: Hartmut <e9hack@googlemail.com>
Cc: Oliver Endriss <o.endriss@gmx.de>
Cc: Andreas Oberritter <obi@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

drivers/media/dvb/dvb-core/dmxdev.c
drivers/media/dvb/dvb-core/dvb_demux.c

index 0c733c6..069d847 100644 (file)
@@ -364,16 +364,15 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
                                       enum dmx_success success)
 {
        struct dmxdev_filter *dmxdevfilter = filter->priv;
-       unsigned long flags;
        int ret;
 
        if (dmxdevfilter->buffer.error) {
                wake_up(&dmxdevfilter->buffer.queue);
                return 0;
        }
-       spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
+       spin_lock(&dmxdevfilter->dev->lock);
        if (dmxdevfilter->state != DMXDEV_STATE_GO) {
-               spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+               spin_unlock(&dmxdevfilter->dev->lock);
                return 0;
        }
        del_timer(&dmxdevfilter->timer);
@@ -392,7 +391,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
        }
        if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
                dmxdevfilter->state = DMXDEV_STATE_DONE;
-       spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+       spin_unlock(&dmxdevfilter->dev->lock);
        wake_up(&dmxdevfilter->buffer.queue);
        return 0;
 }
@@ -404,12 +403,11 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
 {
        struct dmxdev_filter *dmxdevfilter = feed->priv;
        struct dvb_ringbuffer *buffer;
-       unsigned long flags;
        int ret;
 
-       spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
+       spin_lock(&dmxdevfilter->dev->lock);
        if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {
-               spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+               spin_unlock(&dmxdevfilter->dev->lock);
                return 0;
        }
 
@@ -419,7 +417,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
        else
                buffer = &dmxdevfilter->dev->dvr_buffer;
        if (buffer->error) {
-               spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+               spin_unlock(&dmxdevfilter->dev->lock);
                wake_up(&buffer->queue);
                return 0;
        }
@@ -430,7 +428,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
                dvb_ringbuffer_flush(buffer);
                buffer->error = ret;
        }
-       spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
+       spin_unlock(&dmxdevfilter->dev->lock);
        wake_up(&buffer->queue);
        return 0;
 }
index a2c1fd5..e2eca0b 100644 (file)
@@ -399,9 +399,7 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
 void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
                              size_t count)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&demux->lock, flags);
+       spin_lock(&demux->lock);
 
        while (count--) {
                if (buf[0] == 0x47)
@@ -409,17 +407,16 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
                buf += 188;
        }
 
-       spin_unlock_irqrestore(&demux->lock, flags);
+       spin_unlock(&demux->lock);
 }
 
 EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
 
 void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
 {
-       unsigned long flags;
        int p = 0, i, j;
 
-       spin_lock_irqsave(&demux->lock, flags);
+       spin_lock(&demux->lock);
 
        if (demux->tsbufp) {
                i = demux->tsbufp;
@@ -452,18 +449,17 @@ void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
        }
 
 bailout:
-       spin_unlock_irqrestore(&demux->lock, flags);
+       spin_unlock(&demux->lock);
 }
 
 EXPORT_SYMBOL(dvb_dmx_swfilter);
 
 void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
 {
-       unsigned long flags;
        int p = 0, i, j;
        u8 tmppack[188];
 
-       spin_lock_irqsave(&demux->lock, flags);
+       spin_lock(&demux->lock);
 
        if (demux->tsbufp) {
                i = demux->tsbufp;
@@ -504,7 +500,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
        }
 
 bailout:
-       spin_unlock_irqrestore(&demux->lock, flags);
+       spin_unlock(&demux->lock);
 }
 
 EXPORT_SYMBOL(dvb_dmx_swfilter_204);