mem: Align downstream cache packet creation in atomic and timing
This patch makes the control flow more uniform in atomic and timing, ultimately making the code easier to understand.
This commit is contained in:
parent
53d735b17e
commit
6c92ee49f1
2 changed files with 34 additions and 33 deletions
57
src/mem/cache/cache.cc
vendored
57
src/mem/cache/cache.cc
vendored
|
@ -903,30 +903,20 @@ Cache::recvTimingReq(PacketPtr pkt)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// See comment in cache.hh.
|
|
||||||
PacketPtr
|
PacketPtr
|
||||||
Cache::getBusPacket(PacketPtr cpu_pkt, CacheBlk *blk,
|
Cache::createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk,
|
||||||
bool needsWritable) const
|
bool needsWritable) const
|
||||||
{
|
{
|
||||||
|
// should never see evictions here
|
||||||
|
assert(!cpu_pkt->isEviction());
|
||||||
|
|
||||||
bool blkValid = blk && blk->isValid();
|
bool blkValid = blk && blk->isValid();
|
||||||
|
|
||||||
if (cpu_pkt->req->isUncacheable()) {
|
if (cpu_pkt->req->isUncacheable() ||
|
||||||
// note that at the point we see the uncacheable request we
|
(!blkValid && cpu_pkt->isUpgrade())) {
|
||||||
// flush any block, but there could be an outstanding MSHR,
|
// uncacheable requests and upgrades from upper-level caches
|
||||||
// and the cache could have filled again before we actually
|
// that missed completely just go through as is
|
||||||
// send out the forwarded uncacheable request (blk could thus
|
return nullptr;
|
||||||
// be non-null)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!blkValid &&
|
|
||||||
(cpu_pkt->isUpgrade() ||
|
|
||||||
cpu_pkt->isEviction())) {
|
|
||||||
// Writebacks that weren't allocated in access() and upgrades
|
|
||||||
// from upper-level caches that missed completely just go
|
|
||||||
// through.
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(cpu_pkt->needsResponse());
|
assert(cpu_pkt->needsResponse());
|
||||||
|
@ -1032,7 +1022,16 @@ Cache::recvAtomic(PacketPtr pkt)
|
||||||
if (!satisfied) {
|
if (!satisfied) {
|
||||||
// MISS
|
// MISS
|
||||||
|
|
||||||
PacketPtr bus_pkt = getBusPacket(pkt, blk, pkt->needsWritable());
|
// deal with the packets that go through the write path of
|
||||||
|
// the cache, i.e. any evictions and uncacheable writes
|
||||||
|
if (pkt->isEviction() ||
|
||||||
|
(pkt->req->isUncacheable() && pkt->isWrite())) {
|
||||||
|
lat += ticksToCycles(memSidePort->sendAtomic(pkt));
|
||||||
|
return lat * clockPeriod();
|
||||||
|
}
|
||||||
|
// only misses left
|
||||||
|
|
||||||
|
PacketPtr bus_pkt = createMissPacket(pkt, blk, pkt->needsWritable());
|
||||||
|
|
||||||
bool is_forward = (bus_pkt == NULL);
|
bool is_forward = (bus_pkt == NULL);
|
||||||
|
|
||||||
|
@ -1052,6 +1051,8 @@ Cache::recvAtomic(PacketPtr pkt)
|
||||||
|
|
||||||
lat += ticksToCycles(memSidePort->sendAtomic(bus_pkt));
|
lat += ticksToCycles(memSidePort->sendAtomic(bus_pkt));
|
||||||
|
|
||||||
|
bool is_invalidate = bus_pkt->isInvalidate();
|
||||||
|
|
||||||
// We are now dealing with the response handling
|
// We are now dealing with the response handling
|
||||||
DPRINTF(Cache, "Receive response: %s for addr %#llx (%s) in state %i\n",
|
DPRINTF(Cache, "Receive response: %s for addr %#llx (%s) in state %i\n",
|
||||||
bus_pkt->cmdString(), bus_pkt->getAddr(),
|
bus_pkt->cmdString(), bus_pkt->getAddr(),
|
||||||
|
@ -1068,12 +1069,6 @@ Cache::recvAtomic(PacketPtr pkt)
|
||||||
if (bus_pkt->isError()) {
|
if (bus_pkt->isError()) {
|
||||||
pkt->makeAtomicResponse();
|
pkt->makeAtomicResponse();
|
||||||
pkt->copyError(bus_pkt);
|
pkt->copyError(bus_pkt);
|
||||||
} else if (pkt->cmd == MemCmd::InvalidateReq) {
|
|
||||||
if (blk) {
|
|
||||||
// invalidate response to a cache that received
|
|
||||||
// an invalidate request
|
|
||||||
satisfyCpuSideRequest(pkt, blk);
|
|
||||||
}
|
|
||||||
} else if (pkt->cmd == MemCmd::WriteLineReq) {
|
} else if (pkt->cmd == MemCmd::WriteLineReq) {
|
||||||
// note the use of pkt, not bus_pkt here.
|
// note the use of pkt, not bus_pkt here.
|
||||||
|
|
||||||
|
@ -1081,6 +1076,8 @@ Cache::recvAtomic(PacketPtr pkt)
|
||||||
// the write to a whole line
|
// the write to a whole line
|
||||||
blk = handleFill(pkt, blk, writebacks,
|
blk = handleFill(pkt, blk, writebacks,
|
||||||
allocOnFill(pkt->cmd));
|
allocOnFill(pkt->cmd));
|
||||||
|
assert(blk != NULL);
|
||||||
|
is_invalidate = false;
|
||||||
satisfyCpuSideRequest(pkt, blk);
|
satisfyCpuSideRequest(pkt, blk);
|
||||||
} else if (bus_pkt->isRead() ||
|
} else if (bus_pkt->isRead() ||
|
||||||
bus_pkt->cmd == MemCmd::UpgradeResp) {
|
bus_pkt->cmd == MemCmd::UpgradeResp) {
|
||||||
|
@ -1097,6 +1094,10 @@ Cache::recvAtomic(PacketPtr pkt)
|
||||||
}
|
}
|
||||||
delete bus_pkt;
|
delete bus_pkt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_invalidate && blk && blk->isValid()) {
|
||||||
|
invalidateBlock(blk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that we don't invoke the prefetcher at all in atomic mode.
|
// Note that we don't invoke the prefetcher at all in atomic mode.
|
||||||
|
@ -2445,7 +2446,7 @@ Cache::sendMSHRQueuePacket(MSHR* mshr)
|
||||||
|
|
||||||
// either a prefetch that is not present upstream, or a normal
|
// either a prefetch that is not present upstream, or a normal
|
||||||
// MSHR request, proceed to get the packet to send downstream
|
// MSHR request, proceed to get the packet to send downstream
|
||||||
PacketPtr pkt = getBusPacket(tgt_pkt, blk, mshr->needsWritable());
|
PacketPtr pkt = createMissPacket(tgt_pkt, blk, mshr->needsWritable());
|
||||||
|
|
||||||
mshr->isForward = (pkt == NULL);
|
mshr->isForward = (pkt == NULL);
|
||||||
|
|
||||||
|
|
10
src/mem/cache/cache.hh
vendored
10
src/mem/cache/cache.hh
vendored
|
@ -460,18 +460,18 @@ class Cache : public BaseCache
|
||||||
bool invalidateVisitor(CacheBlk &blk);
|
bool invalidateVisitor(CacheBlk &blk);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate an appropriate downstream bus request packet for the
|
* Create an appropriate downstream bus request packet for the
|
||||||
* given parameters.
|
* given parameters.
|
||||||
* @param cpu_pkt The upstream request that needs to be satisfied.
|
* @param cpu_pkt The miss that needs to be satisfied.
|
||||||
* @param blk The block currently in the cache corresponding to
|
* @param blk The block currently in the cache corresponding to
|
||||||
* cpu_pkt (NULL if none).
|
* cpu_pkt (NULL if none).
|
||||||
* @param needsExclusive Indicates that an exclusive copy is required
|
* @param needsWritable Indicates that the block must be writable
|
||||||
* even if the request in cpu_pkt doesn't indicate that.
|
* even if the request in cpu_pkt doesn't indicate that.
|
||||||
* @return A new Packet containing the request, or NULL if the
|
* @return A new Packet containing the request, or NULL if the
|
||||||
* current request in cpu_pkt should just be forwarded on.
|
* current request in cpu_pkt should just be forwarded on.
|
||||||
*/
|
*/
|
||||||
PacketPtr getBusPacket(PacketPtr cpu_pkt, CacheBlk *blk,
|
PacketPtr createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk,
|
||||||
bool needsExclusive) const;
|
bool needsWritable) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the next queue entry to service, either a pending miss
|
* Return the next queue entry to service, either a pending miss
|
||||||
|
|
Loading…
Reference in a new issue