diff options
author | Marko Ristola <marko.ristola@kolumbus.fi> | 2010-11-14 12:09:04 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-12-29 05:16:48 -0500 |
commit | 9c81496a88b04206d0607b23b298b6529da1fcb0 (patch) | |
tree | 4b8abc23a2d2976129c6837461b207fd98cb85b7 /drivers/media | |
parent | 116d588ea21cf0278a4de1e3272e9c3220a647e7 (diff) |
[media] Mantis: append tasklet maintenance for DVB stream delivery
After dvb-core has called mantis-fe->stop_feed(dvbdmxfeed)
the last time (count to zero), no data should ever be copied
with dvb_dmx_swfilter() by a tasklet: the target structure
might be in an unusable state. Caller of mantis_fe->stop_feed()
assumes that feeding is stopped after stop_feed() has been
called, ie. dvb_dmx_swfilter() isn't running, and won't be called.
There is a risk that dvb_dmx_swfilter() references freed resources
(memory or spinlocks or ???) causing instabilities. Thus
tasklet_disable(&mantis->tasklet) must be called inside of
mantis-fe->stop_feed(dvbdmxfeed) when necessary.
Signed-off-by: Marko Ristola <marko.ristola@kolumbus.fi>
Signed-off-by: Manu Abraham <manu@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/mantis/mantis_dvb.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/media/dvb/mantis/mantis_dvb.c b/drivers/media/dvb/mantis/mantis_dvb.c index 99d82eec3b03..a9864f7134e1 100644 --- a/drivers/media/dvb/mantis/mantis_dvb.c +++ b/drivers/media/dvb/mantis/mantis_dvb.c | |||
@@ -117,6 +117,7 @@ static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
117 | if (mantis->feeds == 1) { | 117 | if (mantis->feeds == 1) { |
118 | dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma"); | 118 | dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma"); |
119 | mantis_dma_start(mantis); | 119 | mantis_dma_start(mantis); |
120 | tasklet_enable(&mantis->tasklet); | ||
120 | } | 121 | } |
121 | 122 | ||
122 | return mantis->feeds; | 123 | return mantis->feeds; |
@@ -136,6 +137,7 @@ static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
136 | mantis->feeds--; | 137 | mantis->feeds--; |
137 | if (mantis->feeds == 0) { | 138 | if (mantis->feeds == 0) { |
138 | dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma"); | 139 | dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma"); |
140 | tasklet_disable(&mantis->tasklet); | ||
139 | mantis_dma_stop(mantis); | 141 | mantis_dma_stop(mantis); |
140 | } | 142 | } |
141 | 143 | ||
@@ -216,6 +218,7 @@ int __devinit mantis_dvb_init(struct mantis_pci *mantis) | |||
216 | 218 | ||
217 | dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx); | 219 | dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx); |
218 | tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis); | 220 | tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis); |
221 | tasklet_disable(&mantis->tasklet); | ||
219 | if (mantis->hwconfig) { | 222 | if (mantis->hwconfig) { |
220 | result = config->frontend_init(mantis, mantis->fe); | 223 | result = config->frontend_init(mantis, mantis->fe); |
221 | if (result < 0) { | 224 | if (result < 0) { |