From: Phil Elwell <phil@xxxxxxxxxxxxxxx> The dequeue_pending flag wasn't protected by a spinlock in the service_callback. So fix this to make it safe. Signed-off-by: Phil Elwell <phil@xxxxxxxxxxxxxxx> Signed-off-by: Stefan Wahren <stefan.wahren@xxxxxxxx> --- .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index 0525211..4f024fa 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -279,6 +279,7 @@ struct vchiq_instance_struct { USER_SERVICE_T *user_service; VCHIQ_SERVICE_T *service; VCHIQ_INSTANCE_T instance; + bool skip_completion = false; DEBUG_INITIALISE(g_state.local) DEBUG_TRACE(SERVICE_CALLBACK_LINE); @@ -345,9 +346,6 @@ struct vchiq_instance_struct { user_service->msg_queue[user_service->msg_insert & (MSG_QUEUE_SIZE - 1)] = header; user_service->msg_insert++; - spin_unlock(&msg_queue_spinlock); - - up(&user_service->insert_event); /* If there is a thread waiting in DEQUEUE_MESSAGE, or if ** there is a MESSAGE_AVAILABLE in the completion queue then @@ -356,15 +354,20 @@ struct vchiq_instance_struct { if (((user_service->message_available_pos - instance->completion_remove) >= 0) || user_service->dequeue_pending) { - DEBUG_TRACE(SERVICE_CALLBACK_LINE); user_service->dequeue_pending = 0; - return VCHIQ_SUCCESS; + skip_completion = true; } + spin_unlock(&msg_queue_spinlock); + up(&user_service->insert_event); + header = NULL; } DEBUG_TRACE(SERVICE_CALLBACK_LINE); + if (skip_completion) + return VCHIQ_SUCCESS; + return add_completion(instance, reason, header, user_service, bulk_userdata); } -- 1.7.9.5 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel