Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Kernel Oops after setting the same PID for PES and section filter



Hi,

we use the Linux DVB-API Version 3 for the tuxbox project (PPC-powered settop box) and recently we had some bug reports concerning a Kernel Oops during streaming.

I was able to reproduce and trace it, found out it occured in the dvb_demux.c and following this I tried to get the relations of the different structures but failed in some parts. I've attached a simple code that will trigger the crash on our platform sooner or later (depending on the contents of the feed_list).

Problem ist that the functions dvbdmx_release_section_feed() and dvbdmx_release_ts_feed() (both in dvb_demux.c) only check for the PID while traversing the demux->feed_list.

But this PID is present 2 times now. Only the first entry is found and deleted. If this was the wrong one the false reference stays in the list which now points to the freed entry (pid is set to 0xffff and state is set to DMX_STATE_FREE).

Of course sooner or later this entry will get re-added to the list and can then severely corrupt the prev/next-pointers which leads to a lockup or the reported Kernel Oops.

As I don't see the big picture yet: why does this happen? Having the same PID in the list twice seems not to be expected by the functions, so should this situation actually get turned into one feed supplying both PES and section client (so PES gets software-filtered)?

But what if a possible hardware-section filter is present?

Unfortunately I haven't found an architectural description of the inner workings so my guessings might be incorrect.

Any help on this would be appreciated.

Carsten Juttner

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "sys/ioctl.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "linux/dvb/dmx.h"

int main (int argc, char **argv){
	struct dmx_pes_filter_params pes;
	struct dmx_sct_filter_params sct;

	int dem1,dem2;

	memset (&pes,0,sizeof(struct dmx_pes_filter_params));
	memset (&sct,0,sizeof(struct dmx_sct_filter_params));

	dem1 = open ("/dev/dvb/adapter0/demux0", O_RDWR);
	dem2 = open ("/dev/dvb/adapter0/demux0", O_RDWR);
	
	pes.pid = 0x0000;
	pes.output = DMX_OUT_TAP;
	pes.input = DMX_IN_FRONTEND;
	pes.pes_type = DMX_PES_OTHER;
	pes.flags = DMX_IMMEDIATE_START;

	sct.pid = 0x0000;	// same PID as before
	sct.timeout = 10000;
	sct.flags = DMX_IMMEDIATE_START;
	
	ioctl (dem1, DMX_SET_PES_FILTER, &pes);
	ioctl (dem2, DMX_SET_FILTER, &sct);

	close (dem1);
	close (dem2);
	return 0;
}

Home | Main Index | Thread Index