Revamp replacement-of-upgrade handling.
--HG-- extra : convert_revision : 9bc09d8ae6d50e6dfbb4ab21514612f9aa102a2e
This commit is contained in:
parent
1b20df5607
commit
c4903e0882
4 changed files with 36 additions and 68 deletions
3
src/mem/cache/cache.hh
vendored
3
src/mem/cache/cache.hh
vendored
|
@ -136,6 +136,9 @@ class Cache : public BaseCache
|
|||
/** Prefetcher */
|
||||
BasePrefetcher *prefetcher;
|
||||
|
||||
/** Temporary cache block for occasional transitory use */
|
||||
BlkType *tempBlock;
|
||||
|
||||
/**
|
||||
* Can this cache should allocate a block on a line-sized write miss.
|
||||
*/
|
||||
|
|
36
src/mem/cache/cache_impl.hh
vendored
36
src/mem/cache/cache_impl.hh
vendored
|
@ -58,6 +58,9 @@ Cache<TagStore,Coherence>::Cache(const std::string &_name,
|
|||
doFastWrites(params.doFastWrites),
|
||||
prefetchMiss(params.prefetchMiss)
|
||||
{
|
||||
tempBlock = new BlkType();
|
||||
tempBlock->data = new uint8_t[blkSize];
|
||||
|
||||
cpuSidePort = new CpuSidePort(_name + "-cpu_side_port", this);
|
||||
memSidePort = new MemSidePort(_name + "-mem_side_port", this);
|
||||
cpuSidePort->setOtherPort(memSidePort);
|
||||
|
@ -678,11 +681,8 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr pkt)
|
|||
pkt->getAddr());
|
||||
BlkType *blk = tags->findBlock(pkt->getAddr());
|
||||
|
||||
if (!mshr->handleFill(pkt, blk)) {
|
||||
mq->markPending(mshr);
|
||||
requestMemSideBus((RequestCause)mq->index, pkt->finishTime);
|
||||
return;
|
||||
}
|
||||
// give mshr a chance to do some dirty work
|
||||
mshr->handleFill(pkt, blk);
|
||||
|
||||
PacketList writebacks;
|
||||
blk = handleFill(pkt, blk, writebacks);
|
||||
|
@ -693,6 +693,13 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr pkt)
|
|||
allocateBuffer(wbPkt, time, true);
|
||||
writebacks.pop_front();
|
||||
}
|
||||
// if we used temp block, clear it out
|
||||
if (blk == tempBlock) {
|
||||
if (blk->isDirty()) {
|
||||
allocateBuffer(writebackBlk(blk), time, true);
|
||||
}
|
||||
tags->invalidateBlk(blk);
|
||||
}
|
||||
} else {
|
||||
if (pkt->req->isUncacheable()) {
|
||||
mshr_uncacheable_lat[pkt->cmd.toInt()][0/*pkt->req->getThreadNum()*/] +=
|
||||
|
@ -764,17 +771,28 @@ Cache<TagStore,Coherence>::handleFill(PacketPtr pkt, BlkType *blk,
|
|||
Addr repl_addr = tags->regenerateBlkAddr(blk->tag, blk->set);
|
||||
MSHR *repl_mshr = mshrQueue.findMatch(repl_addr);
|
||||
if (repl_mshr) {
|
||||
repl_mshr->handleReplacement(blk, blkSize);
|
||||
}
|
||||
|
||||
// must be an outstanding upgrade request on block
|
||||
// we're about to replace...
|
||||
assert(!blk->isWritable());
|
||||
assert(repl_mshr->needsExclusive);
|
||||
// too hard to replace block with transient state;
|
||||
// just use temporary storage to complete the current
|
||||
// request and then get rid of it
|
||||
assert(!tempBlock->isValid());
|
||||
blk = tempBlock;
|
||||
tempBlock->set = tags->extractSet(addr);
|
||||
DPRINTF(Cache, "using temp block for %x\n", addr);
|
||||
} else {
|
||||
DPRINTF(Cache, "replacement: replacing %x with %x: %s\n",
|
||||
repl_addr, addr, blk->isDirty() ? "writeback" : "clean");
|
||||
repl_addr, addr,
|
||||
blk->isDirty() ? "writeback" : "clean");
|
||||
|
||||
if (blk->isDirty()) {
|
||||
// Save writeback packet for handling by caller
|
||||
writebacks.push_back(writebackBlk(blk));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blk->tag = tags->extractTag(addr);
|
||||
blk->status = coherence->getNewState(pkt);
|
||||
|
|
51
src/mem/cache/miss/mshr.cc
vendored
51
src/mem/cache/miss/mshr.cc
vendored
|
@ -76,7 +76,6 @@ MSHR::allocate(Addr _addr, int _size, PacketPtr target,
|
|||
deferredNeedsExclusive = false;
|
||||
pendingInvalidate = false;
|
||||
pendingShared = false;
|
||||
replacedPendingUpgrade = false;
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
|
@ -185,61 +184,13 @@ MSHR::promoteDeferredTargets()
|
|||
|
||||
|
||||
void
|
||||
MSHR::handleReplacement(CacheBlk *blk, int blkSize)
|
||||
{
|
||||
// must be an outstanding upgrade request on block we're about to
|
||||
// replace...
|
||||
assert(!blk->isWritable());
|
||||
assert(needsExclusive);
|
||||
replacedPendingUpgrade = true;
|
||||
|
||||
// if it's dirty, just remember what happened and allow the
|
||||
// writeback to continue. we'll reissue a ReadEx later whether
|
||||
// the upgrade succeeds or not
|
||||
if (blk->isDirty()) {
|
||||
replacedPendingUpgradeDirty = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// if not dirty, we need to save it off as it will be only valid
|
||||
// copy in system if upgrade is successful (and may need to be
|
||||
// written back then, as the current owner if any will be
|
||||
// invalidating its block)
|
||||
replacedPendingUpgradeDirty = false;
|
||||
data = new uint8_t[blkSize];
|
||||
std::memcpy(data, blk->data, blkSize);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MSHR::handleFill(Packet *pkt, CacheBlk *blk)
|
||||
{
|
||||
if (replacedPendingUpgrade) {
|
||||
// block was replaced while upgrade request was in service
|
||||
assert(pkt->cmd == MemCmd::UpgradeResp);
|
||||
assert(blk == NULL);
|
||||
assert(replacedPendingUpgrade);
|
||||
replacedPendingUpgrade = false; // reset
|
||||
if (replacedPendingUpgradeDirty) {
|
||||
// we wrote back the previous copy; just reissue as a ReadEx
|
||||
return false;
|
||||
}
|
||||
|
||||
// previous copy was not dirty, but we are now owner... fake out
|
||||
// cache by taking saved data and converting UpgradeResp to
|
||||
// ReadExResp
|
||||
assert(data);
|
||||
pkt->cmd = MemCmd::ReadExResp;
|
||||
pkt->setData(data);
|
||||
delete [] data;
|
||||
data = NULL;
|
||||
} else if (pendingShared) {
|
||||
if (pendingShared) {
|
||||
// we snooped another read while this read was in
|
||||
// service... assert shared line on its behalf
|
||||
pkt->assertShared();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
6
src/mem/cache/miss/mshr.hh
vendored
6
src/mem/cache/miss/mshr.hh
vendored
|
@ -106,9 +106,6 @@ class MSHR : public Packet::SenderState
|
|||
bool deferredNeedsExclusive;
|
||||
bool pendingInvalidate;
|
||||
bool pendingShared;
|
||||
/** Is there a pending upgrade that got replaced? */
|
||||
bool replacedPendingUpgrade;
|
||||
bool replacedPendingUpgradeDirty;
|
||||
|
||||
/** Thread number of the miss. */
|
||||
short threadNum;
|
||||
|
@ -213,8 +210,7 @@ public:
|
|||
|
||||
bool promoteDeferredTargets();
|
||||
|
||||
void handleReplacement(CacheBlk *blk, int blkSize);
|
||||
bool handleFill(Packet *pkt, CacheBlk *blk);
|
||||
void handleFill(Packet *pkt, CacheBlk *blk);
|
||||
|
||||
/**
|
||||
* Prints the contents of this MSHR to stderr.
|
||||
|
|
Loading…
Reference in a new issue