mem-cache: masked writes are not whole-line writes

We now explicitly check in both the cache and the MSHRs if writes are
masked or not before promoting to a whole-line write. Failure to do
this previously was resulting in data loss when dirty data was present
in lower level caches and a coincidentally aligned and
cache-line-sized masked write occured.

Change-Id: I9434590d8b22e4d993167d789eb9d15a2e866bf1
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/64340
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Sascha Bischoff
2022-08-03 17:11:30 +01:00
committed by Giacomo Travaglini
parent befa5baa78
commit dd6595bf56
2 changed files with 4 additions and 2 deletions

View File

@@ -140,6 +140,7 @@ MSHR::TargetList::updateWriteFlags(PacketPtr pkt)
Request::MEM_SWAP_COND | Request::SECURE | Request::LOCKED_RMW;
const auto &req_flags = pkt->req->getFlags();
bool compat_write = !req_flags.isSet(no_merge_flags);
bool masked_write = pkt->isMaskedWrite();
// if this is the first write, it might be a whole
// line write and even if we can't merge any
@@ -147,7 +148,7 @@ MSHR::TargetList::updateWriteFlags(PacketPtr pkt)
// it as a whole line write (e.g., SECURE whole line
// write)
bool first_write = empty();
if (first_write || compat_write) {
if (!masked_write && (first_write || compat_write)) {
auto offset = pkt->getOffset(blkSize);
auto begin = writesBitmap.begin() + offset;
std::fill(begin, begin + pkt->getSize(), true);

View File

@@ -625,7 +625,8 @@ class Packet : public Printable
bool isWholeLineWrite(unsigned blk_size)
{
return (cmd == MemCmd::WriteReq || cmd == MemCmd::WriteLineReq) &&
getOffset(blk_size) == 0 && getSize() == blk_size;
getOffset(blk_size) == 0 && getSize() == blk_size &&
!isMaskedWrite();
}
//@{