This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/cgit.cgi/media_tree.git tree:

Subject: [media] media-device: get rid of the spinlock
Author:  Mauro Carvalho Chehab <[email protected]>
Date:    Wed Mar 16 09:04:02 2016 -0300

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]

Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Reviewed-by: Javier Martinez Canillas <[email protected]>
Acked-by: Sakari Ailus <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>

 drivers/media/media-device.c | 32 ++++++++++++++------------------
 drivers/media/media-entity.c | 16 ++++++++--------
 include/media/media-device.h |  6 +-----
 3 files changed, 23 insertions(+), 31 deletions(-)

---

http://git.linuxtv.org/cgit.cgi/media_tree.git/commit/?id=c38077d39c7eb84f031b072eab8009acfff57134
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 6e43c95629ea..c32fa15cc76e 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -90,17 +90,17 @@ static struct media_entity *find_entity(struct media_device 
*mdev, u32 id)
 
        id &= ~MEDIA_ENT_ID_FLAG_NEXT;
 
-       spin_lock(&mdev->lock);
+       mutex_lock(&mdev->graph_mutex);
 
        media_device_for_each_entity(entity, mdev) {
                if (((media_entity_id(entity) == id) && !next) ||
                    ((media_entity_id(entity) > id) && next)) {
-                       spin_unlock(&mdev->lock);
+                       mutex_unlock(&mdev->graph_mutex);
                        return entity;
                }
        }
 
-       spin_unlock(&mdev->lock);
+       mutex_unlock(&mdev->graph_mutex);
 
        return NULL;
 }
@@ -590,12 +590,12 @@ int __must_check media_device_register_entity(struct 
media_device *mdev,
        if (!ida_pre_get(&mdev->entity_internal_idx, GFP_KERNEL))
                return -ENOMEM;
 
-       spin_lock(&mdev->lock);
+       mutex_lock(&mdev->graph_mutex);
 
        ret = ida_get_new_above(&mdev->entity_internal_idx, 1,
                                &entity->internal_idx);
        if (ret < 0) {
-               spin_unlock(&mdev->lock);
+               mutex_unlock(&mdev->graph_mutex);
                return ret;
        }
 
@@ -615,9 +615,6 @@ int __must_check media_device_register_entity(struct 
media_device *mdev,
                (notify)->notify(entity, notify->notify_data);
        }
 
-       spin_unlock(&mdev->lock);
-
-       mutex_lock(&mdev->graph_mutex);
        if (mdev->entity_internal_idx_max
            >= mdev->pm_count_walk.ent_enum.idx_max) {
                struct media_entity_graph new = { .top = 0 };
@@ -680,9 +677,9 @@ void media_device_unregister_entity(struct media_entity 
*entity)
        if (mdev == NULL)
                return;
 
-       spin_lock(&mdev->lock);
+       mutex_lock(&mdev->graph_mutex);
        __media_device_unregister_entity(entity);
-       spin_unlock(&mdev->lock);
+       mutex_unlock(&mdev->graph_mutex);
 }
 EXPORT_SYMBOL_GPL(media_device_unregister_entity);
 
@@ -703,7 +700,6 @@ void media_device_init(struct media_device *mdev)
        INIT_LIST_HEAD(&mdev->pads);
        INIT_LIST_HEAD(&mdev->links);
        INIT_LIST_HEAD(&mdev->entity_notify);
-       spin_lock_init(&mdev->lock);
        mutex_init(&mdev->graph_mutex);
        ida_init(&mdev->entity_internal_idx);
 
@@ -752,9 +748,9 @@ EXPORT_SYMBOL_GPL(__media_device_register);
 int __must_check media_device_register_entity_notify(struct media_device *mdev,
                                        struct media_entity_notify *nptr)
 {
-       spin_lock(&mdev->lock);
+       mutex_lock(&mdev->graph_mutex);
        list_add_tail(&nptr->list, &mdev->entity_notify);
-       spin_unlock(&mdev->lock);
+       mutex_unlock(&mdev->graph_mutex);
        return 0;
 }
 EXPORT_SYMBOL_GPL(media_device_register_entity_notify);
@@ -771,9 +767,9 @@ static void __media_device_unregister_entity_notify(struct 
media_device *mdev,
 void media_device_unregister_entity_notify(struct media_device *mdev,
                                        struct media_entity_notify *nptr)
 {
-       spin_lock(&mdev->lock);
+       mutex_lock(&mdev->graph_mutex);
        __media_device_unregister_entity_notify(mdev, nptr);
-       spin_unlock(&mdev->lock);
+       mutex_unlock(&mdev->graph_mutex);
 }
 EXPORT_SYMBOL_GPL(media_device_unregister_entity_notify);
 
@@ -787,11 +783,11 @@ void media_device_unregister(struct media_device *mdev)
        if (mdev == NULL)
                return;
 
-       spin_lock(&mdev->lock);
+       mutex_lock(&mdev->graph_mutex);
 
        /* Check if mdev was ever registered at all */
        if (!media_devnode_is_registered(&mdev->devnode)) {
-               spin_unlock(&mdev->lock);
+               mutex_unlock(&mdev->graph_mutex);
                return;
        }
 
@@ -811,7 +807,7 @@ void media_device_unregister(struct media_device *mdev)
                kfree(intf);
        }
 
-       spin_unlock(&mdev->lock);
+       mutex_unlock(&mdev->graph_mutex);
 
        device_remove_file(&mdev->devnode.dev, &dev_attr_model);
        media_devnode_unregister(&mdev->devnode);
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);
diff --git a/include/media/media-device.h b/include/media/media-device.h
index df74cfa7da4a..0c2de97181f3 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -25,7 +25,6 @@
 
 #include <linux/list.h>
 #include <linux/mutex.h>
-#include <linux/spinlock.h>
 
 #include <media/media-devnode.h>
 #include <media/media-entity.h>
@@ -304,8 +303,7 @@ struct media_entity_notify {
  * @pads:      List of registered pads
  * @links:     List of registered links
  * @entity_notify: List of registered entity_notify callbacks
- * @lock:      Entities list lock
- * @graph_mutex: Entities graph operation lock
+ * @graph_mutex: Protects access to struct media_device data
  * @pm_count_walk: Graph walk for power state walk. Access serialised using
  *                graph_mutex.
  *
@@ -371,8 +369,6 @@ struct media_device {
        /* notify callback list invoked when a new entity is registered */
        struct list_head entity_notify;
 
-       /* Protects the graph objects creation/removal */
-       spinlock_t lock;
        /* Serializes graph operations. */
        struct mutex graph_mutex;
        struct media_entity_graph pm_count_walk;

_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to