O3: Fixes fetch deadlock when the interrupt clears before CPU handles it.
Review Request #338 - Created Dec. 6, 2010 and submitted
| Information | |
|---|---|
| Ali Saidi | |
| gem5 | |
| Reviewers | |
| Default | |
| ali, gblack, nate, stever | |
O3: Fixes fetch deadlock when the interrupt clears before CPU handles it. When this condition occurs the cpu should restart the fetch stage to fetch from the original execution path. Fault handling in the commit stage is cleaned up a little bit so the control flow is simplier. Finally, if an instruction is being used to carry a fault it isn't executed, so the fault propigates appropriately.
Posted (Dec. 8, 2010, 2:30 p.m.)
Could you please explain the reason for this change? I'm not familiar enough with ARM's interrupt architecture to know what the commit message is saying. My guess is that the interrupt controller initially thought it was going to signal an interrupt but then later changed it's mind. If that's the case, then really shouldn't we change the interrupt controller so it doesn't change its mind? I don't that that's possible, but I can't think of why it wouldn't be.
-
src/cpu/o3/iew_impl.hh (Diff revision 1) -
Shouldn't the instruction be a nop in this case and do nothing when executed?
Posted (Dec. 21, 2010, 9:11 a.m.)
-
src/cpu/o3/commit_impl.hh (Diff revision 1) -
I think this code is evolving toward unnecessary complexity. It looks to me like there are two separate things going on: 1. calling cpu->checkInterrupts() to see if there are pending interrupts, and if so, initiating the pipeline flush and storing the interrupt code in the 'interrupt' variable 2. if the 'interrupt' variable is set and the pipeline is flushed, handling the interrupt Having both of these things combined in a single function that has to get called if either one of these things needs to be done is confusing. Is there even any need to store the interrupt fault code between 1 and 2? Seems like we just need a bool to remember that we passed 1 and are waiting for 2, and a few tests to see if either we arrived at 2 or the interrupt got cleared so we should roll back to a pre-1 state.
-
src/cpu/o3/fetch_impl.hh (Diff revision 1) -
I'm confused... in fetchCacheLine() we check (interruptPending && !(pc & 0x3)) and isSwitchedOut() and return false.... so what are the cases where fetchCacheLine returns true that need to be fixed up here? And aren't those cases that should be fixed up by making fetchCacheLine() return false rather than adding all these special checks here?
-
src/cpu/o3/fetch_impl.hh (Diff revision 1) -
Why not combine this info into a single DPRINTF?
Posted (Jan. 10, 2011, 9:32 a.m.)
-
src/cpu/o3/commit_impl.hh (Diff revision 1) -
I split this into two functions, but boolean is if interrupt == NoFault or not. The flow control is much better and after it passes regressions I'll post it.
-
src/cpu/o3/fetch_impl.hh (Diff revision 1) -
Moved the check into fetchCacheLine. No ugly macros, but there still is an alpha specific bit
-
src/cpu/o3/fetch_impl.hh (Diff revision 1) -
merged
-
src/cpu/o3/iew_impl.hh (Diff revision 1) -
yup
Review request changed
Updated (Jan. 12, 2011, 1:06 a.m.)
Summary: |
|
|||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Description: |
|
|||||||||||||||||||||||||||
Diff: |
Revision 2 (+92 -47) |
Posted (Jan. 16, 2011, 4:58 p.m.)
I still don't totally follow why this is necessary, although I believe it probably is. One sticky problem you can run into with x86 (and probably most ISAs) is if you enable interrupts and then immediately disable them again, expecting that that will let any pent up interrupts get handled. Is it possible the CPU might attempt to process one but then lose it's opportunity in that case? I know in some real world case (I don't remember the specifics) it can hang an OS which expects an interrupt to get through as described and move things along. If that doesn't matter here then never mind, but it's a potential problem it would be best to fix if possible.
-
src/arch/arm/interrupts.hh (Diff revision 2) -
This should probably go into it's own change and just get committed right away since it's just fixing a typo basically. It doesn't have anything to do with the O3 changes.
-
src/cpu/o3/commit.hh (Diff revision 2) -
I think this is spelled propagate. This should be fixed in the commit message too, and wherever else it might be.
-
src/cpu/o3/commit_impl.hh (Diff revision 2) -
This line is too long now.
Posted (Jan. 17, 2011, 1:01 a.m.)
Much better... thanks for splitting handleInterrupt(), this is much clearer and cleaner. Just a few little things left. I'll take your word on the merged DPRINTF since that didn't seem to make it into the revised diff.
-
src/cpu/o3/commit.hh (Diff revision 2) -
Yea, it's definitely "propagate"
-
src/cpu/o3/commit_impl.hh (Diff revision 2) -
I'm confused by the bare 'interrupt' term here... shouldn't it be 'interrupt != NoFault' or something like that?
-
src/cpu/o3/fetch.hh (Diff revision 2) -
This is a big improvement... seems like it would be even better if we could create a new ISA-dependent function like suppressInterrupts() that returns ((pc & 0x3) != 0) for the Alpha case and false for everyone else, then get rid of this function and change the original line to (interruptPending && !suppressInterrupts(pc)) which addresses my other concern, that checkInterrupt() is kind of unspecific since we already have a function called checkInterrupts().
