mem: Fix event scheduling issue for prefetches
authorMitch Hayenga <mitch.hayenga@arm.com>
Tue, 23 Dec 2014 14:31:18 +0000 (09:31 -0500)
committerMitch Hayenga <mitch.hayenga@arm.com>
Tue, 23 Dec 2014 14:31:18 +0000 (09:31 -0500)
The cache's MemSidePacketQueue schedules a sendEvent based upon
nextMSHRReadyTime() which is the time when the next MSHR is ready or whenever
a future prefetch is ready.  However, a prefetch being ready does not guarentee
that it can obtain an MSHR.  So, when all MSHRs are full,
the simulation ends up unnecessiciarly scheduling a sendEvent every picosecond
until an MSHR is finally freed and the prefetch can happen.

This patch fixes this by not signaling the prefetch ready time if the prefetch
could not be generated.  The event is rescheduled as soon as a MSHR becomes
available.

src/mem/cache/cache_impl.hh

index 115e7aeb8ff384742c8287f90dea594c20a9f7df..cb02f7558d2b8264f9a516a871d66c026934077a 100644 (file)
@@ -1197,6 +1197,15 @@ Cache<TagStore>::recvTimingResp(PacketPtr pkt)
         if (wasFull && !mq->isFull()) {
             clearBlocked((BlockedCause)mq->index);
         }
+
+        // Request the bus for a prefetch if this deallocation freed enough
+        // MSHRs for a prefetch to take place
+        if (prefetcher && mq == &mshrQueue && mshrQueue.canPrefetch()) {
+            Tick next_pf_time = std::max(prefetcher->nextPrefetchReadyTime(),
+                                         curTick());
+            if (next_pf_time != MaxTick)
+                requestMemSideBus(Request_PF, next_pf_time);
+        }
     }
 
     // copy writebacks to write buffer
@@ -1955,7 +1964,9 @@ Cache<TagStore>::nextMSHRReadyTime() const
     Tick nextReady = std::min(mshrQueue.nextMSHRReadyTime(),
                               writeBuffer.nextMSHRReadyTime());
 
-    if (prefetcher) {
+    // Don't signal prefetch ready time if no MSHRs available
+    // Will signal once enoguh MSHRs are deallocated
+    if (prefetcher && mshrQueue.canPrefetch()) {
         nextReady = std::min(nextReady,
                              prefetcher->nextPrefetchReadyTime());
     }