Bladeren bron

mm-drivers: hw_fence: add check to avoid empty join hw fence

Current driver creates a join hw-fence from a fence-array, adds its
waiting client to it, and then it decides if signal the hw-fence
depending in the current state of all the child hw-fences from the
fence array.

However, if by any reason the fence-array gets all its children cleared
within it (which can happen for spec-fences failures), hw-fence driver
logic won't signal the new created join-fence.
This can lead to the creation of an empty or incomplete join-fence that
the waiting-client will be waiting-for, but won't be signaled.

Add a check to make sure that if above scenario is ever presented,
the register for wait API catches this issue and fails to register
for wait in this invalid fence.

Change-Id: If3c69405d2a3adfefd12f447257c2560b839d238
Signed-off-by: Ingrid Gallardo <[email protected]>
Ingrid Gallardo 2 jaren geleden
bovenliggende
commit
f5cc2eb42f
1 gewijzigde bestanden met toevoegingen van 17 en 0 verwijderingen
  1. 17 0
      hw_fence/src/hw_fence_drv_priv.c

+ 17 - 0
hw_fence/src/hw_fence_drv_priv.c

@@ -1072,9 +1072,16 @@ static void _cleanup_join_and_child_fences(struct hw_fence_driver_data *drv_data
 	int idx, j;
 	u64 hash = 0;
 
+	if (!array->fences)
+		goto destroy_fence;
+
 	/* cleanup the child-fences from the parent join-fence */
 	for (idx = iteration; idx >= 0; idx--) {
 		child_fence = array->fences[idx];
+		if (!child_fence) {
+			HWFNC_ERR("invalid child fence idx:%d\n", idx);
+			continue;
+		}
 
 		hw_fence_child = msm_hw_fence_find(drv_data, hw_fence_client, child_fence->context,
 			child_fence->seqno, &hash);
@@ -1113,6 +1120,7 @@ static void _cleanup_join_and_child_fences(struct hw_fence_driver_data *drv_data
 		GLOBAL_ATOMIC_STORE(drv_data, &hw_fence_child->lock, 0); /* unlock */
 	}
 
+destroy_fence:
 	/* destroy join fence */
 	_hw_fence_process_join_fence(drv_data, hw_fence_client, array, &hash_join_fence,
 		false);
@@ -1230,6 +1238,15 @@ int hw_fence_process_fence_array(struct hw_fence_driver_data *drv_data,
 		 */
 		_hw_fence_process_join_fence(drv_data, hw_fence_client, array, &hash_join_fence,
 			false);
+	} else if (!array->num_fences) {
+		/*
+		 * if we didn't signal the join-fence and the number of fences is not set in
+		 * the fence-array, then fail here, otherwise driver would create a join-fence
+		 * with no-childs that won't be signaled at all or an incomplete join-fence
+		 */
+		HWFNC_ERR("invalid fence-array ctx:%llu seqno:%llu without fences\n",
+			array->base.context, array->base.seqno);
+		goto error_array;
 	}
 
 	return ret;