x86: Delay X86 table walk on receiving walker response

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.
This commit is contained in:
Andreas Hansson 2015-01-22 05:00:54 -05:00
parent f49830ce0b
commit ce12d4bc63
2 changed files with 11 additions and 3 deletions

View file

@ -124,8 +124,10 @@ Walker::recvTimingResp(PacketPtr pkt)
delete senderWalk; delete senderWalk;
// Since we block requests when another is outstanding, we // Since we block requests when another is outstanding, we
// need to check if there is a waiting request to be serviced // need to check if there is a waiting request to be serviced
if (currStates.size()) if (currStates.size() && !startWalkWrapperEvent.scheduled())
startWalkWrapper(); // delay sending any new requests until we are finished
// with the responses
schedule(startWalkWrapperEvent, clockEdge());
} }
return true; return true;
} }

View file

@ -183,6 +183,11 @@ namespace X86ISA
// Wrapper for checking for squashes before starting a translation. // Wrapper for checking for squashes before starting a translation.
void startWalkWrapper(); void startWalkWrapper();
/**
* Event used to call startWalkWrapper.
**/
EventWrapper<Walker, &Walker::startWalkWrapper> startWalkWrapperEvent;
// Functions for dealing with packets. // Functions for dealing with packets.
bool recvTimingResp(PacketPtr pkt); bool recvTimingResp(PacketPtr pkt);
void recvRetry(); void recvRetry();
@ -207,7 +212,8 @@ namespace X86ISA
MemObject(params), port(name() + ".port", this), MemObject(params), port(name() + ".port", this),
funcState(this, NULL, NULL, true), tlb(NULL), sys(params->system), funcState(this, NULL, NULL, true), tlb(NULL), sys(params->system),
masterId(sys->getMasterId(name())), masterId(sys->getMasterId(name())),
numSquashable(params->num_squash_per_cycle) numSquashable(params->num_squash_per_cycle),
startWalkWrapperEvent(this)
{ {
} }
}; };