[Cbe-oss-dev] [PATCH 08/22]MARS/base: waiting block search fix

Yuji Mano yuji.mano at am.sony.com
Fri Mar 20 07:54:10 EST 2009


From: Kazunori Asayama <asayama at sm.sony.co.jp>

Avoid block after processing waiting blocks.

The current scheduler has possibility to block forever after waiting
block is processed, since the static variable 'queue_header' is
overwritten in the 'update_header_bits' function. This patch fixes the
problem by retrying the search in that case.

This also reduces number of locks while processing waiting blocks.

Signed-off-by: Kazunori Asayama <asayama at sm.sony.co.jp>
Signed-off-by: Yuji Mano <yuji.mano at am.sony.com>
---
 base/src/mpu/kernel/kernel.c |   63 +++++++++++++++++++++++--------------------
 1 file changed, 35 insertions(+), 28 deletions(-)

--- a/base/src/mpu/kernel/kernel.c
+++ b/base/src/mpu/kernel/kernel.c
@@ -704,8 +704,7 @@ static int search_block(int block, int r
 					MARS_BITS_SET(bits, WORKLOAD_STATE,
 						MARS_WORKLOAD_STATE_READY);
 
-					/* update queue header bits */
-					update_header_bits(block);
+					index = i;
 				}
 			/* waiting for signal so check signal bit and reset */
 			} else if (signal == MARS_WORKLOAD_SIGNAL_ON) {
@@ -714,37 +713,43 @@ static int search_block(int block, int r
 				MARS_BITS_SET(bits, WORKLOAD_STATE,
 					      MARS_WORKLOAD_STATE_READY);
 
-				/* update queue header bits */
-				update_header_bits(block);
+				index = i;
 			}
 		}
 	}
 
 	/* index is set so reserve the runnable workload */
 	if (index >= 0) {
-		/* update the current state of the workload */
-		MARS_BITS_SET(&queue_block.bits[index], WORKLOAD_STATE,
-			      MARS_WORKLOAD_STATE_RUNNING);
-
-		/* reset the counter for reserved workload */
-		MARS_BITS_SET(&queue_block.bits[index], WORKLOAD_COUNTER,
-			      MARS_WORKLOAD_COUNTER_MIN);
-
-		/* check if this kernel ran this workload most recently */
-		workload_is_cached =
-			(workload_id ==
-				MARS_WORKLOAD_PER_BLOCK * block + index) &&
-			(kernel_params.kernel_id ==
-				MARS_BITS_GET(&queue_block.bits[index],
-					      WORKLOAD_KERNEL_ID));
-
-		/* set the kernel id of this kernel into block bits */
-		MARS_BITS_SET(&queue_block.bits[index], WORKLOAD_KERNEL_ID,
-			      kernel_params.kernel_id);
+		if (ready) {
+			/* update the current state of the workload */
+			MARS_BITS_SET(&queue_block.bits[index],
+				      WORKLOAD_STATE,
+				      MARS_WORKLOAD_STATE_RUNNING);
+
+			/* reset the counter for reserved workload */
+			MARS_BITS_SET(&queue_block.bits[index],
+				      WORKLOAD_COUNTER,
+				      MARS_WORKLOAD_COUNTER_MIN);
+
+			/* check if kernel ran this workload most recently */
+			workload_is_cached =
+				(workload_id ==
+				 MARS_WORKLOAD_PER_BLOCK * block + index) &&
+				(kernel_params.kernel_id ==
+				 MARS_BITS_GET(&queue_block.bits[index],
+					       WORKLOAD_KERNEL_ID));
+
+			/* set the kernel id of this kernel into block bits */
+			MARS_BITS_SET(&queue_block.bits[index],
+				      WORKLOAD_KERNEL_ID,
+				      kernel_params.kernel_id);
 
-		/* update queue header bits and reset block counter */
+			/* reset block counter */
+			update_header_bits_counter(block, 1);
+		}
+
+		/* update queue header bits */
 		update_header_bits(block);
-		update_header_bits_counter(block, 1);
 	}
 
 	/* unlock the queue block */
@@ -768,7 +773,8 @@ static int workload_reserve(void)
 {
 	int i;
 	int block = -1;
-	int index = -1;
+	int index;
+	int retry = 0;
 	uint8_t max_block_priority = 0;
 	uint16_t max_block_counter = 0;
 
@@ -806,12 +812,13 @@ static int workload_reserve(void)
 
 		/* block is waiting so check block */
 		if (block_waiting)
-			search_block(i, 0);
+			retry |= (search_block(i, 0) >= 0);
 	}
 
 	/* no runnable workload found */
 	if (block < 0)
-		return MARS_KERNEL_STATUS_IDLE;
+		return retry ?
+			MARS_KERNEL_STATUS_RETRY : MARS_KERNEL_STATUS_IDLE;
 
 	/* search block for workload index to run */
 	index = search_block(block, 1);






More information about the cbe-oss-dev mailing list