brcm2708: update linux 4.4 patches to latest version
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.4 / 0300-vchiq_arm-Add-completion-records-under-the-mutex.patch
1 From 9b9ba43bf2cfd1bde5651f69a4f141a66dd7a012 Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.org>
3 Date: Thu, 21 Apr 2016 13:49:32 +0100
4 Subject: [PATCH 300/381] vchiq_arm: Add completion records under the mutex
5
6 An issue was observed when flushing openmax components
7 which generate a large number of messages returning
8 buffers to host.
9
10 We occasionally found a duplicate message from 16
11 messages prior, resulting in a buffer returned twice.
12
13 While only one thread adds completions, without the
14 mutex you don't get the protection of the automatic
15 memory barrier you get with synchronisation objects.
16
17 Signed-off-by: Phil Elwell <phil@raspberrypi.org>
18 ---
19 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c | 13 ++++++++++++-
20 1 file changed, 12 insertions(+), 1 deletion(-)
21
22 --- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
23 +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
24 @@ -210,6 +210,8 @@ add_completion(VCHIQ_INSTANCE_T instance
25 VCHIQ_COMPLETION_DATA_T *completion;
26 DEBUG_INITIALISE(g_state.local)
27
28 + mutex_lock(&instance->completion_mutex);
29 +
30 while (instance->completion_insert ==
31 (instance->completion_remove + MAX_COMPLETIONS)) {
32 /* Out of space - wait for the client */
33 @@ -217,11 +219,17 @@ add_completion(VCHIQ_INSTANCE_T instance
34 vchiq_log_trace(vchiq_arm_log_level,
35 "add_completion - completion queue full");
36 DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT);
37 +
38 + mutex_unlock(&instance->completion_mutex);
39 if (down_interruptible(&instance->remove_event) != 0) {
40 vchiq_log_info(vchiq_arm_log_level,
41 "service_callback interrupted");
42 return VCHIQ_RETRY;
43 - } else if (instance->closing) {
44 + }
45 +
46 + mutex_lock(&instance->completion_mutex);
47 + if (instance->closing) {
48 + mutex_unlock(&instance->completion_mutex);
49 vchiq_log_info(vchiq_arm_log_level,
50 "service_callback closing");
51 return VCHIQ_SUCCESS;
52 @@ -254,8 +262,11 @@ add_completion(VCHIQ_INSTANCE_T instance
53 if (reason == VCHIQ_MESSAGE_AVAILABLE)
54 user_service->message_available_pos =
55 instance->completion_insert;
56 +
57 instance->completion_insert++;
58
59 + mutex_unlock(&instance->completion_mutex);
60 +
61 up(&instance->insert_event);
62
63 return VCHIQ_SUCCESS;