summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.4/0297-vchiq_arm-Add-completion-records-under-the-mutex.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-4.4/0297-vchiq_arm-Add-completion-records-under-the-mutex.patch')
-rw-r--r--target/linux/brcm2708/patches-4.4/0297-vchiq_arm-Add-completion-records-under-the-mutex.patch63
1 files changed, 63 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.4/0297-vchiq_arm-Add-completion-records-under-the-mutex.patch b/target/linux/brcm2708/patches-4.4/0297-vchiq_arm-Add-completion-records-under-the-mutex.patch
new file mode 100644
index 0000000000..8075b63a88
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.4/0297-vchiq_arm-Add-completion-records-under-the-mutex.patch
@@ -0,0 +1,63 @@
+From 3ea5efb1f91da877b375eccb94e1cd4517fd8638 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Thu, 21 Apr 2016 13:49:32 +0100
+Subject: [PATCH 297/423] vchiq_arm: Add completion records under the mutex
+
+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;