mem-ruby: Remove DataBlk from MOESI_AMD DirectoryEntry

This protocol is using an old style where read/writes to memory were
being done by writing to a DataBlock in a DirectoryMemory entry. This
results in having multiple copies of memory, leads to stale copies in at
least one memory (usually DRAM), and require --access-backing-store in
most cases to work properly. This changeset removes all references to
getDirectoryEntry(...).DataBlk and instead forwards those reads and
writes to DRAM always.

Change-Id: If2e52151789ad82c7b55c8fa2b41c1f4e5b65994
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/57409
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Reviewed-by: Matt Sinclair <mattdsinclair@gmail.com>
Maintainer: Matt Sinclair <mattdsinclair@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Matthew Poremba
2022-03-08 10:55:14 -08:00
parent 3a950f0345
commit bfcab1258f

View File

@@ -132,7 +132,6 @@ machine(MachineType:Directory, "AMD Baseline protocol")
// DirectoryEntry
structure(Entry, desc="...", interface="AbstractCacheEntry", main="false") {
State DirectoryState, desc="Directory state";
DataBlock DataBlk, desc="data for the block";
NetDest VicDirtyIgnore, desc="VicDirty coming from whom to ignore";
}
@@ -195,16 +194,6 @@ machine(MachineType:Directory, "AMD Baseline protocol")
return dir_entry;
}
DataBlock getDataBlock(Addr addr), return_by_ref="yes" {
TBE tbe := TBEs.lookup(addr);
if (is_valid(tbe) && tbe.MemData) {
DPRINTF(RubySlicc, "Returning DataBlk from TBE %s:%s\n", addr, tbe);
return tbe.DataBlk;
}
DPRINTF(RubySlicc, "Returning DataBlk from Dir %s:%s\n", addr, getDirectoryEntry(addr));
return getDirectoryEntry(addr).DataBlk;
}
State getState(TBE tbe, CacheEntry entry, Addr addr) {
return getDirectoryEntry(addr).DirectoryState;
}
@@ -920,7 +909,13 @@ machine(MachineType:Directory, "AMD Baseline protocol")
action(d_writeDataToMemory, "d", desc="Write data to memory") {
peek(responseNetwork_in, ResponseMsg) {
getDirectoryEntry(address).DataBlk := in_msg.DataBlk;
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := in_msg.DataBlk;
}
if (tbe.Dirty == false) {
// have to update the TBE, too, because of how this
// directory deals with functional writes
@@ -966,7 +961,6 @@ machine(MachineType:Directory, "AMD Baseline protocol")
tbe.WTRequestor := in_msg.WTRequestor;
tbe.LastSender := in_msg.Requestor;
}
tbe.DataBlk := getDirectoryEntry(address).DataBlk; // Data only for WBs
tbe.Dirty := false;
if (in_msg.Type == CoherenceRequestType:WriteThrough) {
tbe.DataBlk.copyPartial(in_msg.DataBlk,in_msg.writeMask);
@@ -980,30 +974,36 @@ machine(MachineType:Directory, "AMD Baseline protocol")
}
action(dt_deallocateTBE, "dt", desc="deallocate TBE Entry") {
if (tbe.Dirty == false) {
getDirectoryEntry(address).DataBlk := tbe.DataBlk;
}
TBEs.deallocate(address);
unset_tbe();
}
action(wd_writeBackData, "wd", desc="Write back data if needed") {
if (tbe.wtData) {
getDirectoryEntry(address).DataBlk.copyPartial(tbe.DataBlk, tbe.writeMask);
} else if (tbe.atomicData) {
tbe.DataBlk.atomicPartial(getDirectoryEntry(address).DataBlk,tbe.writeMask);
getDirectoryEntry(address).DataBlk := tbe.DataBlk;
} else if (tbe.Dirty == false) {
getDirectoryEntry(address).DataBlk := tbe.DataBlk;
if (tbe.wtData || tbe.atomicData || tbe.Dirty == false) {
if (tbe.atomicData) {
tbe.DataBlk.atomicPartial(tbe.DataBlk, tbe.writeMask);
}
enqueue(memQueue_out, MemoryMsg, to_memory_controller_latency) {
out_msg.addr := address;
out_msg.Type := MemoryRequestType:MEMORY_WB;
out_msg.Sender := machineID;
out_msg.MessageSize := MessageSizeType:Writeback_Data;
out_msg.DataBlk := tbe.DataBlk;
DPRINTF(ProtocolTrace, "%s\n", out_msg);
}
}
}
action(mt_writeMemDataToTBE, "mt", desc="write Mem data to TBE") {
peek(memQueue_in, MemoryMsg) {
if (tbe.wtData == true) {
// do nothing
// Keep the write-through data based on mask, but use the memory block
// for the masked-off data.
DataBlock tmpBlk := in_msg.DataBlk;
tmpBlk.copyPartial(tbe.DataBlk, tbe.writeMask);
tbe.DataBlk := tmpBlk;
} else if (tbe.Dirty == false) {
tbe.DataBlk := getDirectoryEntry(address).DataBlk;
tbe.DataBlk := in_msg.DataBlk;
}
tbe.MemData := true;
}