You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] DSP panic with Zephyr on Intel MTL, regression 27th June #9268
Describe the bug
A DSP panic started showing up in CI runs on 27th June. No individual PR merged recently shows this in test results, so suspcion is a combination of PRs merged. Current suspect:
One thing to clean up in power_down assembly is window exceptions. You're called in a context where register windowing is enabled, which means that any access to registers other than A0-A3 can in principle trap. And the first use of A11+ (the last window, after which no window exceptions will occur) doesn't happen until after you've locked three data and four instruction lines into the cache. I don't see why that's illegal, but if I wanted to place bets on "how to exercise weird core behavior", this would be on the list. Strongly suggest "pre-spilling" all registers by e.g. putting a and a15, a15, a15 # force window exceptions right after the ENTRY instruction.
Also, I note there are two "MOVI" pseudo instructions after you start locking cache lines which are going to end up pointing into an arbitrary literals location. You need an explicit L32R to be sure it lands in valid memory, not a compiler-generated MOVI.
Also, I note there are two "MOVI" pseudo instructions after you start locking cache lines
Oooh, and there are lots more in asm_memory_management.h in contexts where you've already started shutting down memory! I'm going to place my chips on this as the culprit. I give it 60%+ odds.
Someone needs to comb through these files and make sure there's no "MOVI" usage (which again to be clear: is only a CPU instruction for small values, for big ones the compiler gets fancy and emits a .literals record for the linker to find and place). I mean, maybe I'll lose the bet and these will turn out to all be valid/non-loading variants. But still I think style would demand this be cleaned up.
Also, I note there are two "MOVI" pseudo instructions after you start locking cache lines
Oooh, and there are lots more in asm_memory_management.h in contexts where you've already started shutting down memory! I'm going to place my chips on this as the culprit. I give it 60%+ odds.
Someone needs to comb through these files and make sure there's no "MOVI" usage (which again to be clear: is only a CPU instruction for small values, for big ones the compiler gets fancy and emits a .literals record for the linker to find and place). I mean, maybe I'll lose the bet and these will turn out to all be valid/non-loading variants. But still I think style would demand this be cleaned up.
@andyross ouch, yes, that sounds like a problem. Thanks for finding it! Now somebody just needs to fix it...
Also, I note there are two "MOVI" pseudo instructions after you start locking cache lines which are going to end up pointing into an arbitrary literals location. You need an explicit L32R to be sure it lands in valid memory, not a compiler-generated MOVI.
Oooh, and there are lots more in asm_memory_management.h in contexts where you've already started shutting down memory! I'm going to place my chips on this as the culprit. I give it 60%+ odds.
FWIW: I still bet that if you whiteboxed a rig to enumerate all the dcache indexes and check how many of them can be pinned, we'd discover that something in the boot ROM or elsewhere has left a line pinned accidentally, preventing more pinning at that index, and we're just hitting that by bad luck in the linker.
Would be non-trivial assembly to write, and tedious to debug as the only feedback is a panic, but not "hard" hopefully.
@lyakh my read is there are three ways, so you need to prove you can lock two lines at each index to saturate. IIRC there are two separate dcache regions in the code in question, right? So if those overlap in index and happen to collide with something already in the cache, then we'd be in a situation where we're trying to lock the same index in all three ways, which is illegal.
Activity
kv2019i commentedon Jun 27, 2024
Also seen in:
lyakh commentedon Jun 27, 2024
git bisectreliably brought to an SOF commit, that obviously cannot be the real reason - in a sense that that commit only adds 2 new functions without calling them and without touching a single line of runnable code, so it's purely modifying the build layout.The crash happens at https://github.com/zephyrproject-rtos/zephyr/blob/b82b5b0734c30490368e21627423f10036487343/soc/intel/intel_adsp/ace/power_down.S#L64
That location is trying to lock in cache a variable on caller's stack https://github.com/zephyrproject-rtos/zephyr/blob/b82b5b0734c30490368e21627423f10036487343/soc/intel/intel_adsp/ace/power.c#L342 which all looks valid. However, it causes an exception. As a WA moving that variable to
.bssby making itstaticseems to eliminate the problem.lyakh commentedon Jun 27, 2024
@ceolin any ideas?
lyakh commentedon Jun 27, 2024
teburd commentedon Jun 27, 2024
What does the assembly dump look like for pm_state_set and power_down?
andyross commentedon Jun 27, 2024
One thing to clean up in power_down assembly is window exceptions. You're called in a context where register windowing is enabled, which means that any access to registers other than A0-A3 can in principle trap. And the first use of A11+ (the last window, after which no window exceptions will occur) doesn't happen until after you've locked three data and four instruction lines into the cache. I don't see why that's illegal, but if I wanted to place bets on "how to exercise weird core behavior", this would be on the list. Strongly suggest "pre-spilling" all registers by e.g. putting a
and a15, a15, a15 # force window exceptionsright after the ENTRY instruction.Also, I note there are two "MOVI" pseudo instructions after you start locking cache lines which are going to end up pointing into an arbitrary literals location. You need an explicit L32R to be sure it lands in valid memory, not a compiler-generated MOVI.
andyross commentedon Jun 27, 2024
Oooh, and there are lots more in asm_memory_management.h in contexts where you've already started shutting down memory! I'm going to place my chips on this as the culprit. I give it 60%+ odds.
Someone needs to comb through these files and make sure there's no "MOVI" usage (which again to be clear: is only a CPU instruction for small values, for big ones the compiler gets fancy and emits a .literals record for the linker to find and place). I mean, maybe I'll lose the bet and these will turn out to all be valid/non-loading variants. But still I think style would demand this be cleaned up.
lyakh commentedon Jun 28, 2024
@andyross ouch, yes, that sounds like a problem. Thanks for finding it! Now somebody just needs to fix it...
lyakh commentedon Jun 28, 2024
@andyross I looked again at these. And TBH I don't see a problem with those specific ones. Here are the lines we're talking about:
https://github.com/zephyrproject-rtos/zephyr/blob/cfbe2adabc511663776642616cdc75510db882d3/soc/intel/intel_adsp/ace/power_down.S#L53-L61
Firstly, they just lock some cache lines, all the memory is still powered on. The problem would occur if we tried to access RAM after it's powered off, correct? So, those locations before powering down RAM should be safe? Same about these two lines https://github.com/zephyrproject-rtos/zephyr/blob/cfbe2adabc511663776642616cdc75510db882d3/soc/intel/intel_adsp/ace/power_down.S#L67-L68
These ones - yes, agree, look dangerous...
lyakh commentedon Jun 28, 2024
@andyross @teburd that was a nice theory, but it doesn't seem to help: zephyrproject-rtos/zephyr#75174 doesn't fix the problem. What exactly did we bet, Andy? ;-)
33 remaining items
lyakh commentedon Sep 5, 2024
and a new attempt to fix it zephyrproject-rtos/zephyr#78057
andyross commentedon Sep 5, 2024
Posted this in the PR by accident, copying here:
FWIW: I still bet that if you whiteboxed a rig to enumerate all the dcache indexes and check how many of them can be pinned, we'd discover that something in the boot ROM or elsewhere has left a line pinned accidentally, preventing more pinning at that index, and we're just hitting that by bad luck in the linker.
Would be non-trivial assembly to write, and tedious to debug as the only feedback is a panic, but not "hard" hopefully.
lyakh commentedon Sep 6, 2024
@andyross I think what I've tested that back when debugging this last time by doing either one or both of the following things:
DIUNeither had helped
andyross commentedon Sep 7, 2024
@lyakh my read is there are three ways, so you need to prove you can lock two lines at each index to saturate. IIRC there are two separate dcache regions in the code in question, right? So if those overlap in index and happen to collide with something already in the cache, then we'd be in a situation where we're trying to lock the same index in all three ways, which is illegal.
Maybe. :)
lyakh commentedon Sep 9, 2024
@andyross sure, but as I said - I also tried unlocking all cache lines and it didn't help either
wszypelt commentedon Sep 20, 2024
@lyakh is everything working now? Can we close this issue?
marc-hb commentedon Sep 20, 2024
@wszypelt the last words are "... and it didn't help either"
?
lyakh commentedon Sep 23, 2024
@marc-hb that was a reply to a specific question, not a statement about the state of this bug
lyakh commentedon Sep 23, 2024
@wszypelt yes, so far zephyrproject-rtos/zephyr#78283 has fixed it
intel_adsp/ace: power: pad the hpsram_mask passed to power_down
intel_adsp/ace: power: pad the hpsram_mask passed to power_down