From: Lee Hackseung Date: Thu, 10 Aug 2017 04:44:44 +0000 (+0900) Subject: Revert "vchiq_arm: Avoid use of mutex in add_completion" X-Git-Tag: submit/tizen/20170828.023313~54 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=38d37f10f792234f31535280e293524ed42e249d;p=platform%2Fkernel%2Flinux-rpi3.git Revert "vchiq_arm: Avoid use of mutex in add_completion" This reverts commit 3d17f0eb02770a2d3a0a73d3ea63b75b7b5e876c. --- diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index 5a2b8fb459eb..db44c4763790 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -64,10 +64,10 @@ #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) { diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c index 71a3bedc5531..160db24aeea3 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +++ b/drivers/staging/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,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); }