cpu-o3: bugfix of rename squash when SMT

In an SMT CPU, upon a squash, the phys regs used by
mispredicted instructions can still be owned by executing
instructions in IEW. If the regs are added back to freelist
on this tick, the reg may be renamed to be used by another
SMT thread. This causes reg ownership hazard, which may
eventually freeze the CPU.

This patch delays the freelist update to avoid the hazard.

Change-Id: I993b3c7d357269f01146db61fc8a7b83a989ea45
This commit is contained in:
He, Wenjian
2023-08-05 22:09:08 +08:00
parent 4cac85cb80
commit 03c2b4692c
2 changed files with 20 additions and 2 deletions

View File

@@ -940,8 +940,11 @@ Rename::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
// previous physical register that it was renamed to.
renameMap[tid]->setEntry(hb_it->archReg, hb_it->prevPhysReg);
// Put the renamed physical register back on the free list.
freeList->addReg(hb_it->newPhysReg);
// The phys regs can still be owned by squashing but
// executing instructions in IEW at this moment. To avoid
// ownership hazard in SMT CPU, we delay the freelist update
// until they are indeed squashed in the commit stage.
freeingInProgress[tid].push_back(hb_it->newPhysReg);
}
// Notify potential listeners that the register mapping needs to be
@@ -1296,6 +1299,18 @@ Rename::checkSignalsAndUpdate(ThreadID tid)
squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
return true;
} else if (!fromCommit->commitInfo[tid].robSquashing &&
!freeingInProgress[tid].empty()) {
DPRINTF(Rename, "[tid:%i] Freeing phys regs of misspeculated "
"instructions.\n", tid);
auto reg_it = freeingInProgress[tid].cbegin();
while ( reg_it != freeingInProgress[tid].cend()){
// Put the renamed physical register back on the free list.
freeList->addReg(*reg_it);
++reg_it;
}
freeingInProgress[tid].clear();
}
if (checkStall(tid)) {

View File

@@ -359,6 +359,9 @@ class Rename
/** Free list interface. */
UnifiedFreeList *freeList;
/** Hold phys regs to be released after squash finish */
std::vector<PhysRegIdPtr> freeingInProgress[MaxThreads];
/** Pointer to the list of active threads. */
std::list<ThreadID> *activeThreads;