summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNikos Nikoleris <nikos.nikoleris@arm.com>2019-11-07 10:50:36 +0000
committerNikos Nikoleris <nikos.nikoleris@arm.com>2020-01-07 09:42:01 +0000
commit96e8f2ed3c3e1cfa32677dcc32f2d0c263dd6be6 (patch)
tree731912fbb58246fe35647cdbb8b5c5f31d05e69e /src
parent3001388ae1e0c97df7223b00367ee9cec572c4c7 (diff)
downloadgem5-96e8f2ed3c3e1cfa32677dcc32f2d0c263dd6be6.tar.xz
mem-cache: Ensure that responses get data from the right source
This CL makes sure that we use the right source for data for responses after a response from the cache below. Change-Id: I7329f3e6bcb7ce2054e912eb9dea48c9d169d45a Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23667 Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/mem/cache/cache.cc45
1 files changed, 31 insertions, 14 deletions
diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc
index e7dd5efc9..a4f2baeb6 100644
--- a/src/mem/cache/cache.cc
+++ b/src/mem/cache/cache.cc
@@ -756,7 +756,14 @@ Cache::serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk)
assert(blk->isWritable());
}
- if (blk && blk->isValid() && !mshr->isForward) {
+ // Here we decide whether we will satisfy the target using
+ // data from the block or from the response. We use the
+ // block data to satisfy the request when the block is
+ // present and valid and in addition the response in not
+ // forwarding data to the cache above (we didn't fill
+ // either); otherwise we use the packet data.
+ if (blk && blk->isValid() &&
+ (!mshr->isForward || !pkt->hasData())) {
satisfyRequest(tgt_pkt, blk, true, mshr->hasPostDowngrade());
// How many bytes past the first request is this one
@@ -791,15 +798,15 @@ Cache::serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk)
pkt->payloadDelay;
tgt_pkt->req->setExtraData(0);
} else {
- // We are about to send a response to a cache above
- // that asked for an invalidation; we need to
- // invalidate our copy immediately as the most
- // up-to-date copy of the block will now be in the
- // cache above. It will also prevent this cache from
- // responding (if the block was previously dirty) to
- // snoops as they should snoop the caches above where
- // they will get the response from.
if (is_invalidate && blk && blk->isValid()) {
+ // We are about to send a response to a cache above
+ // that asked for an invalidation; we need to
+ // invalidate our copy immediately as the most
+ // up-to-date copy of the block will now be in the
+ // cache above. It will also prevent this cache from
+ // responding (if the block was previously dirty) to
+ // snoops as they should snoop the caches above where
+ // they will get the response from.
invalidateBlock(blk);
}
// not a cache fill, just forwarding response
@@ -807,12 +814,22 @@ Cache::serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk)
// from lower level cahces/memory to the core.
completion_time += clockEdge(responseLatency) +
pkt->payloadDelay;
- if (pkt->isRead() && !is_error) {
- // sanity check
- assert(pkt->matchAddr(tgt_pkt));
- assert(pkt->getSize() >= tgt_pkt->getSize());
+ if (!is_error) {
+ if (pkt->isRead()) {
+ // sanity check
+ assert(pkt->matchAddr(tgt_pkt));
+ assert(pkt->getSize() >= tgt_pkt->getSize());
- tgt_pkt->setData(pkt->getConstPtr<uint8_t>());
+ tgt_pkt->setData(pkt->getConstPtr<uint8_t>());
+ } else {
+ // MSHR targets can read data either from the
+ // block or the response pkt. If we can't get data
+ // from the block (i.e., invalid or has old data)
+ // or the response (did not bring in any data)
+ // then make sure that the target didn't expect
+ // any.
+ assert(!tgt_pkt->hasRespData());
+ }
}
// this response did not allocate here and therefore