mem: Transition away from isSupplyExclusive for writebacks
This patch changes how writebacks communicate whether the line is passed as modified or owned. Previously we relied on the isSupplyExclusive mechanism, which was originally designed to avoid unecessary snoops. For normal cache requests we use the sharedAsserted mechanism to determine if a block should be marked writeable or not, and with this patch we transition the writebacks to also use this mechanism. Conceptually this is cleaner and more consistent.
This commit is contained in:
parent
5902e29e84
commit
5a18e181ff
2 changed files with 14 additions and 6 deletions
19
src/mem/cache/cache_impl.hh
vendored
19
src/mem/cache/cache_impl.hh
vendored
|
@ -400,7 +400,9 @@ Cache::access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
blk->status |= BlkDirty;
|
blk->status |= BlkDirty;
|
||||||
if (pkt->isSupplyExclusive()) {
|
// if shared is not asserted we got the writeback in modified
|
||||||
|
// state, if it is asserted we are in the owned state
|
||||||
|
if (!pkt->sharedAsserted()) {
|
||||||
blk->status |= BlkWritable;
|
blk->status |= BlkWritable;
|
||||||
}
|
}
|
||||||
// nothing else to do; writeback doesn't expect response
|
// nothing else to do; writeback doesn't expect response
|
||||||
|
@ -1475,8 +1477,14 @@ Cache::writebackBlk(CacheBlk *blk)
|
||||||
|
|
||||||
PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback);
|
PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback);
|
||||||
if (blk->isWritable()) {
|
if (blk->isWritable()) {
|
||||||
writeback->setSupplyExclusive();
|
// not asserting shared means we pass the block in modified
|
||||||
|
// state, mark our own block non-writeable
|
||||||
|
blk->status &= ~BlkWritable;
|
||||||
|
} else {
|
||||||
|
// we are in the owned state, tell the receiver
|
||||||
|
writeback->assertShared();
|
||||||
}
|
}
|
||||||
|
|
||||||
writeback->allocate();
|
writeback->allocate();
|
||||||
std::memcpy(writeback->getPtr<uint8_t>(), blk->data, blkSize);
|
std::memcpy(writeback->getPtr<uint8_t>(), blk->data, blkSize);
|
||||||
|
|
||||||
|
@ -1998,9 +2006,10 @@ Cache::recvTimingSnoopReq(PacketPtr pkt)
|
||||||
pkt->assertMemInhibit();
|
pkt->assertMemInhibit();
|
||||||
if (!pkt->needsExclusive()) {
|
if (!pkt->needsExclusive()) {
|
||||||
pkt->assertShared();
|
pkt->assertShared();
|
||||||
// the writeback is no longer the exclusive copy in
|
// the writeback is no longer passing exclusivity (the
|
||||||
// the system
|
// receiving cache should consider the block owned
|
||||||
wb_pkt->clearSupplyExclusive();
|
// rather than modified)
|
||||||
|
wb_pkt->assertShared();
|
||||||
} else {
|
} else {
|
||||||
// if we're not asserting the shared line, we need to
|
// if we're not asserting the shared line, we need to
|
||||||
// invalidate our copy. we'll do that below as long as
|
// invalidate our copy. we'll do that below as long as
|
||||||
|
|
|
@ -500,7 +500,6 @@ class Packet : public Printable
|
||||||
void setExpressSnoop() { flags.set(EXPRESS_SNOOP); }
|
void setExpressSnoop() { flags.set(EXPRESS_SNOOP); }
|
||||||
bool isExpressSnoop() const { return flags.isSet(EXPRESS_SNOOP); }
|
bool isExpressSnoop() const { return flags.isSet(EXPRESS_SNOOP); }
|
||||||
void setSupplyExclusive() { flags.set(SUPPLY_EXCLUSIVE); }
|
void setSupplyExclusive() { flags.set(SUPPLY_EXCLUSIVE); }
|
||||||
void clearSupplyExclusive() { flags.clear(SUPPLY_EXCLUSIVE); }
|
|
||||||
bool isSupplyExclusive() const { return flags.isSet(SUPPLY_EXCLUSIVE); }
|
bool isSupplyExclusive() const { return flags.isSet(SUPPLY_EXCLUSIVE); }
|
||||||
void setSuppressFuncError() { flags.set(SUPPRESS_FUNC_ERROR); }
|
void setSuppressFuncError() { flags.set(SUPPRESS_FUNC_ERROR); }
|
||||||
bool suppressFuncError() const { return flags.isSet(SUPPRESS_FUNC_ERROR); }
|
bool suppressFuncError() const { return flags.isSet(SUPPRESS_FUNC_ERROR); }
|
||||||
|
|
Loading…
Reference in a new issue