-
Notifications
You must be signed in to change notification settings - Fork 72
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
Kernel Panic - OpenZFS 2.1.0 on Apple Silicon #796
Comments
Tried to symbolicate this manually for the last hour or so but I can't get "image lookup -a" to print anything and all the online instructions I found are outdated. |
It's certainly plausible that we are crashing through the kernel call stack guard page, and that it's more likely on an arm than on an x86_64. I don't run zfs on an M1 yet (your efforts here make that more likely and I wager I would be more likely than you to run into all sorts of interesting panics on ARM :) ), and I don't think lundman does either. I also, on my most stressed-out box, run with a 32 kB stack. On arm, the xnu KERNEL_STACK_SIZE macro will be 1, 2, or 4 times 16k in the normal case, when the kernel is DEBUG, and when kernel address sanitization is on, respectively, and there is the helpful comment in osfmk/mach/arm/vm_param.h to try doubling that when compiler optimization is off. kernel_stack_pages is by default KERNEL_STACK_SIZE divided by the page size, which is 16k on ARM, and therefore 1 in the normal case. We can change this at boot time (nvram boot-args="keepsyms=1 kernel_stack_pages=2"), and see the result reflected in sysctl kern.stack_size (it would go from 16384 to 32768 in this case). Running with two stack pages instead of one is almost certainly fine on anything but a very-busy-with-many-many-threads M1 with the smallest possible amount of RAM. In the general case, on arm, threads will have an upper and a lower guard page already, and the usual single stack page. On x86_64, there's an upper and lower guard page as well, but pagesize is only 4k; there's also 4 stack pages in the usual case. Assuming your Ultra has more than the absolute minimum of RAM, bumping up the kernel_stack_pages is likely to stop these panics at almost unnoticeable cost. You can also adjust (at run time, dynamically) sysctl kstat.spl.misc.spl_misc.split_stack_below. By default it is 8192, and that might not be the best choice on ARMs. You could make it bigger (to say 12k) which makes it more likely that known deep stack descents are pushed into separate threads more aggressively. Schematically, rather than going a() -> b() -> c() -> d() ... -> z(), we'd be doing a() -> b() -> c() -> spawn new thread calling d and wait for it to end, new thread: d() -> e() -> f() ... -> spawn new thread calling g() and wait for it to end ... If either or both of these approaches make your panics go away, we can look at further reducing stack frame size on arm builds, and sprinkling stack switching into a few more places. |
Thanks for you help. I have 128 GB of RAM so I'll find some time to experiment with the boot-args and see if I can get that working. There are conflicting reports about whether SIP needs to be disabled, etc. and I didn't have much luck with keepsyms when I tried it, but I didn't spend a lot of time on it yet. Unfortunately it seems to take several days to reproduce and is fairly unpredictable, so it's not going to be a long process to try to work out what is helping. |
I noticed the allocation size (0xc000) was missing from the panic above somehow, so I fixed that. I don't really know what I'm talking about, but does the panic happening here suggest that it's failing when trying to allocate kernel memory for a new thread rather than on stack overflow? The return value from kernel_memory_allocate indicates
|
Bah, you're right, I was too tired to look properly at the site of the panic. Keep an eye on kstat.spl.misc.spl_misc.active_threads to see if it becomes outrageously large. "top -u -o th" is possibly also valuable (#th column) or the equivalent in Activity Monitor or the like. A thousand and change kernel threads is not worrisome, nor is 3000-5000 total system threads. Much more than that would be something to look into, however. When I'm more awake, we can see if /usr/bin/vmmap kernel and /usr/bin/zprint can tell us something about a run on the relevant memory zones. |
kstat.spl.misc.spl_misc.active_threads is 514 currently, and whenever I've looked at the number of threads for kernel_task in top/Activity Monitor it's been pretty stable at ~1,360, but I'll start logging the former to a file every minute or so and see if anything exciting happens over time. |
I've been monitoring active_threads as above and it's almost always 514, and changes to 525 briefly sometimes under load. I was seeing some Spotlight-related crashes in my logs so I disabled that for one of my two pools where it had somehow re-enabled itself. It hasn't kernel panicked since then (the one I posted above). I had some similar issues on my previous Mac Mini fileserver running 1.9.x so I had disabled Spotlight where possible. |
With Spotlight disabled (it was preciously accidentally enabled for one of my two pools), I now haven't had a crash in over a month. I suspect there's some issue with the interaction between OpenZFS and Spotlight (since I had similar problems previously with an Intel Mac Mini), but I'm closing this because I can't be sure where the issue lies and am no longer reproducing the issue. I never saw an active_threads over 527 and it was almost always stable at 514. |
Setting the P.S. I'm running a Mac Studio M1 Max 32GB. |
OK, so doubling stack_pages work? then we are overflowing somewhere. Do we know which binary that stack is from at the top of this issue? |
M1 Ultra Mac Studio (macOS Monterey 12.3.1) running OpenZFS 2.1.0 Release. Apologies for no symbols in the backtrace, I'm not sure how to do that on the new hardware yet.
Edit: Corrected allocation size in kernel_memory_allocate.
The text was updated successfully, but these errors were encountered: