Revert "vchiq_arm: Avoid use of mutex in add_completion"
authorLee Hackseung <lhs@dignsys.com>
Thu, 10 Aug 2017 04:44:44 +0000 (13:44 +0900)
committerJaechul Lee <jcsing.lee@samsung.com>
Fri, 18 Aug 2017 01:04:44 +0000 (10:04 +0900)
This reverts commit 3d17f0eb02770a2d3a0a73d3ea63b75b7b5e876c.

drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c

index 5a2b8fb459ebe086ec229f37b6381bdbe6f808ca..db44c4763790be9230e668ce0e45024fb3ac7563 100644 (file)
 #define VCHIQ_MINOR 0
 
 /* Some per-instance constants */
-#define MAX_COMPLETIONS 128
+#define MAX_COMPLETIONS 16
 #define MAX_SERVICES 64
 #define MAX_ELEMENTS 8
-#define MSG_QUEUE_SIZE 128
+#define MSG_QUEUE_SIZE 64
 
 #define KEEPALIVE_VER 1
 #define KEEPALIVE_VER_MIN KEEPALIVE_VER
@@ -208,24 +208,28 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason,
        void *bulk_userdata)
 {
        VCHIQ_COMPLETION_DATA_T *completion;
-       int insert;
        DEBUG_INITIALISE(g_state.local)
 
-       insert = instance->completion_insert;
-       while ((insert - instance->completion_remove) >= MAX_COMPLETIONS) {
+       mutex_lock(&instance->completion_mutex);
+
+       while (instance->completion_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;
@@ -233,7 +237,9 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason,
                DEBUG_TRACE(SERVICE_CALLBACK_LINE);
        }
 
-       completion = &instance->completions[insert & (MAX_COMPLETIONS - 1)];
+       completion =
+                &instance->completions[instance->completion_insert &
+                (MAX_COMPLETIONS - 1)];
 
        completion->header = header;
        completion->reason = reason;
@@ -254,9 +260,12 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason,
        wmb();
 
        if (reason == VCHIQ_MESSAGE_AVAILABLE)
-               user_service->message_available_pos = insert;
+               user_service->message_available_pos =
+                       instance->completion_insert;
 
-       instance->completion_insert = ++insert;
+       instance->completion_insert++;
+
+       mutex_unlock(&instance->completion_mutex);
 
        up(&instance->insert_event);
 
@@ -786,7 +795,6 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        instance->completion_insert)
                        && !instance->closing) {
                        int rc;
-
                        DEBUG_TRACE(AWAIT_COMPLETION_LINE);
                        mutex_unlock(&instance->completion_mutex);
                        rc = down_interruptible(&instance->insert_event);
@@ -801,29 +809,24 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                }
                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 (remove == instance->completion_insert)
+                               if (instance->completion_remove ==
+                                       instance->completion_insert)
                                        break;
-
                                completion = &instance->completions[
-                                       remove & (MAX_COMPLETIONS - 1)];
-
-
-                               /* A read memory barrier is needed to prevent
-                               ** the prefetch of a stale completion record
-                               */
-                               rmb();
+                                       instance->completion_remove &
+                                       (MAX_COMPLETIONS - 1)];
 
                                service = completion->service_userdata;
                                user_service = service->base.userdata;
@@ -900,11 +903,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                                        break;
                                }
 
-                               /* Ensure that the above copy has completed
-                               ** before advancing the remove pointer. */
-                               mb();
-
-                               instance->completion_remove = ++remove;
+                               instance->completion_remove++;
                        }
 
                        if (msgbufcount != args.msgbufcount) {
index 71a3bedc55314f3b22dbff40c05dedf03b5e7169..160db24aeea33a8296923501009c1f02bc41e599 100644 (file)
@@ -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,8 +626,6 @@ 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);
@@ -743,8 +741,6 @@ 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);
        }