Quoting nathan binkert <[email protected]>:

The problem Gabe is seeing is related to x86 micro-ops.  He is having a race
condition between commit redirecting fetch before fetch has finished issuing
a macro-op that is doing operations that cannot be interrupted because they
can't be replayed safely. For instance updating the stack pointer mid
instruction.  He is trying not to wait for the pipe to drain as much as he
is trying to allow fetch to issue what it needs to before redirecting as
soon as possible.
I guess the thing I don't understand is, why is commit redirecting
fetch?  Why isn't an interrupt simply directly redirecting the fetch
stage as if there were some sort of "interrupt macroop" in the middle
of the fetch stream?

I'll admit that I don't know how it works on x86, but I'm pretty sure
that on alpha an interrupt is a fetch stage thing.

Steve/Ali, any ideas?

  Nate
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev


There seems to be some confusion over how this works, and that's understandable since it is a bit confusing. I'm not sure I have it totally right. This is how I think it works.

1. Commit decides the time is right for an interrupt. It uses ISA defined functions/whatnot to do that, but basically, imagine an interrupt is queued up and an instruction just turned on interrupts. It signals this back to fetch, keeps processing instructions, and waits for a condition described below.

2. Fetch gets the signal from commit. It waits until it finds a break in the instruction stream where interrupts are allowed, at which point it stops creating new instructions.

3. Commit waits until everything that's coming has made it's way through and the pipe is empty and up to a commit point. It checks if interrupts are still enabled (an intermediate instruction may have turned interrupts back off), and if they're still on it services the interrupt.

4. Fetch starts back up at the start of the interrupt.

What my patch is addressing is how commit decides everything fetch is going to send has made its way through the pipe. Before, it would just make sure the ROB and store queue were empty. That would miss cases where instructions hadn't made it to the ROB (they were stuck by serialization in decode, for instance). If those instructions which get left behind were necessary to get all the way up to a commit point, you'll effectively take an interrupt in the middle of an instruction (bad news). My change replaces that check with one that makes sure the instList (I think?) is empty. When an instruction is created in fetch, as part of that function call it's put into the list. I believe the only time an instruction is ever removed is when it's in commit and it is recognized as squashed or is committed. Basically it holds all the "live" instructions in the CPU, and a comment near its declaration I think even says as much. Maybe this misses committed stores that haven't written back? Not sure.

I think maybe this scheme is flawed in any case. What if there's a branch mispredict in microcode? Will the squashed microops just be dropped? Will fetch remain stopped at it's "boundary" even though it didn't get all of it, or will it start up again and find a new boundary? This may work, but I suspect it's an overlooked corner case.

Another possibility other than communicating back to fetch, having fetch find a boundary, making commit infer everything has bubbled through, and then checking if interrupts are still allowed (which has a flaw I detailed earlier). To me it makes sense to just make commit decide "INTERRUPT NOW. Everyone out of the pool!" at some commit point, have it nuke everything else in the pipe, and make fetch start again from that point. It would basically be the same as the fault handling mechanism. As I explained before, it seems like it would be a wash performance wise.

Is that any clearer now? Did I mangle any of the facts?

Gabe
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to