From 03c2b4692c16b6a0d73a0eabd40e9e0d80ebbba3 Mon Sep 17 00:00:00 2001 From: "He, Wenjian" Date: Sat, 5 Aug 2023 22:09:08 +0800 Subject: [PATCH] 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 --- src/cpu/o3/rename.cc | 19 +++++++++++++++++-- src/cpu/o3/rename.hh | 3 +++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/cpu/o3/rename.cc b/src/cpu/o3/rename.cc index f8c305eb1c..3a78efb1b0 100644 --- a/src/cpu/o3/rename.cc +++ b/src/cpu/o3/rename.cc @@ -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)) { diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh index 61ef476501..81e63e5019 100644 --- a/src/cpu/o3/rename.hh +++ b/src/cpu/o3/rename.hh @@ -359,6 +359,9 @@ class Rename /** Free list interface. */ UnifiedFreeList *freeList; + /** Hold phys regs to be released after squash finish */ + std::vector freeingInProgress[MaxThreads]; + /** Pointer to the list of active threads. */ std::list *activeThreads;