There is a memory lead in the demuxer, it's possible to open the dvr0 device
several times, each time after the first will leak the dvr buffer. This patch
fixes that by only allowing a single read mode open, which is what the API says
should be the case. It's still possible to open multiple times in write mode.
This doesn't seem to cause a problem and could be a useful thing to do. It
would allow separate processes/threads to send audio/video/subtitles to a
decoder.
This is my first time using mercurial, so hopefully I got the patch format
correct.
# HG changeset patch
# User xyzzy@xxxxxxxxxxxxxxxxxxx
# Node ID 6396b65320e33fa6507622cbf58f6c0d2bf0da1f
# Parent e4f6344a95f9b9027f555f95dfa2e6af023d95e4
Fix memory leak in dvr open
From: Trent Piepho <xyzzy@xxxxxxxxxxxxx>
The dvr device could be opened multiple times simultaneously in O_RDONLY mode.
Each open after the first would allocate a new dvr buffer (1880 KB) and leak
the old buffer. The first close would de-allocate the dvr buffer and cause
all other open dvrs to stop working. This patch allows only a single O_RDONLY
open of the drv device, as per the API specification. Multiple O_WRONLY opens
are still allowed and don't appear to cause any problems.
Signed-off-by: Trent Piepho <xyzzy@xxxxxxxxxxxxx>
diff -r e4f6344a95f9 -r 6396b65320e3 linux/drivers/media/dvb/dvb-core/dmxdev.c
--- a/linux/drivers/media/dvb/dvb-core/dmxdev.c Mon Mar 27 11:00:40 2006 -0300
+++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c Mon Mar 27 13:31:49 2006 -0800
@@ -141,12 +141,18 @@ static int dvb_dvr_open(struct inode *in
}
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
- void *mem = vmalloc(DVR_BUFFER_SIZE);
+ void *mem;
+ if (!dvbdev->readers) {
+ mutex_unlock(&dmxdev->mutex);
+ return -EBUSY;
+ }
+ mem = vmalloc(DVR_BUFFER_SIZE);
if (!mem) {
mutex_unlock(&dmxdev->mutex);
return -ENOMEM;
}
dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
+ dvbdev->readers--;
}
if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
@@ -184,6 +190,7 @@ static int dvb_dvr_release(struct inode
dmxdev->dvr_orig_fe);
}
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+ dvbdev->readers++;
if (dmxdev->dvr_buffer.data) {
void *mem = dmxdev->dvr_buffer.data;
mb();
@@ -1029,8 +1036,7 @@ static struct file_operations dvb_dvr_fo
static struct dvb_device dvbdev_dvr = {
.priv = NULL,
- .users = 1,
- .writers = 1,
+ .readers = 1,
.fops = &dvb_dvr_fops
};
_______________________________________________
linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb