Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpu: Don't change to suspend if the thread status is halted #1039

Merged
merged 1 commit into from May 16, 2024

Conversation

rogerchang23424
Copy link
Contributor

In our gem5 model, there are four types represent thread context: Active, Suspend, Halting and Halted

enum Status
{
/// Running. Instructions should be executed only when
/// the context is in this state.
Active,
/// Temporarily inactive. Entered while waiting for
/// synchronization, etc.
Suspended,
/// Trying to exit and waiting for an event to completely exit.
/// Entered when target executes an exit syscall.
Halting,
/// Permanently shut down. Entered when target executes
/// m5exit pseudo-instruction. When all contexts enter
/// this state, the simulation will terminate.
Halted
};

When initializing the gem5 instance, all of the thread contexts are set Halted. The status of thread context will not be active until the Workload initializes start up, except the StubWorkload. So if the user uses the StubWorkload, and the CPU is connected with the model_reset port. The thread context of the CPU will be activated possibly.

The following is the steps of activating thread context of the CPU without Workload[1] initialization or lower model_reset port[2].

  1. Raise the model_reset port (Change the state from Halted to Suspend)

    gem5/src/cpu/base.cc

    Lines 671 to 673 in 5641c5e

    if (state) {
    // As we enter reset, stop execution.
    tc->quiesce();

  2. Post the interrupt to CPU (Change the state from Suspend to Active)

    gem5/src/cpu/base.cc

    Lines 231 to 239 in 5641c5e

    BaseCPU::postInterrupt(ThreadID tid, int int_num, int index)
    {
    interrupts[tid]->post(int_num, index);
    // Only wake up syscall emulation if it is not waiting on a futex.
    // This is to model the fact that instructions such as ARM SEV
    // should wake up a WFE sleep, but not a futex syscall WAIT.
    if (FullSystem || !system->futexMap.is_waiting(threadContexts[tid]))
    wakeup(tid);
    }

Implementation of wakeup

SimpleCPU:

gem5/src/cpu/simple/base.cc

Lines 251 to 259 in 5641c5e

BaseSimpleCPU::wakeup(ThreadID tid)
{
getCpuAddrMonitor(tid)->gotWakeup = true;
if (threadInfo[tid]->thread->status() == ThreadContext::Suspended) {
DPRINTF(Quiesce,"[tid:%d] Suspended Processor awoke\n", tid);
threadInfo[tid]->thread->activate();
}
}

MinorCPU:

gem5/src/cpu/minor/cpu.cc

Lines 143 to 151 in 5641c5e

MinorCPU::wakeup(ThreadID tid)
{
DPRINTF(Drain, "[tid:%d] MinorCPU wakeup\n", tid);
assert(tid < numThreads);
if (threads[tid]->status() == ThreadContext::Suspended) {
threads[tid]->activate();
}
}

O3CPU:

gem5/src/cpu/o3/cpu.cc

Lines 1337 to 1346 in 5641c5e

CPU::wakeup(ThreadID tid)
{
if (thread[tid]->status() != gem5::ThreadContext::Suspended)
return;
wakeCPU();
DPRINTF(Quiesce, "Suspended Processor woken\n");
threadContexts[tid]->activate();
}

This CL fixed the issue when raising the model reset port to CPU(let CPU sleep) if the CPU is not activated by workload. If the CPU status is halted, it's should not change to Suspend to avoid wake up

Reference

The model_reset is introduced in the CL:
https://gem5-review.googlesource.com/c/public/gem5/+/67574/4

[1] Activate by workload (ARM example):

FsWorkload::initState()
{
KernelWorkload::initState();
// Reset CP15?? What does that mean -- ali
// FPEXC.EN = 0
for (auto *tc: system->threads) {
Reset().invoke(tc);
tc->activate();
}
auto *arm_sys = dynamic_cast<ArmSystem *>(system);

[2] Lower the model_reset:

gem5/src/cpu/base.cc

Lines 191 to 192 in 5641c5e

modelResetPort.onChange([this](const bool &new_val) {
setReset(new_val);

gem5/src/cpu/base.cc

Lines 674 to 685 in 5641c5e

} else {
// As we leave reset, first reset thread state,
tc->getIsaPtr()->resetThread();
// reset the decoder in case it had partially decoded something,
tc->getDecoderPtr()->reset();
// flush the TLBs,
tc->getMMUPtr()->flushAll();
// Clear any interrupts,
interrupts[tc->threadId()]->clearAll();
// and finally reenable execution.
tc->activate();
}

Change-Id: I5bfc0b7491d14369fff77b98b71c0ac763fb7c42

@giactra giactra self-requested a review April 22, 2024 15:16
@ivanaamit ivanaamit added the cpu General gem5 CPU code (e.g., `BaseCPU`) label Apr 22, 2024
In our gem5 model, there are four types represent thread context:
Active, Suspend, Halting and Halted

https://github.com/gem5/gem5/blob/5641c5e4642f7d44651f783bdb018d3cf8ba01b5/src/cpu/thread_context.hh#L99-L117

When initializing the gem5 instance, all of the thread contexts are set Halted. The status of thread context will not be active until the Workload initializes start up, except the StubWorkload. So if the user uses the StubWorkload, and the CPU is connected with the model_reset port. The thread context of the CPU will be activated possibly.

The following is the steps of activating thread context of the CPU without Workload[1] initialization or lower model_reset port[2].

1. Raise the model_reset port (Change the state from Halted to Suspend)
https://github.com/gem5/gem5/blob/5641c5e4642f7d44651f783bdb018d3cf8ba01b5/src/cpu/base.cc#L671-L673

2. Post the interrupt to CPU (Change the state from Suspend to Active)
https://github.com/gem5/gem5/blob/5641c5e4642f7d44651f783bdb018d3cf8ba01b5/src/cpu/base.cc#L231-L239

Implementation of wakeup

SimpleCPU:
https://github.com/gem5/gem5/blob/5641c5e4642f7d44651f783bdb018d3cf8ba01b5/src/cpu/simple/base.cc#L251-L259

MinorCPU:
https://github.com/gem5/gem5/blob/5641c5e4642f7d44651f783bdb018d3cf8ba01b5/src/cpu/minor/cpu.cc#L143-L151

O3CPU:
https://github.com/gem5/gem5/blob/5641c5e4642f7d44651f783bdb018d3cf8ba01b5/src/cpu/o3/cpu.cc#L1337-L1346

This CL fixed the issue when raising the model reset port to CPU(let CPU sleep) if the CPU is not activated by workload. If the CPU status is halted, it's should not change to Suspend to avoid wake up

Reference

The model_reset is introduced in the CL:
https://gem5-review.googlesource.com/c/public/gem5/+/67574/4

[1] Activate by workload (ARM example):
https://github.com/gem5/gem5/blob/5641c5e4642f7d44651f783bdb018d3cf8ba01b5/src/arch/arm/fs_workload.cc#L101-L114

[2] Lower the model_reset:
https://github.com/gem5/gem5/blob/5641c5e4642f7d44651f783bdb018d3cf8ba01b5/src/cpu/base.cc#L191-L192
https://github.com/gem5/gem5/blob/5641c5e4642f7d44651f783bdb018d3cf8ba01b5/src/cpu/base.cc#L674-L685

Change-Id: I5bfc0b7491d14369fff77b98b71c0ac763fb7c42
@ivanaamit
Copy link
Contributor

Hi @giactra, I noticed that you self-requested a review for this PR. Do you have time to look at it? Thanks.

@ivanaamit ivanaamit merged commit 321bd07 into gem5:develop May 16, 2024
35 checks passed
@rogerchang23424 rogerchang23424 deleted the fix-cpu-halted branch May 16, 2024 23:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cpu General gem5 CPU code (e.g., `BaseCPU`)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants