mem: Ignore uncacheable MSHRs when finding matches
authorAndreas Hansson <andreas.hansson@arm.com>
Fri, 27 Mar 2015 08:56:00 +0000 (04:56 -0400)
committerAndreas Hansson <andreas.hansson@arm.com>
Fri, 27 Mar 2015 08:56:00 +0000 (04:56 -0400)
This patch changes how we search for matching MSHRs, ignoring any MSHR
that is allocated for an uncacheable access. By doing so, this patch
fixes a corner case in the MSHRs where incorrect data ended up being
copied into a (cacheable) read packet due to a first uncacheable MSHR
target of size 4, followed by a cacheable target to the same MSHR of
size 64. The latter target was filled with nonsense data.

src/mem/cache/mshr.cc
src/mem/cache/mshr_queue.cc

index 79cf7a99812eeb909020316a0ec19838da592d6e..0915df23f291ca593eae1f2d9a06909b666cd857 100644 (file)
@@ -273,6 +273,15 @@ MSHR::deallocate()
 void
 MSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order)
 {
+    // assume we'd never issue a prefetch when we've got an
+    // outstanding miss
+    assert(pkt->cmd != MemCmd::HardPFReq);
+
+    // uncacheable accesses always allocate a new MSHR, and cacheable
+    // accesses ignore any uncacheable MSHRs, thus we should never
+    // have targets addded if originally allocated uncacheable
+    assert(!_isUncacheable);
+
     // if there's a request already in service for this MSHR, we will
     // have to defer the new target until after the response if any of
     // the following are true:
@@ -283,11 +292,6 @@ MSHR::allocateTarget(PacketPtr pkt, Tick whenReady, Counter _order)
     //   getting an exclusive block back or we have already snooped
     //   another read request that will downgrade our exclusive block
     //   to shared
-
-    // assume we'd never issue a prefetch when we've got an
-    // outstanding miss
-    assert(pkt->cmd != MemCmd::HardPFReq);
-
     if (inService &&
         (!deferredTargets.empty() || hasPostInvalidate() ||
          (pkt->needsExclusive() &&
index 2b72cf3397896d1b62b85b3548c6a05b90d96e26..f8587e1f17263897b6208948632d34d764082f5f 100644 (file)
@@ -69,7 +69,13 @@ MSHR *
 MSHRQueue::findMatch(Addr blk_addr, bool is_secure) const
 {
     for (const auto& mshr : allocatedList) {
-        if (mshr->blkAddr == blk_addr && mshr->isSecure == is_secure) {
+        // we ignore any MSHRs allocated for uncacheable accesses and
+        // simply ignore them when matching, in the cache we never
+        // check for matches when adding new uncacheable entries, and
+        // we do not want normal cacheable accesses being added to an
+        // MSHR serving an uncacheable access
+        if (!mshr->isUncacheable() && mshr->blkAddr == blk_addr &&
+            mshr->isSecure == is_secure) {
             return mshr;
         }
     }
@@ -84,7 +90,8 @@ MSHRQueue::findMatches(Addr blk_addr, bool is_secure,
     assert(matches.empty());
     bool retval = false;
     for (const auto& mshr : allocatedList) {
-        if (mshr->blkAddr == blk_addr && mshr->isSecure == is_secure) {
+        if (!mshr->isUncacheable() && mshr->blkAddr == blk_addr &&
+            mshr->isSecure == is_secure) {
             retval = true;
             matches.push_back(mshr);
         }