x86: Delay X86 table walk on receiving walker response
authorAndreas Hansson <andreas.hansson@arm.com>
Thu, 22 Jan 2015 10:00:54 +0000 (05:00 -0500)
committerAndreas Hansson <andreas.hansson@arm.com>
Thu, 22 Jan 2015 10:00:54 +0000 (05:00 -0500)
This patch fixes a minor issue in the X86 page table walker where it
ended up sending new request packets to the crossbar before the
response processing was finished (recvTimingResp is directly calling
sendTimingReq). Under certain conditions this caused the crossbar to
see illegal combinations of request/response overlap, in turn causing
problems with a slightly modified crossbar implementation.

src/arch/x86/pagetable_walker.cc
src/arch/x86/pagetable_walker.hh

index cc2a5099d8f00847382b988c592aad9ea20be407..81c4ccdb5e1de94feb4edae489c8778949d51117 100644 (file)
@@ -124,8 +124,10 @@ Walker::recvTimingResp(PacketPtr pkt)
         delete senderWalk;
         // Since we block requests when another is outstanding, we
         // need to check if there is a waiting request to be serviced
-        if (currStates.size())
-            startWalkWrapper();
+        if (currStates.size() && !startWalkWrapperEvent.scheduled())
+            // delay sending any new requests until we are finished
+            // with the responses
+            schedule(startWalkWrapperEvent, clockEdge());
     }
     return true;
 }
index c6766689b6a750de0620691c0f7830d0885825c6..c8ec549fe2003ee2e97ff696ede5eb755f464347 100644 (file)
@@ -183,6 +183,11 @@ namespace X86ISA
         // Wrapper for checking for squashes before starting a translation.
         void startWalkWrapper();
 
+        /**
+         * Event used to call startWalkWrapper.
+         **/
+        EventWrapper<Walker, &Walker::startWalkWrapper> startWalkWrapperEvent;
+
         // Functions for dealing with packets.
         bool recvTimingResp(PacketPtr pkt);
         void recvRetry();
@@ -207,7 +212,8 @@ namespace X86ISA
             MemObject(params), port(name() + ".port", this),
             funcState(this, NULL, NULL, true), tlb(NULL), sys(params->system),
             masterId(sys->getMasterId(name())),
-            numSquashable(params->num_squash_per_cycle)
+            numSquashable(params->num_squash_per_cycle),
+            startWalkWrapperEvent(this)
         {
         }
     };