Skip to content

Commit 17a6500

Browse files
committed
cpu-o3: fix smt shared sbuffer
Change-Id: Icfcaf46e311e9a1d6e28df53bec101faf5627bf1
1 parent 3566e2d commit 17a6500

File tree

14 files changed

+1459
-180
lines changed

14 files changed

+1459
-180
lines changed

src/cpu/base.cc

Lines changed: 234 additions & 73 deletions
Large diffs are not rendered by default.

src/cpu/base.hh

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -139,16 +139,8 @@ struct DiffAllStates
139139
class BaseCPU : public ClockedObject
140140
{
141141
protected:
142-
struct RecentCommittedStore
143-
{
144-
bool valid = false;
145-
Addr addr = 0;
146-
size_t size = 0;
147-
InstSeqNum seq = 0;
148-
uint8_t data[16] = {};
149-
};
150-
151-
std::vector<std::deque<RecentCommittedStore>> recentCommittedStores;
142+
std::vector<uint8_t> sharedReplayCatchupBudget;
143+
std::vector<bool> syncVisibleStoreReplayArmed;
152144

153145
const unsigned IntRegIndexBase = 0;
154146
const unsigned FPRegIndexBase = 32;
@@ -756,6 +748,8 @@ class BaseCPU : public ClockedObject
756748
gem5::Addr physEffAddr;
757749
gem5::Addr effSize;
758750
uint8_t *goldenValue;
751+
uint8_t loadDiffEvidenceKind;
752+
uint8_t *loadDiffEvidenceData;
759753
uint64_t amoOldGoldenValue;
760754
// Register address causing difftest error
761755
bool errorRegsValue[diffAllNum];
@@ -789,7 +783,18 @@ class BaseCPU : public ClockedObject
789783

790784
void difftestStep(ThreadID tid, InstSeqNum seq);
791785

792-
void recordCommittedStore(ThreadID tid, const o3::DynInstPtr &inst);
786+
virtual bool findPendingStoreValue(ThreadID tid, Addr addr, size_t size,
787+
InstSeqNum seq, uint8_t *data) const
788+
{
789+
return false;
790+
}
791+
792+
virtual bool findPendingLocalStoreValue(ThreadID tid, Addr addr,
793+
size_t size, InstSeqNum seq,
794+
uint8_t *data) const
795+
{
796+
return false;
797+
}
793798

794799
inline bool difftestEnabled() const { return enableDifftest; }
795800

@@ -824,6 +829,20 @@ class BaseCPU : public ClockedObject
824829
uint8_t *getGoldenMemPtr() { return goldenMemPtr; }
825830

826831
gem5::GoldenGloablMem *goldenMemManager() { return _goldenMemManager; }
832+
void syncVisibleSharedStoreToDiffRefs(Addr paddr, size_t size,
833+
ThreadID exclude_tid =
834+
InvalidThreadID);
835+
void armSharedReplayCatchup(ThreadID tid);
836+
void armSyncVisibleStoreReplay(ThreadID tid)
837+
{
838+
syncVisibleStoreReplayArmed.at(tid) = true;
839+
}
840+
bool consumeSyncVisibleStoreReplay(ThreadID tid)
841+
{
842+
bool armed = syncVisibleStoreReplayArmed.at(tid);
843+
syncVisibleStoreReplayArmed.at(tid) = false;
844+
return armed;
845+
}
827846

828847
void checkL1DRefill(Addr paddr, const uint8_t *refill_data, size_t size);
829848
};

src/cpu/difftest.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,7 @@ void
174174
NemuProxy::initState(int coreid, uint8_t *golden_mem)
175175
{
176176
if (multiCore) {
177-
warn("Setting mhartid to %d\n", coreid);
178177
setHartId(coreid);
179-
warn("Setting gmaddr to %#lx\n", (uint64_t) golden_mem);
180178
nemuPutGmaddr(golden_mem);
181179
}
182180
}

src/cpu/o3/commit.cc

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,19 @@ Commit::takeOverFrom()
562562
rob->takeOverFrom();
563563
}
564564

565+
void
566+
Commit::activateThread(ThreadID tid)
567+
{
568+
if (commitPolicy != CommitPolicy::RoundRobin) {
569+
return;
570+
}
571+
572+
auto thread_it = std::find(priority_list.begin(), priority_list.end(), tid);
573+
if (thread_it == priority_list.end()) {
574+
priority_list.push_back(tid);
575+
}
576+
}
577+
565578
void
566579
Commit::deactivateThread(ThreadID tid)
567580
{
@@ -1001,7 +1014,6 @@ Commit::commit()
10011014
std::list<ThreadID>::iterator end = activeThreads->end();
10021015

10031016
int num_squashing_threads = 0;
1004-
10051017
while (threads != end) {
10061018
ThreadID tid = *threads++;
10071019

@@ -1212,9 +1224,9 @@ Commit::commitInsts()
12121224
continue;
12131225
}
12141226

1215-
while (num_committed < commit_width &&
1216-
num_committed_per_thread[commit_thread] <
1217-
commit_width_per_thread[commit_thread]) {
1227+
while (num_committed < commit_width &&
1228+
num_committed_per_thread[commit_thread] <
1229+
commit_width_per_thread[commit_thread]) {
12181230
// hardware transactionally memory
12191231
// If executing within a transaction,
12201232
// need to handle interrupts specially
@@ -1453,6 +1465,11 @@ Commit::commitInsts()
14531465

14541466
}
14551467

1468+
if (head_inst->isReadBarrier() ||
1469+
head_inst->isWriteBarrier()) {
1470+
cpu->armSyncVisibleStoreReplay(tid);
1471+
}
1472+
14561473
if (cpu->difftestEnabled()) {
14571474
diffInst(tid, head_inst);
14581475
}
@@ -1562,6 +1579,7 @@ Commit::commitInsts()
15621579
if (!interrupt && avoidQuiesceLiveLock &&
15631580
onInstBoundary && cpu->checkInterrupts(0))
15641581
squashAfter(tid, head_inst);
1582+
15651583
} else {
15661584
DPRINTF(Commit, "Unable to commit head instruction PC:%s "
15671585
"[tid:%i] [sn:%llu].\n",
@@ -1617,8 +1635,9 @@ Commit::diffInst(ThreadID tid, const DynInstPtr &inst) {
16171635
cpu->diffInfo.physEffAddr = inst->physEffAddr;
16181636
cpu->diffInfo.effSize = inst->effSize;
16191637
cpu->diffInfo.goldenValue = inst->getGolden();
1638+
cpu->diffInfo.loadDiffEvidenceKind = inst->loadDiffEvidenceKind();
1639+
cpu->diffInfo.loadDiffEvidenceData = inst->getLoadDiffEvidenceData();
16201640
cpu->diffInfo.amoOldGoldenValue = inst->getAmoOldGoldenValue();
1621-
cpu->recordCommittedStore(tid, inst);
16221641
cpu->difftestStep(tid, inst->seqNum);
16231642
}
16241643

@@ -1649,9 +1668,12 @@ Commit::commitHead(const DynInstPtr &head_inst, unsigned inst_num)
16491668
// Memory-ordering instructions such as sfence.vma must not execute
16501669
// until older stores are visible; otherwise page-table updates may
16511670
// race with the TLB invalidation.
1652-
if ((head_inst->isMemRef() || head_inst->isReturn() ||
1653-
head_inst->isReadBarrier() || head_inst->isWriteBarrier()) &&
1654-
(inst_num > 0 || !iewStage->flushStores(tid))) {
1671+
const bool needs_store_drain =
1672+
head_inst->isMemRef() || head_inst->isReturn() ||
1673+
head_inst->isReadBarrier() || head_inst->isWriteBarrier();
1674+
const bool stores_drained =
1675+
!needs_store_drain || iewStage->flushStores(tid, head_inst->seqNum);
1676+
if (needs_store_drain && (inst_num > 0 || !stores_drained)) {
16551677
DPRINTF(Commit,
16561678
"[tid:%i] [sn:%llu] "
16571679
"Waiting for all stores to writeback.\n",
@@ -1705,7 +1727,7 @@ Commit::commitHead(const DynInstPtr &head_inst, unsigned inst_num)
17051727

17061728
if (inst_fault != NoFault) {
17071729
traceLogInstFault(head_inst, inst_fault);
1708-
if (!iewStage->flushStores(tid) || inst_num > 0) {
1730+
if (!iewStage->flushStores(tid, head_inst->seqNum) || inst_num > 0) {
17091731
DPRINTF(Commit,
17101732
"[tid:%i] [sn:%llu] "
17111733
"Stores outstanding, fault must wait.\n",
@@ -2189,6 +2211,22 @@ Commit::getCommittingThread()
21892211
ThreadID
21902212
Commit::roundRobin()
21912213
{
2214+
for (auto it = priority_list.begin(); it != priority_list.end();) {
2215+
if (std::find(activeThreads->begin(), activeThreads->end(), *it) ==
2216+
activeThreads->end()) {
2217+
it = priority_list.erase(it);
2218+
} else {
2219+
++it;
2220+
}
2221+
}
2222+
2223+
for (ThreadID tid : *activeThreads) {
2224+
if (std::find(priority_list.begin(), priority_list.end(), tid) ==
2225+
priority_list.end()) {
2226+
priority_list.push_back(tid);
2227+
}
2228+
}
2229+
21922230
std::list<ThreadID>::iterator pri_iter = priority_list.begin();
21932231
std::list<ThreadID>::iterator end = priority_list.end();
21942232

src/cpu/o3/commit.hh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,9 @@ class Commit
280280
/** Takes over from another CPU's thread. */
281281
void takeOverFrom();
282282

283+
/** Schedules a thread for commit arbitration. */
284+
void activateThread(ThreadID tid);
285+
283286
/** Deschedules a thread from scheduling */
284287
void deactivateThread(ThreadID tid);
285288

src/cpu/o3/cpu.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,7 @@ CPU::activateThread(ThreadID tid)
657657
DPRINTF(O3CPU, "[tid:%i] Adding to active threads list\n", tid);
658658

659659
activeThreads.push_back(tid);
660+
commit.activateThread(tid);
660661
}
661662
}
662663

@@ -1561,6 +1562,7 @@ CPU::dumpInsts()
15611562
++num;
15621563
}
15631564
}
1565+
15641566
/*
15651567
void
15661568
CPU::wakeDependents(const DynInstPtr &inst)

src/cpu/o3/cpu.hh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,19 @@ class CPU : public BaseCPU
433433

434434
uint32_t getIQInsts() { return iew.getIQInsts(); }
435435

436+
bool findPendingStoreValue(ThreadID tid, Addr addr, size_t size,
437+
InstSeqNum seq, uint8_t *data) const override
438+
{
439+
return iew.findPendingStoreValue(tid, addr, size, seq, data);
440+
}
441+
442+
bool findPendingLocalStoreValue(ThreadID tid, Addr addr, size_t size,
443+
InstSeqNum seq,
444+
uint8_t *data) const override
445+
{
446+
return iew.findPendingLocalStoreValue(tid, addr, size, seq, data);
447+
}
448+
436449
/**
437450
* Return the oldest in-flight instruction sequence number.
438451
* If there are no in-flight instructions, returns the maximum value

src/cpu/o3/dyn_inst.hh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ class DynInst : public ExecContext, public RefCounted
255255

256256
bool _hasProducerStorePC = false;
257257
Addr _producerStorePC = 0;
258+
uint8_t _loadDiffEvidenceKind = 0;
259+
uint8_t _loadDiffEvidenceData[8] = {0};
258260

259261
protected:
260262
/** The result of the instruction; assumes an instruction can have many
@@ -403,6 +405,25 @@ class DynInst : public ExecContext, public RefCounted
403405
_producerStorePC = 0;
404406
}
405407

408+
void
409+
clearLoadDiffEvidence()
410+
{
411+
_loadDiffEvidenceKind = 0;
412+
memset(_loadDiffEvidenceData, 0, sizeof(_loadDiffEvidenceData));
413+
}
414+
415+
void
416+
setLoadDiffEvidence(uint8_t kind, const uint8_t *data)
417+
{
418+
panic_if(effSize > sizeof(_loadDiffEvidenceData),
419+
"Unexpected load diff evidence size %u\n", effSize);
420+
_loadDiffEvidenceKind = kind;
421+
memcpy(_loadDiffEvidenceData, data, effSize);
422+
}
423+
424+
uint8_t loadDiffEvidenceKind() const { return _loadDiffEvidenceKind; }
425+
uint8_t *getLoadDiffEvidenceData() { return _loadDiffEvidenceData; }
426+
406427
/** The thread this instruction is from. */
407428
ThreadID threadNumber = 0;
408429

src/cpu/o3/iew.hh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,23 @@ class IEW
260260
* the store queue or the store buffer to write back to.
261261
*/
262262
bool flushStores(ThreadID tid) { return ldstQueue.flushStores(tid); }
263+
bool flushStores(ThreadID tid, InstSeqNum seq_num)
264+
{
265+
return ldstQueue.flushStores(tid, seq_num);
266+
}
267+
268+
bool findPendingStoreValue(ThreadID tid, Addr addr, size_t size,
269+
InstSeqNum seq, uint8_t *data) const
270+
{
271+
return ldstQueue.findPendingStoreValue(tid, addr, size, seq, data);
272+
}
273+
274+
bool findPendingLocalStoreValue(ThreadID tid, Addr addr, size_t size,
275+
InstSeqNum seq, uint8_t *data) const
276+
{
277+
return ldstQueue.findPendingLocalStoreValue(tid, addr, size, seq,
278+
data);
279+
}
263280

264281
/** Check if we need to squash after a load/store/branch is executed. */
265282
void SquashCheckAfterExe(DynInstPtr inst);

0 commit comments

Comments
 (0)