summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/cache/base.cc27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index f087618c7..f31fbaf03 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013, 2018 ARM Limited
+ * Copyright (c) 2012-2013, 2018-2019 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
@@ -1263,6 +1263,31 @@ BaseCache::handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks,
chatty_assert(!isReadOnly, "Should never see dirty snoop response "
"in read-only cache %s\n", name());
+
+ } else if (pkt->cmd.isSWPrefetch() && pkt->needsWritable()) {
+ // All other copies of the block were invalidated and we
+ // have an exclusive copy.
+
+ // The coherence protocol assumes that if we fetched an
+ // exclusive copy of the block, we have the intention to
+ // modify it. Therefore the MSHR for the PrefetchExReq has
+ // been the point of ordering and this cache has commited
+ // to respond to snoops for the block.
+ //
+ // In most cases this is true anyway - a PrefetchExReq
+ // will be followed by a WriteReq. However, if that
+ // doesn't happen, the block is not marked as dirty and
+ // the cache doesn't respond to snoops that has committed
+ // to do so.
+ //
+ // To avoid deadlocks in cases where there is a snoop
+ // between the PrefetchExReq and the expected WriteReq, we
+ // proactively mark the block as Dirty.
+
+ blk->status |= BlkDirty;
+
+ panic_if(!isReadOnly, "Prefetch exclusive requests from read-only "
+ "cache %s\n", name());
}
}