The functions dvb_dmxdev_section_callback, dvb_dmxdev_ts_callback,
dvb_dmx_swfilter_packet, dvb_dmx_swfilter_packets, dvb_dmx_swfilter and
dvb_dmx_swfilter_204 may be called from both interrupt and process
context. Therefore they need to be protected by spin_lock_irqsave()
instead of spin_lock().
This fixes a deadlock discovered by lockdep.
Signed-off-by: Andreas Oberritter <obi@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
enum dmx_success success)
{
struct dmxdev_filter *dmxdevfilter = filter->priv;
enum dmx_success success)
{
struct dmxdev_filter *dmxdevfilter = filter->priv;
int ret;
if (dmxdevfilter->buffer.error) {
wake_up(&dmxdevfilter->buffer.queue);
return 0;
}
int ret;
if (dmxdevfilter->buffer.error) {
wake_up(&dmxdevfilter->buffer.queue);
return 0;
}
- spin_lock(&dmxdevfilter->dev->lock);
+ spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
if (dmxdevfilter->state != DMXDEV_STATE_GO) {
if (dmxdevfilter->state != DMXDEV_STATE_GO) {
- spin_unlock(&dmxdevfilter->dev->lock);
+ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
return 0;
}
del_timer(&dmxdevfilter->timer);
return 0;
}
del_timer(&dmxdevfilter->timer);
}
if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
dmxdevfilter->state = DMXDEV_STATE_DONE;
}
if (dmxdevfilter->params.sec.flags & DMX_ONESHOT)
dmxdevfilter->state = DMXDEV_STATE_DONE;
- spin_unlock(&dmxdevfilter->dev->lock);
+ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
wake_up(&dmxdevfilter->buffer.queue);
return 0;
}
wake_up(&dmxdevfilter->buffer.queue);
return 0;
}
{
struct dmxdev_filter *dmxdevfilter = feed->priv;
struct dvb_ringbuffer *buffer;
{
struct dmxdev_filter *dmxdevfilter = feed->priv;
struct dvb_ringbuffer *buffer;
- spin_lock(&dmxdevfilter->dev->lock);
+ spin_lock_irqsave(&dmxdevfilter->dev->lock, flags);
if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {
if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) {
- spin_unlock(&dmxdevfilter->dev->lock);
+ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
else
buffer = &dmxdevfilter->dev->dvr_buffer;
if (buffer->error) {
else
buffer = &dmxdevfilter->dev->dvr_buffer;
if (buffer->error) {
- spin_unlock(&dmxdevfilter->dev->lock);
+ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
wake_up(&buffer->queue);
return 0;
}
wake_up(&buffer->queue);
return 0;
}
dvb_ringbuffer_flush(buffer);
buffer->error = ret;
}
dvb_ringbuffer_flush(buffer);
buffer->error = ret;
}
- spin_unlock(&dmxdevfilter->dev->lock);
+ spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags);
wake_up(&buffer->queue);
return 0;
}
wake_up(&buffer->queue);
return 0;
}
void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
size_t count)
{
void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf,
size_t count)
{
- spin_lock(&demux->lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&demux->lock, flags);
while (count--) {
if (buf[0] == 0x47)
while (count--) {
if (buf[0] == 0x47)
- spin_unlock(&demux->lock);
+ spin_unlock_irqrestore(&demux->lock, flags);
}
EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
{
}
EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
{
- spin_lock(&demux->lock);
+ spin_lock_irqsave(&demux->lock, flags);
if (demux->tsbufp) {
i = demux->tsbufp;
if (demux->tsbufp) {
i = demux->tsbufp;
- spin_unlock(&demux->lock);
+ spin_unlock_irqrestore(&demux->lock, flags);
}
EXPORT_SYMBOL(dvb_dmx_swfilter);
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
{
}
EXPORT_SYMBOL(dvb_dmx_swfilter);
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
{
int p = 0, i, j;
u8 tmppack[188];
int p = 0, i, j;
u8 tmppack[188];
- spin_lock(&demux->lock);
+ spin_lock_irqsave(&demux->lock, flags);
if (demux->tsbufp) {
i = demux->tsbufp;
if (demux->tsbufp) {
i = demux->tsbufp;
- spin_unlock(&demux->lock);
+ spin_unlock_irqrestore(&demux->lock, flags);
}
EXPORT_SYMBOL(dvb_dmx_swfilter_204);
}
EXPORT_SYMBOL(dvb_dmx_swfilter_204);