diff options
author | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2016-04-06 10:55:24 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2016-04-20 13:12:02 -0300 |
commit | e2c91d4d78ee3a69ad634bc7ef90688704baab9d (patch) | |
tree | d1476d2f4f400d54f06afdc3029f67affd4b3a2b /drivers/media/media-entity.c | |
parent | ecb7b0183a89613c154d1bea48b494907efbf8f9 (diff) | |
download | linux-e2c91d4d78ee3a69ad634bc7ef90688704baab9d.tar.gz linux-e2c91d4d78ee3a69ad634bc7ef90688704baab9d.tar.bz2 linux-e2c91d4d78ee3a69ad634bc7ef90688704baab9d.zip |
[media] media-device: get rid of the spinlock
Right now, the lock schema for media_device struct is messy,
since sometimes, it is protected via a spin lock, while, for
media graph traversal, it is protected by a mutex.
Solve this conflict by always using a mutex.
As a side effect, this prevents a bug when the media notifiers
is called at atomic context, while running the notifier callback:
BUG: sleeping function called from invalid context at mm/slub.c:1289
in_atomic(): 1, irqs_disabled(): 0, pid: 3479, name: modprobe
4 locks held by modprobe/3479:
#0: (&dev->mutex){......}, at: [<ffffffff81ce8933>] __driver_attach+0xa3/0x160
#1: (&dev->mutex){......}, at: [<ffffffff81ce8941>] __driver_attach+0xb1/0x160
#2: (register_mutex#5){+.+.+.}, at: [<ffffffffa10596c7>] usb_audio_probe+0x257/0x1c90 [snd_usb_audio]
#3: (&(&mdev->lock)->rlock){+.+.+.}, at: [<ffffffffa0e6051b>] media_device_register_entity+0x1cb/0x700 [media]
CPU: 2 PID: 3479 Comm: modprobe Not tainted 4.5.0-rc3+ #49
Hardware name: /NUC5i7RYB, BIOS RYBDWi35.86A.0350.2015.0812.1722 08/12/2015
0000000000000000 ffff8803b3f6f288 ffffffff81933901 ffff8803c4bae000
ffff8803c4bae5c8 ffff8803b3f6f2b0 ffffffff811c6af5 ffff8803c4bae000
ffffffff8285d7f6 0000000000000509 ffff8803b3f6f2f0 ffffffff811c6ce5
Call Trace:
[<ffffffff81933901>] dump_stack+0x85/0xc4
[<ffffffff811c6af5>] ___might_sleep+0x245/0x3a0
[<ffffffff811c6ce5>] __might_sleep+0x95/0x1a0
[<ffffffff8155aade>] kmem_cache_alloc_trace+0x20e/0x300
[<ffffffffa0e66e3d>] ? media_add_link+0x4d/0x140 [media]
[<ffffffffa0e66e3d>] media_add_link+0x4d/0x140 [media]
[<ffffffffa0e69931>] media_create_pad_link+0xa1/0x600 [media]
[<ffffffffa0fe11b3>] au0828_media_graph_notify+0x173/0x360 [au0828]
[<ffffffffa0e68a6a>] ? media_gobj_create+0x1ba/0x480 [media]
[<ffffffffa0e606fb>] media_device_register_entity+0x3ab/0x700 [media]
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/media-entity.c')
-rw-r--r-- | drivers/media/media-entity.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index e95070b3a3d4..c53c1d5589a0 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -219,7 +219,7 @@ int media_entity_pads_init(struct media_entity *entity, u16 num_pads, entity->pads = pads; if (mdev) - spin_lock(&mdev->lock); + mutex_lock(&mdev->graph_mutex); for (i = 0; i < num_pads; i++) { pads[i].entity = entity; @@ -230,7 +230,7 @@ int media_entity_pads_init(struct media_entity *entity, u16 num_pads, } if (mdev) - spin_unlock(&mdev->lock); + mutex_unlock(&mdev->graph_mutex); return 0; } @@ -747,9 +747,9 @@ void media_entity_remove_links(struct media_entity *entity) if (mdev == NULL) return; - spin_lock(&mdev->lock); + mutex_lock(&mdev->graph_mutex); __media_entity_remove_links(entity); - spin_unlock(&mdev->lock); + mutex_unlock(&mdev->graph_mutex); } EXPORT_SYMBOL_GPL(media_entity_remove_links); @@ -951,9 +951,9 @@ void media_remove_intf_link(struct media_link *link) if (mdev == NULL) return; - spin_lock(&mdev->lock); + mutex_lock(&mdev->graph_mutex); __media_remove_intf_link(link); - spin_unlock(&mdev->lock); + mutex_unlock(&mdev->graph_mutex); } EXPORT_SYMBOL_GPL(media_remove_intf_link); @@ -975,8 +975,8 @@ void media_remove_intf_links(struct media_interface *intf) if (mdev == NULL) return; - spin_lock(&mdev->lock); + mutex_lock(&mdev->graph_mutex); __media_remove_intf_links(intf); - spin_unlock(&mdev->lock); + mutex_unlock(&mdev->graph_mutex); } EXPORT_SYMBOL_GPL(media_remove_intf_links); |