cpu-o3: Fixed halt assertion failure
authorDaniel Gerzhoy <daniel.gerzhoy@gmail.com>
Tue, 3 Nov 2020 20:28:18 +0000 (15:28 -0500)
committerDaniel Gerzhoy <daniel.gerzhoy@gmail.com>
Fri, 4 Dec 2020 14:09:59 +0000 (14:09 +0000)
Halting the O3 CPU would cause an assertion failure because
instructions were not finished being squashed in the ROB.

Change-Id: I8b8c375d0e520861af3657249de987de2451b6f1
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/37676
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
src/cpu/o3/cpu.cc
src/cpu/o3/rob_impl.hh

index c910cc4870bf665339c4eee48c6ef8f0425ba9d2..4068b306d7159a5fed6b18a666bfd38b6525568d 100644 (file)
@@ -717,6 +717,15 @@ FullO3CPU<Impl>::haltContext(ThreadID tid)
     deactivateThread(tid);
     removeThread(tid);
 
+    // If this was the last thread then unschedule the tick event.
+    if (activeThreads.size() == 0) {
+        if (tickEvent.scheduled())
+        {
+            unscheduleTickEvent();
+        }
+        lastRunningCycle = curCycle();
+        _status = Idle;
+    }
     updateCycleCounters(BaseCPU::CPU_STATE_SLEEP);
 }
 
@@ -795,6 +804,15 @@ FullO3CPU<Impl>::removeThread(ThreadID tid)
     rename.clearStates(tid);
     iew.clearStates(tid);
 
+    // Flush out any old data from the time buffers.
+    for (int i = 0; i < timeBuffer.getSize(); ++i) {
+        timeBuffer.advance();
+        fetchQueue.advance();
+        decodeQueue.advance();
+        renameQueue.advance();
+        iewQueue.advance();
+    }
+
     // at this step, all instructions in the pipeline should be already
     // either committed successfully or squashed. All thread-specific
     // queues in the pipeline must be empty.
index d4a02b5988adc4c7f26e2e5cf1e74f96520e50fc..73c8a4bffb228f851964697304598005637f772c 100644 (file)
@@ -338,8 +338,18 @@ ROB<Impl>::doSquash(ThreadID tid)
 
     bool robTailUpdate = false;
 
+    unsigned int numInstsToSquash = squashWidth;
+
+    // If the CPU is exiting, squash all of the instructions
+    // it is told to, even if that exceeds the squashWidth.
+    // Set the number to the number of entries (the max).
+    if (cpu->isThreadExiting(tid))
+    {
+        numInstsToSquash = numEntries;
+    }
+
     for (int numSquashed = 0;
-         numSquashed < squashWidth &&
+         numSquashed < numInstsToSquash &&
          squashIt[tid] != instList[tid].end() &&
          (*squashIt[tid])->seqNum > squashedSeqNum[tid];
          ++numSquashed)