summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Reinhardt <steve.reinhardt@amd.com>2010-09-21 23:07:34 -0700
committerSteve Reinhardt <steve.reinhardt@amd.com>2010-09-21 23:07:34 -0700
commite9185363804489ce2b84d50fe77ed94f3a5f1e01 (patch)
tree548ef8a00f15252294a626b728399e4358fc672c
parent0bd9cea34063e4da737af382bb4e3e598448499a (diff)
downloadgem5-e9185363804489ce2b84d50fe77ed94f3a5f1e01.tar.xz
cache: improve coherence handling of writebacks
If we write back an exclusive copy, we now mark it as such, so the cache receiving the writeback can mark its copy as exclusive. This avoids some unnecessary upgrade requests when a cache later tries to re-acquire exclusive access to the block.
-rw-r--r--src/mem/cache/cache_impl.hh8
-rw-r--r--src/mem/packet.hh1
2 files changed, 9 insertions, 0 deletions
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 4f4d720b6..86bf79b7b 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -360,6 +360,9 @@ Cache<TagStore>::access(PacketPtr pkt, BlkType *&blk,
}
std::memcpy(blk->data, pkt->getPtr<uint8_t>(), blkSize);
blk->status |= BlkDirty;
+ if (pkt->isSupplyExclusive()) {
+ blk->status |= BlkWritable;
+ }
// nothing else to do; writeback doesn't expect response
assert(!pkt->needsResponse());
incHitCount(pkt, id);
@@ -1007,6 +1010,9 @@ Cache<TagStore>::writebackBlk(BlkType *blk)
Request *writebackReq =
new Request(tags->regenerateBlkAddr(blk->tag, blk->set), blkSize, 0);
PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback, -1);
+ if (blk->isWritable()) {
+ writeback->setSupplyExclusive();
+ }
writeback->allocate();
std::memcpy(writeback->getPtr<uint8_t>(), blk->data, blkSize);
@@ -1307,6 +1313,8 @@ Cache<TagStore>::snoopTiming(PacketPtr pkt)
pkt->assertMemInhibit();
if (!pkt->needsExclusive()) {
pkt->assertShared();
+ // the writeback is no longer the exclusive copy in the system
+ wb_pkt->clearSupplyExclusive();
} else {
// if we're not asserting the shared line, we need to
// invalidate our copy. we'll do that below as long as
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index cefb7c2ed..48b80879e 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -422,6 +422,7 @@ class Packet : public FastAlloc, public Printable
void setExpressSnoop() { flags.set(EXPRESS_SNOOP); }
bool isExpressSnoop() { return flags.isSet(EXPRESS_SNOOP); }
void setSupplyExclusive() { flags.set(SUPPLY_EXCLUSIVE); }
+ void clearSupplyExclusive() { flags.clear(SUPPLY_EXCLUSIVE); }
bool isSupplyExclusive() { return flags.isSet(SUPPLY_EXCLUSIVE); }
// Network error conditions... encapsulate them as methods since