diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc index 932eb8eefb..86f140fdc6 100644 --- a/src/arch/x86/pagetable_walker.cc +++ b/src/arch/x86/pagetable_walker.cc @@ -205,8 +205,14 @@ Walker::startWalkWrapper() std::make_shared("Squashed Inst"), currState->req, currState->tc, currState->mode); - // delete the current request - delete currState; + // delete the current request if there are no inflight packets. + // if there is something in flight, delete when the packets are + // received and inflight is zero. + if (currState->numInflight() == 0) { + delete currState; + } else { + currState->squash(); + } // check the next translation request, if it exists if (currStates.size()) @@ -597,6 +603,11 @@ Walker::WalkerState::recvPacket(PacketPtr pkt) assert(inflight); assert(state == Waiting); inflight--; + if (squashed) { + // if were were squashed, return true once inflight is zero and + // this WalkerState will be freed there. + return (inflight == 0); + } if (pkt->isRead()) { // should not have a pending read it we also had one outstanding assert(!read); @@ -678,6 +689,12 @@ Walker::WalkerState::sendPackets() } } +unsigned +Walker::WalkerState::numInflight() const +{ + return inflight; +} + bool Walker::WalkerState::isRetrying() { @@ -696,6 +713,12 @@ Walker::WalkerState::wasStarted() return started; } +void +Walker::WalkerState::squash() +{ + squashed = true; +} + void Walker::WalkerState::retry() { diff --git a/src/arch/x86/pagetable_walker.hh b/src/arch/x86/pagetable_walker.hh index 88b8147cf9..73e892471f 100644 --- a/src/arch/x86/pagetable_walker.hh +++ b/src/arch/x86/pagetable_walker.hh @@ -111,6 +111,7 @@ namespace X86ISA bool timing; bool retrying; bool started; + bool squashed; public: WalkerState(Walker * _walker, BaseTLB::Translation *_translation, const RequestPtr &_req, bool _isFunctional = false) : @@ -118,7 +119,7 @@ namespace X86ISA nextState(Ready), inflight(0), translation(_translation), functional(_isFunctional), timing(false), - retrying(false), started(false) + retrying(false), started(false), squashed(false) { } void initState(ThreadContext * _tc, BaseTLB::Mode _mode, @@ -126,10 +127,12 @@ namespace X86ISA Fault startWalk(); Fault startFunctional(Addr &addr, unsigned &logBytes); bool recvPacket(PacketPtr pkt); + unsigned numInflight() const; bool isRetrying(); bool wasStarted(); bool isTiming(); void retry(); + void squash(); std::string name() const {return walker->name();} private: