kernel: update kernel 4.9 to version 4.9.91
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.9 / 950-0098-vchiq_arm-Add-completion-records-under-the-mutex.patch
1 From 152fc9447942bad4e2c6c1e6b86fd252689cc596 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] 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 .../staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 13 ++++++++++++-
20 1 file changed, 12 insertions(+), 1 deletion(-)
21
22 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
23 +++ b/drivers/staging/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;