brcm2708: remove linux 4.4 support
[openwrt/staging/yousong.git] / target / linux / brcm2708 / patches-4.4 / 0426-vchiq_arm-Avoid-use-of-mutex-in-add_completion.patch
diff --git a/target/linux/brcm2708/patches-4.4/0426-vchiq_arm-Avoid-use-of-mutex-in-add_completion.patch b/target/linux/brcm2708/patches-4.4/0426-vchiq_arm-Avoid-use-of-mutex-in-add_completion.patch
deleted file mode 100644 (file)
index d2edccc..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-From c1aad7829f0bb4f13b6a61879361f2405eed2a9b Mon Sep 17 00:00:00 2001
-From: Phil Elwell <phil@raspberrypi.org>
-Date: Mon, 20 Jun 2016 13:51:44 +0100
-Subject: [PATCH] vchiq_arm: Avoid use of mutex in add_completion
-
-Claiming the completion_mutex within add_completion did prevent some
-messages appearing twice, but provokes a deadlock caused by vcsm using
-vchiq within a page fault handler.
-
-Revert the use of completion_mutex, and instead fix the original
-problem using more memory barriers.
-
-Signed-off-by: Phil Elwell <phil@raspberrypi.org>
----
- .../vc04_services/interface/vchiq_arm/vchiq_arm.c  | 55 +++++++++++-----------
- .../vc04_services/interface/vchiq_arm/vchiq_core.c | 14 ++++--
- 2 files changed, 37 insertions(+), 32 deletions(-)
-
---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
-+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c
-@@ -64,10 +64,10 @@
- #define VCHIQ_MINOR 0
- /* Some per-instance constants */
--#define MAX_COMPLETIONS 16
-+#define MAX_COMPLETIONS 128
- #define MAX_SERVICES 64
- #define MAX_ELEMENTS 8
--#define MSG_QUEUE_SIZE 64
-+#define MSG_QUEUE_SIZE 128
- #define KEEPALIVE_VER 1
- #define KEEPALIVE_VER_MIN KEEPALIVE_VER
-@@ -208,28 +208,24 @@ add_completion(VCHIQ_INSTANCE_T instance
-       void *bulk_userdata)
- {
-       VCHIQ_COMPLETION_DATA_T *completion;
-+      int insert;
-       DEBUG_INITIALISE(g_state.local)
--      mutex_lock(&instance->completion_mutex);
--
--      while (instance->completion_insert ==
--              (instance->completion_remove + MAX_COMPLETIONS)) {
-+      insert = instance->completion_insert;
-+      while ((insert - instance->completion_remove) >= MAX_COMPLETIONS) {
-               /* Out of space - wait for the client */
-               DEBUG_TRACE(SERVICE_CALLBACK_LINE);
-               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;
-               }
--              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;
-@@ -237,9 +233,7 @@ add_completion(VCHIQ_INSTANCE_T instance
-               DEBUG_TRACE(SERVICE_CALLBACK_LINE);
-       }
--      completion =
--               &instance->completions[instance->completion_insert &
--               (MAX_COMPLETIONS - 1)];
-+      completion = &instance->completions[insert & (MAX_COMPLETIONS - 1)];
-       completion->header = header;
-       completion->reason = reason;
-@@ -260,12 +254,9 @@ add_completion(VCHIQ_INSTANCE_T instance
-       wmb();
-       if (reason == VCHIQ_MESSAGE_AVAILABLE)
--              user_service->message_available_pos =
--                      instance->completion_insert;
--
--      instance->completion_insert++;
-+              user_service->message_available_pos = insert;
--      mutex_unlock(&instance->completion_mutex);
-+      instance->completion_insert = ++insert;
-       up(&instance->insert_event);
-@@ -795,6 +786,7 @@ vchiq_ioctl(struct file *file, unsigned
-                       instance->completion_insert)
-                       && !instance->closing) {
-                       int rc;
-+
-                       DEBUG_TRACE(AWAIT_COMPLETION_LINE);
-                       mutex_unlock(&instance->completion_mutex);
-                       rc = down_interruptible(&instance->insert_event);
-@@ -809,24 +801,29 @@ vchiq_ioctl(struct file *file, unsigned
-               }
-               DEBUG_TRACE(AWAIT_COMPLETION_LINE);
--              /* A read memory barrier is needed to stop prefetch of a stale
--              ** completion record
--              */
--              rmb();
--
-               if (ret == 0) {
-                       int msgbufcount = args.msgbufcount;
-+                      int remove;
-+
-+                      remove = instance->completion_remove;
-+
-                       for (ret = 0; ret < args.count; ret++) {
-                               VCHIQ_COMPLETION_DATA_T *completion;
-                               VCHIQ_SERVICE_T *service;
-                               USER_SERVICE_T *user_service;
-                               VCHIQ_HEADER_T *header;
--                              if (instance->completion_remove ==
--                                      instance->completion_insert)
-+
-+                              if (remove == instance->completion_insert)
-                                       break;
-+
-                               completion = &instance->completions[
--                                      instance->completion_remove &
--                                      (MAX_COMPLETIONS - 1)];
-+                                      remove & (MAX_COMPLETIONS - 1)];
-+
-+
-+                              /* A read memory barrier is needed to prevent
-+                              ** the prefetch of a stale completion record
-+                              */
-+                              rmb();
-                               service = completion->service_userdata;
-                               user_service = service->base.userdata;
-@@ -903,7 +900,11 @@ vchiq_ioctl(struct file *file, unsigned
-                                       break;
-                               }
--                              instance->completion_remove++;
-+                              /* Ensure that the above copy has completed
-+                              ** before advancing the remove pointer. */
-+                              mb();
-+
-+                              instance->completion_remove = ++remove;
-                       }
-                       if (msgbufcount != args.msgbufcount) {
---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
-+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c
-@@ -610,15 +610,15 @@ process_free_queue(VCHIQ_STATE_T *state)
-       BITSET_T service_found[BITSET_SIZE(VCHIQ_MAX_SERVICES)];
-       int slot_queue_available;
--      /* Use a read memory barrier to ensure that any state that may have
--      ** been modified by another thread is not masked by stale prefetched
--      ** values. */
--      rmb();
--
-       /* Find slots which have been freed by the other side, and return them
-       ** to the available queue. */
-       slot_queue_available = state->slot_queue_available;
-+      /* Use a memory barrier to ensure that any state that may have been
-+      ** modified by another thread is not masked by stale prefetched
-+      ** values. */
-+      mb();
-+
-       while (slot_queue_available != local->slot_queue_recycle) {
-               unsigned int pos;
-               int slot_index = local->slot_queue[slot_queue_available++ &
-@@ -626,6 +626,8 @@ process_free_queue(VCHIQ_STATE_T *state)
-               char *data = (char *)SLOT_DATA_FROM_INDEX(state, slot_index);
-               int data_found = 0;
-+              rmb();
-+
-               vchiq_log_trace(vchiq_core_log_level, "%d: pfq %d=%x %x %x",
-                       state->id, slot_index, (unsigned int)data,
-                       local->slot_queue_recycle, slot_queue_available);
-@@ -741,6 +743,8 @@ process_free_queue(VCHIQ_STATE_T *state)
-                               up(&state->data_quota_event);
-               }
-+              mb();
-+
-               state->slot_queue_available = slot_queue_available;
-               up(&state->slot_available_event);
-       }