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
This commit is contained in:
parent
ff4009ac00
commit
752f1c1fe9
4 changed files with 11 additions and 17 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,12 +1485,10 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool becoming_stalled = true;
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue