mem: Service only the 1st FromCPU MSHR target on ReadRespWithInv

A response to a ReadReq can either be a ReadResp or a
ReadRespWithInvalidate. As we add targets to an MSHR for a ReadReq we
assume that the response will be a ReadResp. When the response is
invalidating (ReadRespWithInvalidate) servicing more than one targets
can potentially violate the memory ordering. This change fixes the way
we handle a ReadRespWithInvalidate. When a cache receives a
ReadRespWithInvalidate we service only the first FromCPU target and
all the FromSnoop targets from the MSHR target list. The rest of the
FromCPU targets are deferred and serviced by a new request.

Change-Id: I75c30c268851987ee5f8644acb46f440b4eeeec2
Reviewed-by: Andreas Hansson <andreas.hansson@arm.com>
Reviewed-by: Stephan Diestelhorst <stephan.diestelhorst@arm.com>
This commit is contained in:
Nikos Nikoleris
2016-12-05 16:48:19 -05:00
parent d28c2906f4
commit 0bd9dfb8de
3 changed files with 83 additions and 19 deletions

View File

@@ -1330,12 +1330,10 @@ Cache::recvTimingResp(PacketPtr pkt)
int initial_offset = initial_tgt->pkt->getOffset(blkSize);
bool from_cache = false;
while (mshr->hasTargets()) {
MSHR::Target *target = mshr->getTarget();
Packet *tgt_pkt = target->pkt;
switch (target->source) {
MSHR::TargetList targets = mshr->extractServiceableTargets(pkt);
for (auto &target: targets) {
Packet *tgt_pkt = target.pkt;
switch (target.source) {
case MSHR::Target::FromCPU:
Tick completion_time;
// Here we charge on completion_time the delay of the xbar if the
@@ -1370,7 +1368,7 @@ Cache::recvTimingResp(PacketPtr pkt)
mshr->promoteWritable();
// NB: we use the original packet here and not the response!
blk = handleFill(tgt_pkt, blk, writebacks,
mshr->allocOnFill());
targets.allocOnFill);
assert(blk != nullptr);
// treat as a fill, and discard the invalidation
@@ -1400,7 +1398,7 @@ Cache::recvTimingResp(PacketPtr pkt)
assert(tgt_pkt->req->masterId() < system->maxMasters());
missLatency[tgt_pkt->cmdToIndex()][tgt_pkt->req->masterId()] +=
completion_time - target->recvTime;
completion_time - target.recvTime;
} else if (pkt->cmd == MemCmd::UpgradeFailResp) {
// failed StoreCond upgrade
assert(tgt_pkt->cmd == MemCmd::StoreCondReq ||
@@ -1462,10 +1460,8 @@ Cache::recvTimingResp(PacketPtr pkt)
break;
default:
panic("Illegal target->source enum %d\n", target->source);
panic("Illegal target->source enum %d\n", target.source);
}
mshr->popTarget();
}
maintainClusivity(from_cache, blk);