diff options
author | Jonathan Nieder <jrnieder@gmail.com> | 2011-05-01 05:29:37 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-05-20 08:29:36 -0400 |
commit | 1fe70e963028f34ba5e32488a7870ff4b410b19b (patch) | |
tree | 8185ba45b69831b8cb6a1b1aef5cb84ea092b8cc /drivers/media/video/cx88/cx88-mpeg.c | |
parent | 8a317a8760cfffa8185b56ff59fb4b6c58488d79 (diff) |
[media] cx88: fix locking of sub-driver operations
The BKL conversion of this driver seems to have gone wrong.
Loading the cx88-blackbird driver deadlocks.
The cause: mpeg_ops::open in the cx2388x blackbird driver acquires the
device lock and calls the sub-driver's request_acquire, which tries to
acquire the lock again. Fix it by clarifying the semantics of
request_acquire, request_release, advise_acquire, and advise_release:
now all will rely on the caller to acquire the device lock.
Based on work by Ben Hutchings <ben@decadent.org.uk>.
Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=31962
Reported-by: Andi Huber <hobrom@gmx.at>
Tested-by: Andi Huber <hobrom@gmx.at>
Tested-by: Marlon de Boer <marlon@hyves.nl>
Cc: stable@kernel.org
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx88/cx88-mpeg.c')
-rw-r--r-- | drivers/media/video/cx88/cx88-mpeg.c | 4 |
1 files changed, 0 insertions, 4 deletions
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index a092c3a4c56d..91d3d179c3c7 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -624,13 +624,11 @@ static int cx8802_request_acquire(struct cx8802_driver *drv) | |||
624 | 624 | ||
625 | if (drv->advise_acquire) | 625 | if (drv->advise_acquire) |
626 | { | 626 | { |
627 | mutex_lock(&drv->core->lock); | ||
628 | core->active_ref++; | 627 | core->active_ref++; |
629 | if (core->active_type_id == CX88_BOARD_NONE) { | 628 | if (core->active_type_id == CX88_BOARD_NONE) { |
630 | core->active_type_id = drv->type_id; | 629 | core->active_type_id = drv->type_id; |
631 | drv->advise_acquire(drv); | 630 | drv->advise_acquire(drv); |
632 | } | 631 | } |
633 | mutex_unlock(&drv->core->lock); | ||
634 | 632 | ||
635 | mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); | 633 | mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); |
636 | } | 634 | } |
@@ -643,14 +641,12 @@ static int cx8802_request_release(struct cx8802_driver *drv) | |||
643 | { | 641 | { |
644 | struct cx88_core *core = drv->core; | 642 | struct cx88_core *core = drv->core; |
645 | 643 | ||
646 | mutex_lock(&drv->core->lock); | ||
647 | if (drv->advise_release && --core->active_ref == 0) | 644 | if (drv->advise_release && --core->active_ref == 0) |
648 | { | 645 | { |
649 | drv->advise_release(drv); | 646 | drv->advise_release(drv); |
650 | core->active_type_id = CX88_BOARD_NONE; | 647 | core->active_type_id = CX88_BOARD_NONE; |
651 | mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); | 648 | mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO)); |
652 | } | 649 | } |
653 | mutex_unlock(&drv->core->lock); | ||
654 | 650 | ||
655 | return 0; | 651 | return 0; |
656 | } | 652 | } |