From: Dave Stevenson <dave.steven...@raspberrypi.org>

commit 8dedab2903f152aa3cee9ae3d57c828dea0d356e upstream.

The commit "staging: bcm2835-camera: Replace open-coded idr with a struct idr."
replaced an internal implementation of an idr with the standard functions
and a spinlock. idr_alloc(GFP_KERNEL) can sleep whilst calling kmem_cache_alloc
to allocate the new node, but this is not valid whilst in an atomic context
due to the spinlock.

There is no need for this to be a spinlock as a standard mutex is
sufficient.

Fixes: 950fd867c635 ("staging: bcm2835-camera: Replace open-coded idr with a 
struct idr.")
Signed-off-by: Dave Stevenson <dave.steven...@raspberrypi.org>
Signed-off-by: Stefan Wahren <wahre...@gmx.net>
Acked-by: Hans Verkuil <hverkuil-ci...@xs4all.nl>
Acked-by: Mauro Carvalho Chehab <mchehab+sams...@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
@@ -161,7 +161,8 @@ struct vchiq_mmal_instance {
        void *bulk_scratch;
 
        struct idr context_map;
-       spinlock_t context_map_lock;
+       /* protect accesses to context_map */
+       struct mutex context_map_lock;
 
        /* component to use next */
        int component_idx;
@@ -184,10 +185,10 @@ get_msg_context(struct vchiq_mmal_instan
         * that when we service the VCHI reply, we can look up what
         * message is being replied to.
         */
-       spin_lock(&instance->context_map_lock);
+       mutex_lock(&instance->context_map_lock);
        handle = idr_alloc(&instance->context_map, msg_context,
                           0, 0, GFP_KERNEL);
-       spin_unlock(&instance->context_map_lock);
+       mutex_unlock(&instance->context_map_lock);
 
        if (handle < 0) {
                kfree(msg_context);
@@ -211,9 +212,9 @@ release_msg_context(struct mmal_msg_cont
 {
        struct vchiq_mmal_instance *instance = msg_context->instance;
 
-       spin_lock(&instance->context_map_lock);
+       mutex_lock(&instance->context_map_lock);
        idr_remove(&instance->context_map, msg_context->handle);
-       spin_unlock(&instance->context_map_lock);
+       mutex_unlock(&instance->context_map_lock);
        kfree(msg_context);
 }
 
@@ -1849,7 +1850,7 @@ int vchiq_mmal_init(struct vchiq_mmal_in
 
        instance->bulk_scratch = vmalloc(PAGE_SIZE);
 
-       spin_lock_init(&instance->context_map_lock);
+       mutex_init(&instance->context_map_lock);
        idr_init_base(&instance->context_map, 1);
 
        params.callback_param = instance;


Reply via email to