Hi all
In TimingSimpleCPU copied below, I have encountered a case where
_status==IcacheWaitResponse as the core is currently waiting for a
response from the instruction cache and I see the response from the
icache about to be satisfied (1000 ticks later). At this point, I have
resumed from a checkpoint in atomic mode, switch to timingMode for 100
ticks and am now switching the core to O3. It appears that some event
is supposed to make sure the _status of the core is in running or idle
before this function is called. Upon further debugging, I notice that
the drain() function is being called in timing.cc for each of 4 cores
(in a 4 core system) and then core 0 is initially able to change state
to drained. However, CPU 1 and 3 are waiting on a nICacheReply. While
waiting, I see core0's fetch() (in timing.cc) get called which creates
a new event that prevents switch out. It appears that there is a race
condition between drain being called and switchOut that sometimes leads
to problems (with more problems happening as I go to 64 cores). Should
there be code in TimingSimpleCPU::fetch() (marked in a comment below)
that prevents this corner case from happening? Is there some other means
that prevents fetch from being called after the core has been drained?
Thanks in advance,
-Richard Strong
void
TimingSimpleCPU::switchOut()
{
assert(_status == Running || _status == Idle);
_status = SwitchedOut;
numCycles += tickToCycles(curTick - previousTick);
// If we've been scheduled to resume but are then told to switch out,
// we'll need to cancel it.
if (fetchEvent.scheduled())
deschedule(fetchEvent);
}
void
TimingSimpleCPU::fetch()
{
DPRINTF(SimpleCPU, "Fetch\n");
/* PLACE TO ADD CHECK FOR STATE DRAINED */
if (!curStaticInst || !curStaticInst->isDelayedCommit())
checkForInterrupts();
checkPcEventQueue();
bool fromRom = isRomMicroPC(thread->readMicroPC());
if (!fromRom && !curMacroStaticInst) {
Request *ifetch_req = new Request();
ifetch_req->setThreadContext(_cpuId, /* thread ID */ 0);
setupFetchRequest(ifetch_req);
thread->itb->translateTiming(ifetch_req, tc, &fetchTranslation,
BaseTLB::Execute);
} else {
_status = IcacheWaitResponse;
completeIfetch(NULL);
numCycles += tickToCycles(curTick - previousTick);
previousTick = curTick;
}
}
_______________________________________________
m5-users mailing list
[email protected]
http://m5sim.org/cgi-bin/mailman/listinfo/m5-users