浏览代码

Merge 662c071517b5e904af004d0624183d891df53efd on remote branch

Change-Id: I4d278359526490d5beb078c900da16c9520ecedd
Linux Build Service Account 2 年之前
父节点
当前提交
8a2b76c10d
共有 8 个文件被更改,包括 122 次插入31 次删除
  1. 4 2
      Android.mk
  2. 29 18
      msm/synx/synx.c
  3. 25 0
      msm/synx/synx_global.c
  4. 10 0
      msm/synx/synx_global.h
  5. 51 9
      msm/synx/synx_util.c
  6. 1 0
      msm/synx/synx_util.h
  7. 1 1
      pineapple.bzl
  8. 1 1
      synx_modules.bzl

+ 4 - 2
Android.mk

@@ -21,12 +21,15 @@ KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM)
 DLKM_DIR   := $(TOP)/device/qcom/common/dlkm
 
 LOCAL_PATH := $(call my-dir)
+LOCAL_MODULE_DDK_BUILD := true
+LOCAL_MODULE_KO_DIRS := msm/synx/synx-driver.ko msm/synx/ipclite.ko
 
 include $(CLEAR_VARS)
 # For incremental compilation
 LOCAL_SRC_FILES           := $(wildcard $(LOCAL_PATH)/**/*) $(wildcard $(LOCAL_PATH)/*)
 LOCAL_MODULE              := synx-driver-symvers
 LOCAL_MODULE_KBUILD_NAME  := Module.symvers
+#LOCAL_MODULE_STEM         := Module.symvers
 LOCAL_MODULE_PATH         := $(KERNEL_MODULES_OUT)
 # Include kp_module.ko in the /vendor/lib/modules (vendor.img)
 # BOARD_VENDOR_KERNEL_MODULES += $(LOCAL_MODULE_PATH)/$(LOCAL_MODULE)
@@ -37,7 +40,7 @@ include $(CLEAR_VARS)
 LOCAL_SRC_FILES   := $(wildcard $(LOCAL_PATH)/**/*) $(wildcard $(LOCAL_PATH)/*)
 $(info LOCAL_SRC_FILES = $(LOCAL_SRC_FILES))
 LOCAL_MODULE      := synx-driver.ko
-LOCAL_MODULE_KBUILD_NAME := msm/synx-driver.ko
+LOCAL_MODULE_KBUILD_NAME := msm/synx/synx-driver.ko
 LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
 include $(DLKM_DIR)/Build_external_kernelmodule.mk
 
@@ -57,7 +60,6 @@ $(info LOCAL_ADDITIONAL_DEPENDENCY = $(LOCAL_ADDITIONAL_DEPENDENCY))
 $(info LOCAL_ADDITIONAL_DEPENDENCIES = $(LOCAL_ADDITIONAL_DEPENDENCIES))
 $(info LOCAL_REQUIRED_MODULES = $(LOCAL_REQUIRED_MODULES))
 $(info DLKM_DIR = $(DLKM_DIR))
-
 include $(DLKM_DIR)/Build_external_kernelmodule.mk
 
 

+ 29 - 18
msm/synx/synx.c

@@ -550,11 +550,13 @@ void synx_signal_handler(struct work_struct *cb_dispatch)
 		idx = (IS_ERR_OR_NULL(synx_obj)) ?
 				synx_util_global_idx(h_synx) :
 				synx_obj->global_idx;
-		rc = synx_global_update_status(idx, status);
-		if (rc != SYNX_SUCCESS)
-			dprintk(SYNX_ERR,
-				"global status update of %u failed=%d\n",
-				h_synx, rc);
+		if (synx_global_get_status(idx) == SYNX_STATE_ACTIVE) {
+			rc = synx_global_update_status(idx, status);
+			if (rc != SYNX_SUCCESS)
+				dprintk(SYNX_ERR,
+					"global status update of %u failed=%d\n",
+					h_synx, rc);
+		}
 		/*
 		 * We are decrementing the reference here assuming this code will be
 		 * executed after handle is released. But in case if clients signal
@@ -562,7 +564,8 @@ void synx_signal_handler(struct work_struct *cb_dispatch)
 		 * one reference thus deleting the global idx. As of now clients cannot
 		 * signal dma fence.
 		 */
-		synx_global_put_ref(idx);
+		if (IS_ERR_OR_NULL(synx_obj))
+			synx_global_put_ref(idx);
 	}
 
 	/*
@@ -589,21 +592,21 @@ void synx_signal_handler(struct work_struct *cb_dispatch)
 	mutex_lock(&synx_obj->obj_lock);
 
 	if (signal_cb->flag & SYNX_SIGNAL_FROM_IPC) {
-		if (synx_util_is_merged_object(synx_obj)) {
+		if (synx_util_is_merged_object(synx_obj))
 			rc = synx_native_signal_merged_fence(synx_obj, status);
-			if (rc != SYNX_SUCCESS) {
-				mutex_unlock(&synx_obj->obj_lock);
-				dprintk(SYNX_ERR,
-					"failed to signal merged fence for %u failed=%d\n",
-					h_synx, rc);
-				goto fail;
-			}
-		}
 		else
 			rc = synx_native_signal_fence(synx_obj, status);
 	}
 
-	if (rc == SYNX_SUCCESS && !synx_util_is_merged_object(synx_obj))
+	if (rc != SYNX_SUCCESS) {
+		mutex_unlock(&synx_obj->obj_lock);
+		dprintk(SYNX_ERR,
+			"failed to signal fence %u with err=%d\n",
+			h_synx, rc);
+		goto fail;
+	}
+
+	if (rc == SYNX_SUCCESS)
 		rc = synx_native_signal_core(synx_obj, status,
 			(signal_cb->flag & SYNX_SIGNAL_FROM_CALLBACK) ?
 			true : false, signal_cb->ext_sync_id);
@@ -723,12 +726,15 @@ int synx_signal(struct synx_session *session, u32 h_synx, u32 status)
 		goto fail;
 	}
 
+	mutex_lock(&synx_obj->obj_lock);
+
 	if (synx_util_is_global_handle(h_synx) ||
 			synx_util_is_global_object(synx_obj))
 		rc = synx_global_update_status(
 				synx_obj->global_idx, status);
 
 	if (rc != SYNX_SUCCESS) {
+		mutex_unlock(&synx_obj->obj_lock);
 		dprintk(SYNX_ERR,
 			"[sess :%llu] status update %d failed=%d\n",
 			client->id, h_synx, rc);
@@ -744,7 +750,6 @@ int synx_signal(struct synx_session *session, u32 h_synx, u32 status)
 		rc = synx_signal_offload_job(client, synx_obj,
 				h_synx, status);
 
-	mutex_lock(&synx_obj->obj_lock);
 	rc = synx_native_signal_fence(synx_obj, status);
 	if (rc != SYNX_SUCCESS)
 		dprintk(SYNX_ERR,
@@ -1046,6 +1051,10 @@ int synx_merge(struct synx_session *session,
 		goto clean_up;
 	}
 
+	rc = synx_util_add_callback(synx_obj, *params->h_merged_obj);
+	if (rc != SYNX_SUCCESS)
+		goto clear;
+
 	rc = synx_util_init_handle(client, synx_obj,
 			params->h_merged_obj, map_entry);
 	if (rc) {
@@ -1204,7 +1213,7 @@ int synx_wait(struct synx_session *session,
 			else
 				synx_native_signal_fence(synx_obj, rc);
 			mutex_unlock(&synx_obj->obj_lock);
-			goto fail;
+			goto status;
 		}
 	}
 
@@ -1218,6 +1227,7 @@ int synx_wait(struct synx_session *session,
 		goto fail;
 	}
 
+status:
 	mutex_lock(&synx_obj->obj_lock);
 	rc = synx_util_get_object_status(synx_obj);
 	mutex_unlock(&synx_obj->obj_lock);
@@ -1437,6 +1447,7 @@ static struct synx_map_entry *synx_handle_conversion(
 			}
 		}
 	} else {
+		synx_obj->map_count++;
 		rc = synx_alloc_global_handle(h_synx);
 		if (rc == SYNX_SUCCESS) {
 			synx_obj->global_idx =

+ 25 - 0
msm/synx/synx_global.c

@@ -328,6 +328,28 @@ int synx_global_get_subscribed_cores(u32 idx, bool *cores)
 	return SYNX_SUCCESS;
 }
 
+int synx_global_fetch_handle_details(u32 idx, u32 *h_synx)
+{
+	int rc;
+	unsigned long flags;
+	struct synx_global_coredata *synx_g_obj;
+
+	if (!synx_gmem.table)
+		return -SYNX_NOMEM;
+
+	if (IS_ERR_OR_NULL(h_synx) || !synx_is_valid_idx(idx))
+		return -SYNX_INVALID;
+
+	rc = synx_gmem_lock(idx, &flags);
+	if (rc)
+		return rc;
+	synx_g_obj = &synx_gmem.table[idx];
+	*h_synx = synx_g_obj->handle;
+	synx_gmem_unlock(idx, &flags);
+
+	return SYNX_SUCCESS;
+}
+
 int synx_global_set_subscribed_core(u32 idx, enum synx_core_id id)
 {
 	int rc;
@@ -710,6 +732,9 @@ int synx_global_merge(u32 *idx_list, u32 num_list, u32 p_idx)
 	if (!synx_is_valid_idx(p_idx))
 		return -SYNX_INVALID;
 
+	if (num_list == 0)
+		return SYNX_SUCCESS;
+
 	while (j < num_list) {
 		idx = idx_list[j];
 

+ 10 - 0
msm/synx/synx_global.h

@@ -293,4 +293,14 @@ int synx_global_clean_cdsp_mem(void);
 
 int synx_global_dump_shared_memory(void);
 
+/**
+ * synx_global_fetch_handle_details - Fetches the synx handle from
+ * global shared memory.
+ *
+ * @param idx :  Global entry index whose handle is requested.
+ *
+ * @return SYNX_SUCCESS on success. Negative error on failure.
+ */
+int synx_global_fetch_handle_details(u32 idx, u32 *h_synx);
+
 #endif /* __SYNX_SHARED_MEM_H__ */

+ 51 - 9
msm/synx/synx_util.c

@@ -12,6 +12,7 @@
 #include "synx_util.h"
 
 extern void synx_external_callback(s32 sync_obj, int status, void *data);
+static u32 __fence_state(struct dma_fence *fence, bool locked);
 
 int synx_util_init_coredata(struct synx_coredata *synx_obj,
 	struct synx_create_params *params,
@@ -247,6 +248,38 @@ void synx_util_put_object(struct synx_coredata *synx_obj)
 	kref_put(&synx_obj->refcount, synx_util_destroy_coredata);
 }
 
+int synx_util_cleanup_merged_fence(struct synx_coredata *synx_obj, int status)
+{
+	struct dma_fence_array *array = NULL;
+	u32 i;
+	int rc = 0;
+
+	if (IS_ERR_OR_NULL(synx_obj) || IS_ERR_OR_NULL(synx_obj->fence))
+		return -SYNX_INVALID;
+
+	if (dma_fence_is_array(synx_obj->fence)) {
+		array = to_dma_fence_array(synx_obj->fence);
+		if (IS_ERR_OR_NULL(array))
+			return -SYNX_INVALID;
+
+		for (i = 0; i < array->num_fences; i++) {
+			if (kref_read(&array->fences[i]->refcount) == 1 &&
+				__fence_state(array->fences[i], false) == SYNX_STATE_ACTIVE) {
+				dma_fence_set_error(array->fences[i],
+					-SYNX_STATE_SIGNALED_CANCEL);
+
+				rc = dma_fence_signal(array->fences[i]);
+				if (rc)
+					dprintk(SYNX_ERR,
+						"signaling child fence %pK failed=%d\n",
+						array->fences[i], rc);
+			}
+			dma_fence_put(array->fences[i]);
+		}
+	}
+	return rc;
+}
+
 void synx_util_object_destroy(struct synx_coredata *synx_obj)
 {
 	int rc;
@@ -263,10 +296,13 @@ void synx_util_object_destroy(struct synx_coredata *synx_obj)
 	list_for_each_entry_safe(synx_cb,
 		synx_cb_temp, &synx_obj->reg_cbs_list, node) {
 		dprintk(SYNX_ERR,
-			"cleaning up callback of session %pK\n",
+			"dipatching un-released callbacks of session %pK\n",
 			synx_cb->session);
+		synx_cb->status = SYNX_STATE_SIGNALED_CANCEL;
 		list_del_init(&synx_cb->node);
-		kfree(synx_cb);
+		queue_work(synx_dev->wq_cb,
+			&synx_cb->cb_dispatch);
+		dprintk(SYNX_VERB, "dispatched callback for fence %pKn", synx_obj->fence);
 	}
 
 	for (i = 0; i < synx_obj->num_bound_synxs; i++) {
@@ -311,7 +347,10 @@ void synx_util_object_destroy(struct synx_coredata *synx_obj)
 	 */
 	if (!IS_ERR_OR_NULL(synx_obj->fence)) {
 		spin_lock_irqsave(synx_obj->fence->lock, flags);
-		if (kref_read(&synx_obj->fence->refcount) == 1 &&
+		if (synx_util_is_merged_object(synx_obj) &&
+			synx_util_get_object_status_locked(synx_obj) == SYNX_STATE_ACTIVE)
+			rc = synx_util_cleanup_merged_fence(synx_obj, -SYNX_STATE_SIGNALED_CANCEL);
+		else if (kref_read(&synx_obj->fence->refcount) == 1 &&
 				(synx_util_get_object_status_locked(synx_obj) ==
 				SYNX_STATE_ACTIVE)) {
 			// set fence error to cancel
@@ -319,12 +358,12 @@ void synx_util_object_destroy(struct synx_coredata *synx_obj)
 				-SYNX_STATE_SIGNALED_CANCEL);
 
 			rc = dma_fence_signal_locked(synx_obj->fence);
-			if (rc)
-				dprintk(SYNX_ERR,
-					"signaling fence %pK failed=%d\n",
-					synx_obj->fence, rc);
 		}
 		spin_unlock_irqrestore(synx_obj->fence->lock, flags);
+		if (rc)
+			dprintk(SYNX_ERR,
+				"signaling fence %pK failed=%d\n",
+				synx_obj->fence, rc);
 	}
 
 	dma_fence_put(synx_obj->fence);
@@ -873,6 +912,7 @@ static void synx_util_cleanup_fence(
 	unsigned long flags;
 	u32 g_status;
 	u32 f_status;
+	u32 h_synx = 0;
 
 	mutex_lock(&synx_obj->obj_lock);
 	synx_obj->map_count--;
@@ -903,6 +943,8 @@ static void synx_util_cleanup_fence(
 			if (synx_util_get_object_status_locked(synx_obj) ==
 				SYNX_STATE_ACTIVE) {
 				signal_cb->synx_obj = NULL;
+				synx_global_fetch_handle_details(synx_obj->global_idx, &h_synx);
+				signal_cb->handle = h_synx;
 				synx_obj->signal_cb =  NULL;
 				/*
 				 * release reference held by signal cb and
@@ -1363,6 +1405,8 @@ static void synx_client_cleanup(struct work_struct *dispatch)
 	struct synx_handle_coredata *curr;
 	struct hlist_node *tmp;
 
+	dprintk(SYNX_INFO, "[sess :%llu] session removed %s\n",
+		client->id, client->name);
 	/*
 	 * go over all the remaining synx obj handles
 	 * un-released from this session and remove them.
@@ -1390,8 +1434,6 @@ static void synx_client_destroy(struct kref *kref)
 		container_of(kref, struct synx_client, refcount);
 
 	hash_del(&client->node);
-	dprintk(SYNX_INFO, "[sess :%llu] session removed %s\n",
-		client->id, client->name);
 
 	INIT_WORK(&client->dispatch, synx_client_cleanup);
 	queue_work(synx_dev->wq_cleanup, &client->dispatch);

+ 1 - 0
msm/synx/synx_util.h

@@ -60,6 +60,7 @@ static inline bool synx_util_is_external_object(
 	struct synx_coredata *synx_obj)
 {
 	if (synx_obj &&
+		!(synx_obj->type & SYNX_CREATE_MERGED_FENCE) &&
 		(synx_obj->type & SYNX_CREATE_DMA_FENCE))
 		return true;
 

+ 1 - 1
pineapple.bzl

@@ -6,7 +6,7 @@ def define_pineapple():
         target = "pineapple",
         registry = synx_modules,
         modules = [
-            "synx",
+            "synx-driver",
             "ipclite",
         ],
         config_options = [

+ 1 - 1
synx_modules.bzl

@@ -6,7 +6,7 @@ synx_modules = create_module_registry([":synx_headers"])
 register_synx_module = synx_modules.register
 
 register_synx_module(
-    name = "synx",
+    name = "synx-driver",
     path = "msm",
     srcs = [
         "synx/synx.c",