mem: Always use InvalidateReq to service WriteLineReq misses

Previously, a WriteLineReq that missed in a cache would send out an
InvalidateReq if the block lookup failed or an UpgradeReq if the
block lookup succeeded but the block had sharers. This changes ensures
that a WriteLineReq always sends an InvalidateReq to invalidate all
copies of the block and satisfy the WriteLineReq.

Change-Id: I207ff5b267663abf02bc0b08aeadde69ad81be61
Reviewed-by: Andreas Hansson <andreas.hansson@arm.com>
This commit is contained in:
Nikos Nikoleris 2016-12-05 16:48:25 -05:00
parent 3172501a59
commit 78a97b1847

View file

@ -924,7 +924,13 @@ Cache::createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk,
// write miss on a shared owned block will generate a ReadExcl, // write miss on a shared owned block will generate a ReadExcl,
// which will clobber the owned copy. // which will clobber the owned copy.
const bool useUpgrades = true; const bool useUpgrades = true;
if (blkValid && useUpgrades) { if (cpu_pkt->cmd == MemCmd::WriteLineReq) {
assert(!blkValid || !blk->isWritable());
// forward as invalidate to all other caches, this gives us
// the line in Exclusive state, and invalidates all other
// copies
cmd = MemCmd::InvalidateReq;
} else if (blkValid && useUpgrades) {
// only reason to be here is that blk is read only and we need // only reason to be here is that blk is read only and we need
// it to be writable // it to be writable
assert(needsWritable); assert(needsWritable);
@ -937,11 +943,6 @@ Cache::createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk,
// where the determination the StoreCond fails is delayed due to // where the determination the StoreCond fails is delayed due to
// all caches not being on the same local bus. // all caches not being on the same local bus.
cmd = MemCmd::SCUpgradeFailReq; cmd = MemCmd::SCUpgradeFailReq;
} else if (cpu_pkt->cmd == MemCmd::WriteLineReq) {
// forward as invalidate to all other caches, this gives us
// the line in Exclusive state, and invalidates all other
// copies
cmd = MemCmd::InvalidateReq;
} else { } else {
// block is invalid // block is invalid
cmd = needsWritable ? MemCmd::ReadExReq : cmd = needsWritable ? MemCmd::ReadExReq :