mem: Fix WriteLineReq fill behaviour
This patch fixes issues in the interactions between deferred snoops and WriteLineReq. More specifically, the patch addresses an issue where deferred snoops caused assertion failures when being serviced on the arrival of an InvalidateResp. The response packet was perceived to be invalidating, when actually it is not for the cache that sent out the original invalidation request.
This commit is contained in:
parent
5570aa9e9a
commit
012dd52dc2
11
src/mem/cache/cache.cc
vendored
11
src/mem/cache/cache.cc
vendored
|
@ -1228,7 +1228,7 @@ Cache::recvTimingResp(PacketPtr pkt)
|
||||||
|
|
||||||
// allow invalidation responses originating from write-line
|
// allow invalidation responses originating from write-line
|
||||||
// requests to be discarded
|
// requests to be discarded
|
||||||
bool discard_invalidate = false;
|
bool is_invalidate = pkt->isInvalidate();
|
||||||
|
|
||||||
// First offset for critical word first calculations
|
// First offset for critical word first calculations
|
||||||
int initial_offset = initial_tgt->pkt->getOffset(blkSize);
|
int initial_offset = initial_tgt->pkt->getOffset(blkSize);
|
||||||
|
@ -1271,7 +1271,7 @@ Cache::recvTimingResp(PacketPtr pkt)
|
||||||
// treat as a fill, and discard the invalidation
|
// treat as a fill, and discard the invalidation
|
||||||
// response
|
// response
|
||||||
is_fill = true;
|
is_fill = true;
|
||||||
discard_invalidate = true;
|
is_invalidate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_fill) {
|
if (is_fill) {
|
||||||
|
@ -1327,7 +1327,7 @@ Cache::recvTimingResp(PacketPtr pkt)
|
||||||
if (is_error)
|
if (is_error)
|
||||||
tgt_pkt->copyError(pkt);
|
tgt_pkt->copyError(pkt);
|
||||||
if (tgt_pkt->cmd == MemCmd::ReadResp &&
|
if (tgt_pkt->cmd == MemCmd::ReadResp &&
|
||||||
(pkt->isInvalidate() || mshr->hasPostInvalidate())) {
|
(is_invalidate || mshr->hasPostInvalidate())) {
|
||||||
// If intermediate cache got ReadRespWithInvalidate,
|
// If intermediate cache got ReadRespWithInvalidate,
|
||||||
// propagate that. Response should not have
|
// propagate that. Response should not have
|
||||||
// isInvalidate() set otherwise.
|
// isInvalidate() set otherwise.
|
||||||
|
@ -1353,7 +1353,7 @@ Cache::recvTimingResp(PacketPtr pkt)
|
||||||
assert(!is_error);
|
assert(!is_error);
|
||||||
// response to snoop request
|
// response to snoop request
|
||||||
DPRINTF(Cache, "processing deferred snoop...\n");
|
DPRINTF(Cache, "processing deferred snoop...\n");
|
||||||
assert(!(pkt->isInvalidate() && !mshr->hasPostInvalidate()));
|
assert(!(is_invalidate && !mshr->hasPostInvalidate()));
|
||||||
handleSnoop(tgt_pkt, blk, true, true, mshr->hasPostInvalidate());
|
handleSnoop(tgt_pkt, blk, true, true, mshr->hasPostInvalidate());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1368,8 +1368,7 @@ Cache::recvTimingResp(PacketPtr pkt)
|
||||||
// an invalidate response stemming from a write line request
|
// an invalidate response stemming from a write line request
|
||||||
// should not invalidate the block, so check if the
|
// should not invalidate the block, so check if the
|
||||||
// invalidation should be discarded
|
// invalidation should be discarded
|
||||||
if ((pkt->isInvalidate() || mshr->hasPostInvalidate()) &&
|
if (is_invalidate || mshr->hasPostInvalidate()) {
|
||||||
!discard_invalidate) {
|
|
||||||
assert(blk != tempBlock);
|
assert(blk != tempBlock);
|
||||||
tags->invalidate(blk);
|
tags->invalidate(blk);
|
||||||
blk->invalidate();
|
blk->invalidate();
|
||||||
|
|
Loading…
Reference in a new issue