changeset fa9ef374075f in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=fa9ef374075f
description:
        mem: Fix a bug in the cache port flow control

        This patch fixes a bug in the cache port where the retry flag was
        reset too early, allowing new requests to arrive before the retry was
        actually sent, but with the event already scheduled. This caused a
        deadlock in the interactions with the O3 LSQ.

        The patche fixes the underlying issue by shifting the resetting of the
        flag to be done by the event that also calls sendRetry(). The patch
        also tidies up the flow control in recvTimingReq and ensures that we
        also check if we already have a retry outstanding.

diffstat:

 src/mem/cache/base.cc       |  11 +++++++++--
 src/mem/cache/base.hh       |   5 ++++-
 src/mem/cache/cache_impl.hh |  27 +++++++++++++++++++--------
 3 files changed, 32 insertions(+), 11 deletions(-)

diffs (80 lines):

diff -r a1eea45928e6 -r fa9ef374075f src/mem/cache/base.cc
--- a/src/mem/cache/base.cc     Tue May 13 12:20:49 2014 -0500
+++ b/src/mem/cache/base.cc     Wed Sep 03 07:42:50 2014 -0400
@@ -106,13 +106,20 @@
     DPRINTF(CachePort, "Cache port %s accepting new requests\n", name());
     blocked = false;
     if (mustSendRetry) {
-        DPRINTF(CachePort, "Cache port %s sending retry\n", name());
-        mustSendRetry = false;
         // @TODO: need to find a better time (next bus cycle?)
         owner.schedule(sendRetryEvent, curTick() + 1);
     }
 }
 
+void
+BaseCache::CacheSlavePort::processSendRetry()
+{
+    DPRINTF(CachePort, "Cache port %s sending retry\n", name());
+
+    // reset the flag and call retry
+    mustSendRetry = false;
+    sendRetry();
+}
 
 void
 BaseCache::init()
diff -r a1eea45928e6 -r fa9ef374075f src/mem/cache/base.hh
--- a/src/mem/cache/base.hh     Tue May 13 12:20:49 2014 -0500
+++ b/src/mem/cache/base.hh     Wed Sep 03 07:42:50 2014 -0400
@@ -182,7 +182,10 @@
 
       private:
 
-        EventWrapper<SlavePort, &SlavePort::sendRetry> sendRetryEvent;
+        void processSendRetry();
+
+        EventWrapper<CacheSlavePort,
+                     &CacheSlavePort::processSendRetry> sendRetryEvent;
 
     };
 
diff -r a1eea45928e6 -r fa9ef374075f src/mem/cache/cache_impl.hh
--- a/src/mem/cache/cache_impl.hh       Tue May 13 12:20:49 2014 -0500
+++ b/src/mem/cache/cache_impl.hh       Wed Sep 03 07:42:50 2014 -0400
@@ -1937,16 +1937,27 @@
 bool
 Cache<TagStore>::CpuSidePort::recvTimingReq(PacketPtr pkt)
 {
-    // always let inhibited requests through even if blocked
-    if (!pkt->memInhibitAsserted() && blocked) {
-        assert(!cache->system->bypassCaches());
-        DPRINTF(Cache,"Scheduling a retry while blocked\n");
-        mustSendRetry = true;
-        return false;
+    assert(!cache->system->bypassCaches());
+
+    bool success = false;
+
+    // always let inhibited requests through, even if blocked
+    if (pkt->memInhibitAsserted()) {
+        // this should always succeed
+        success = cache->recvTimingReq(pkt);
+        assert(success);
+    } else if (blocked || mustSendRetry) {
+        // either already committed to send a retry, or blocked
+        success = false;
+    } else {
+        // for now this should always succeed
+        success = cache->recvTimingReq(pkt);
+        assert(success);
     }
 
-    cache->recvTimingReq(pkt);
-    return true;
+    // remember if we have to retry
+    mustSendRetry = !success;
+    return success;
 }
 
 template<class TagStore>
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to