summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
authorMitch Hayenga <mitch.hayenga@arm.com>2016-07-21 17:19:16 +0100
committerMitch Hayenga <mitch.hayenga@arm.com>2016-07-21 17:19:16 +0100
commit752f1c1fe9e74ebb0d373276b332b3242e589208 (patch)
tree66681f689812f3bba1b8c5f9b1cd301fe5490310 /src/cpu
parentff4009ac005be0347015f8ba5a8e37a3aa930e69 (diff)
downloadgem5-752f1c1fe9e74ebb0d373276b332b3242e589208.tar.xz
cpu: Fix Minor SMT WFI/drain interaction issues
The behavior of WFI is to cause minor to cease evaluating pipeline logic until an interrupt is observed, however a user may wish to drain the system while a core is sleeping due to a WFI. This patch makes WFI drain. If an actual drain occurs during a WFI, the CPU is already drained and will immediately be ready for swapping, checkpointing, etc. This should not negatively impact performance as WFI instructions are 'stream-changing' (treated like unpredicted branches), so all remaining instructions are wrong-path and will be squashed rapidly. Change-Id: I63833d5acb53d8dde78f9f0c9611de0ece385e45
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/minor/decode.cc3
-rw-r--r--src/cpu/minor/execute.cc20
-rw-r--r--src/cpu/minor/fetch1.cc2
-rw-r--r--src/cpu/minor/fetch2.cc3
4 files changed, 11 insertions, 17 deletions
diff --git a/src/cpu/minor/decode.cc b/src/cpu/minor/decode.cc
index 6243bca01..a8a33d989 100644
--- a/src/cpu/minor/decode.cc
+++ b/src/cpu/minor/decode.cc
@@ -313,8 +313,7 @@ Decode::getScheduledThread()
}
for (auto tid : priority_list) {
- if (cpu.getContext(tid)->status() == ThreadContext::Active &&
- getInput(tid) && !decodeInfo[tid].blocked) {
+ if (getInput(tid) && !decodeInfo[tid].blocked) {
threadPriority = tid;
return tid;
}
diff --git a/src/cpu/minor/execute.cc b/src/cpu/minor/execute.cc
index b13e0c020..f5f006733 100644
--- a/src/cpu/minor/execute.cc
+++ b/src/cpu/minor/execute.cc
@@ -559,10 +559,11 @@ Execute::issue(ThreadID thread_id)
} else if (cpu.getContext(thread_id)->status() ==
ThreadContext::Suspended)
{
- DPRINTF(MinorExecute, "Not issuing inst: %s from suspended"
+ DPRINTF(MinorExecute, "Discarding inst: %s from suspended"
" thread\n", *inst);
- issued = false;
+ issued = true;
+ discarded = true;
} else if (inst->id.streamSeqNum != thread.streamSeqNum) {
DPRINTF(MinorExecute, "Discarding inst: %s as its stream"
" state was unexpected, expected: %d\n",
@@ -880,9 +881,8 @@ Execute::commitInst(MinorDynInstPtr inst, bool early_memory_issue,
if (thread->status() == ThreadContext::Suspended &&
!isInterrupted(thread_id))
{
- DPRINTF(MinorExecute, "Not committing inst from suspended thread"
- " inst: %s\n", *inst);
- completed_inst = false;
+ panic("We should never hit the case where we try to commit from a "
+ "suspended thread as the streamSeqNum should not match");
} else if (inst->isFault()) {
ExecContext context(cpu, *cpu.threads[thread_id], *this, inst);
@@ -1485,9 +1485,7 @@ Execute::evaluate()
if (inst->isFault()) {
can_issue_next = true;
} else if (!inst->isBubble()) {
- if (cpu.getContext(tid)->status() != ThreadContext::Suspended) {
- next_issuable_insts.push_back(inst);
- }
+ next_issuable_insts.push_back(inst);
}
}
}
@@ -1741,8 +1739,7 @@ Execute::getIssuingThread()
}
for (auto tid : priority_list) {
- if (cpu.getContext(tid)->status() == ThreadContext::Active &&
- getInput(tid)) {
+ if (getInput(tid)) {
issuePriority = tid;
return tid;
}
@@ -1823,8 +1820,7 @@ Execute::isDrained()
return false;
for (ThreadID tid = 0; tid < cpu.numThreads; tid++) {
- if (executeInfo[tid].drainState != DrainAllInsts ||
- !inputBuffer[tid].empty() ||
+ if (!inputBuffer[tid].empty() ||
!executeInfo[tid].inFlightInsts->empty()) {
return false;
diff --git a/src/cpu/minor/fetch1.cc b/src/cpu/minor/fetch1.cc
index f4f120534..f47f54962 100644
--- a/src/cpu/minor/fetch1.cc
+++ b/src/cpu/minor/fetch1.cc
@@ -734,7 +734,7 @@ Fetch1::isDrained()
(numInFlightFetches() == 0 ? "" : "inFlightFetches "),
((*out.inputWire).isBubble() ? "" : "outputtingLine"));
- drained = drained && thread.state == FetchHalted;
+ drained = drained && (thread.state != FetchRunning);
}
return drained;
diff --git a/src/cpu/minor/fetch2.cc b/src/cpu/minor/fetch2.cc
index ae02b1c22..394fe8549 100644
--- a/src/cpu/minor/fetch2.cc
+++ b/src/cpu/minor/fetch2.cc
@@ -563,8 +563,7 @@ Fetch2::getScheduledThread()
}
for (auto tid : priority_list) {
- if (cpu.getContext(tid)->status() == ThreadContext::Active &&
- getInput(tid) && !fetchInfo[tid].blocked) {
+ if (getInput(tid) && !fetchInfo[tid].blocked) {
threadPriority = tid;
return tid;
}