2016-12-02 10:50:26 +00:00
|
|
|
From 249ccc9a345b7641aaf276867a375cd50f41627d Mon Sep 17 00:00:00 2001
|
2016-04-24 11:03:39 +00:00
|
|
|
From: Phil Elwell <phil@raspberrypi.org>
|
|
|
|
Date: Thu, 21 Apr 2016 13:49:32 +0100
|
2016-09-10 12:54:26 +00:00
|
|
|
Subject: [PATCH] vchiq_arm: Add completion records under the mutex
|
2016-04-24 11:03:39 +00:00
|
|
|
|
|
|
|
An issue was observed when flushing openmax components
|
|
|
|
which generate a large number of messages returning
|
|
|
|
buffers to host.
|
|
|
|
|
|
|
|
We occasionally found a duplicate message from 16
|
|
|
|
messages prior, resulting in a buffer returned twice.
|
|
|
|
|
|
|
|
While only one thread adds completions, without the
|
|
|
|
mutex you don't get the protection of the automatic
|
|
|
|
memory barrier you get with synchronisation objects.
|
|
|
|
|
|
|
|
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
|
|
|
---
|
|
|
|
drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 13 ++++++++++++-
|
|
|
|
1 file changed, 12 insertions(+), 1 deletion(-)
|
|
|
|
|
|
|
|
--- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
|
|
|
|
+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
|
|
|
|
@@ -210,6 +210,8 @@ add_completion(VCHIQ_INSTANCE_T instance
|
|
|
|
VCHIQ_COMPLETION_DATA_T *completion;
|
|
|
|
DEBUG_INITIALISE(g_state.local)
|
|
|
|
|
|
|
|
+ mutex_lock(&instance->completion_mutex);
|
|
|
|
+
|
|
|
|
while (instance->completion_insert ==
|
|
|
|
(instance->completion_remove + MAX_COMPLETIONS)) {
|
|
|
|
/* Out of space - wait for the client */
|
|
|
|
@@ -217,11 +219,17 @@ add_completion(VCHIQ_INSTANCE_T instance
|
|
|
|
vchiq_log_trace(vchiq_arm_log_level,
|
|
|
|
"add_completion - completion queue full");
|
|
|
|
DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT);
|
|
|
|
+
|
|
|
|
+ mutex_unlock(&instance->completion_mutex);
|
|
|
|
if (down_interruptible(&instance->remove_event) != 0) {
|
|
|
|
vchiq_log_info(vchiq_arm_log_level,
|
|
|
|
"service_callback interrupted");
|
|
|
|
return VCHIQ_RETRY;
|
|
|
|
- } else if (instance->closing) {
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ mutex_lock(&instance->completion_mutex);
|
|
|
|
+ if (instance->closing) {
|
|
|
|
+ mutex_unlock(&instance->completion_mutex);
|
|
|
|
vchiq_log_info(vchiq_arm_log_level,
|
|
|
|
"service_callback closing");
|
|
|
|
return VCHIQ_SUCCESS;
|
|
|
|
@@ -254,8 +262,11 @@ add_completion(VCHIQ_INSTANCE_T instance
|
|
|
|
if (reason == VCHIQ_MESSAGE_AVAILABLE)
|
|
|
|
user_service->message_available_pos =
|
|
|
|
instance->completion_insert;
|
|
|
|
+
|
|
|
|
instance->completion_insert++;
|
|
|
|
|
|
|
|
+ mutex_unlock(&instance->completion_mutex);
|
|
|
|
+
|
|
|
|
up(&instance->insert_event);
|
|
|
|
|
|
|
|
return VCHIQ_SUCCESS;
|