changeset f02f3b6562d5 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=f02f3b6562d5
description:
        x86: Squash outstanding walks when instructions are squashed.
        This is the x86 version of the ARM changeset baa17ba80e06. In case an
        instruction has been squashed by the o3 cpu, this patch allows page
        table walker to avoid carrying out a pending translation that the
        instruction requested for.

diffstat:

 src/arch/x86/X86TLB.py           |   2 ++
 src/arch/x86/pagetable_walker.cc |  37 ++++++++++++++++++++++++++++++++-----
 src/arch/x86/pagetable_walker.hh |  10 +++++++++-
 3 files changed, 43 insertions(+), 6 deletions(-)

diffs (100 lines):

diff -r 2ea56473f400 -r f02f3b6562d5 src/arch/x86/X86TLB.py
--- a/src/arch/x86/X86TLB.py    Tue May 21 11:34:41 2013 -0500
+++ b/src/arch/x86/X86TLB.py    Tue May 21 11:40:11 2013 -0500
@@ -47,6 +47,8 @@
     cxx_header = 'arch/x86/pagetable_walker.hh'
     port = MasterPort("Port for the hardware table walker")
     system = Param.System(Parent.any, "system object")
+    num_squash_per_cycle = Param.Unsigned(4,
+            "Number of outstanding walks that can be squashed per cycle")
 
 class X86TLB(BaseTLB):
     type = 'X86TLB'
diff -r 2ea56473f400 -r f02f3b6562d5 src/arch/x86/pagetable_walker.cc
--- a/src/arch/x86/pagetable_walker.cc  Tue May 21 11:34:41 2013 -0500
+++ b/src/arch/x86/pagetable_walker.cc  Tue May 21 11:40:11 2013 -0500
@@ -139,11 +139,8 @@
         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()) {
-            WalkerState * newState = currStates.front();
-            if (!newState->wasStarted())
-                newState->startWalk();
-        }
+        if (currStates.size())
+            startWalkWrapper();
     }
     return true;
 }
@@ -192,6 +189,36 @@
     timing = _isTiming;
 }
 
+void
+Walker::startWalkWrapper()
+{
+    unsigned num_squashed = 0;
+    WalkerState *currState = currStates.front();
+    while ((num_squashed < numSquashable) && currState &&
+        currState->translation->squashed()) {
+        currStates.pop_front();
+        num_squashed++;
+
+        DPRINTF(PageTableWalker, "Squashing table walk for address %#x\n",
+            currState->req->getVaddr());
+
+        // finish the translation which will delete the translation object
+        currState->translation->finish(new UnimpFault("Squashed Inst"),
+                currState->req, currState->tc, currState->mode);
+
+        // delete the current request
+        delete currState;
+
+        // check the next translation request, if it exists
+        if (currStates.size())
+            currState = currStates.front();
+        else
+            currState = NULL;
+    }
+    if (currState && !currState->wasStarted())
+        currState->startWalk();
+}
+
 Fault
 Walker::WalkerState::startWalk()
 {
diff -r 2ea56473f400 -r f02f3b6562d5 src/arch/x86/pagetable_walker.hh
--- a/src/arch/x86/pagetable_walker.hh  Tue May 21 11:34:41 2013 -0500
+++ b/src/arch/x86/pagetable_walker.hh  Tue May 21 11:40:11 2013 -0500
@@ -87,6 +87,7 @@
         // State to track each walk of the page table
         class WalkerState
         {
+          friend class Walker;
           private:
             enum State {
                 Ready,
@@ -176,6 +177,12 @@
         System * sys;
         MasterID masterId;
 
+        // The number of outstanding walks that can be squashed per cycle.
+        unsigned numSquashable;
+
+        // Wrapper for checking for squashes before starting a translation.
+        void startWalkWrapper();
+
         // Functions for dealing with packets.
         bool recvTimingResp(PacketPtr pkt);
         void recvRetry();
@@ -199,7 +206,8 @@
         Walker(const Params *params) :
             MemObject(params), port(name() + ".port", this),
             funcState(this, NULL, NULL, true), tlb(NULL), sys(params->system),
-            masterId(sys->getMasterId(name()))
+            masterId(sys->getMasterId(name())),
+            numSquashable(params->num_squash_per_cycle)
         {
         }
     };
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to