Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[linux-dvb] vfree during spin_lock hold (Was: (In)consistency of DMX/DVR buffers and OSD ioctls)
Hi,
during seeking for a better protection against dropouts of
of a PES filter for DMX_PES_OTHER (AC3) using DMX_OUT_TAP caused
by OSD popups, I've seen that within DmxDevSetBufferSize() in
dmxdev.c that vfree() is called within a spin_lock_irq/spin_unlock_irq
pair. This seems to be a bug. Enclosed a patch which changes this.
Also changed in this patch: hold spin_lock in DmxDevTSCallback()
during copy buffers (seems to decrease dropouts caused by other
activities on the system), use reparent_to_init() for the
kernel threads "arm_mon" and "fe_thread".
Werner
-----------------------------------------------------------------------
--- dmxdev.c
+++ dmxdev.c Wed Mar 27 11:54:02 2002
@@ -288,18 +288,19 @@
DmxDevSetBufferSize(dmxdev_filter_t *dmxdevfilter, unsigned long size)
{
dmxdev_buffer_t *buf=&dmxdevfilter->buffer;
+ void *mem=buffer->data;
if (buf->size==size)
return 0;
if (dmxdevfilter->state>=DMXDEV_STATE_GO)
return -EBUSY;
spin_lock_irq(&dmxdevfilter->dev->lock);
- if (buf->data)
- vfree(buf->data);
buf->data=0;
buf->size=size;
buf->pwrite=buf->pread=0;
spin_unlock_irq(&dmxdevfilter->dev->lock);
+ if (mem)
+ vfree(mem);
if (buf->size) {
void *mem=vmalloc(dmxdevfilter->buffer.size);
@@ -384,18 +385,21 @@
dmxdev_filter_t *dmxdevfilter=(dmxdev_filter_t *) feed->priv;
dmxdev_buffer_t *buffer;
int ret;
-
- if (dmxdevfilter->params.pes.output==DMX_OUT_DECODER)
- return 0;
+
+ spin_lock(&dmxdevfilter->dev->lock);
+ if (dmxdevfilter->params.pes.output==DMX_OUT_DECODER) {
+ spin_unlock(&dmxdevfilter->dev->lock);
+ return 0;
+ }
if (dmxdevfilter->params.pes.output==DMX_OUT_TAP)
buffer=&dmxdevfilter->buffer;
else
buffer=&dmxdevfilter->dev->dvr_buffer;
- if (buffer->error) {
- wake_up(&buffer->queue);
- return 0;
- }
+
+ if (buffer->error)
+ goto out;
+
ret=DmxDevBufferWrite(buffer, buffer1, buffer1_len);
if (ret==buffer1_len)
ret=DmxDevBufferWrite(buffer, buffer2, buffer2_len);
@@ -403,6 +407,8 @@
buffer->pwrite=buffer->pread;
buffer->error=-EBUFFEROVERFLOW;
}
+out:
+ spin_unlock(&dmxdevfilter->dev->lock);
wake_up(&buffer->queue);
return 0;
}
--- dvb.c
+++ dvb.c Wed Mar 27 11:49:06 2002
@@ -427,13 +427,19 @@
u16 newloops;
lock_kernel();
-#if 0
+#if 1
daemonize();
+ reparent_to_init();
+
#else
exit_mm(current);
current->session=current->pgrp=1;
#endif
+ spin_lock_irq(¤t->sigmask_lock);
sigfillset(¤t->blocked);
+ recalc_sigpending(current);
+ spin_unlock_irq(¤t->sigmask_lock);
+
strcpy(current->comm, "arm_mon");
dvb->arm_thread = current;
unlock_kernel();
--- dvb_frontend.c
+++ dvb_frontend.c Wed Mar 27 11:49:06 2002
@@ -431,7 +431,13 @@
lock_kernel();
daemonize();
+ reparent_to_init();
+
+ spin_lock_irq(¤t->sigmask_lock);
sigfillset(¤t->blocked);
+ recalc_sigpending(current);
+ spin_unlock_irq(¤t->sigmask_lock);
+
strcpy(current->comm,"fe_thread");
fe->thread = current;
unlock_kernel();
--
Info:
To unsubscribe send a mail to listar@linuxtv.org with "unsubscribe linux-dvb" as subject.
Home |
Main Index |
Thread Index