If we get a panic in a shutdown handler, we'll recursively call
kern_reboot. Rather than call the same routine that caused problems
again, skip them all and go right to doadump (if dumping).
Sponsored by: Netflix
Differential D32089
kern_reboot: Only call the shutdown handler once imp on Sep 24 2021, 12:11 AM. Authored by Tags None Referenced Files
Subscribers None
Details
Diff Detail
Event TimelineComment Actions I'm told that these day using "bool" and true/false is preferred over using "int" and 1/0, but otherwise this is good. Comment Actions Yea, me too... didn't want to change 'once' to that, so did it in the 'once' style of the function.
Comment Actions I agree with Mark, but would probably just extend "once" to cover everything between lines 442 and 488.
Comment Actions If you code BASIC, please do it in BASIC style, ie. 10/20/30 ... allowing inserting something in the middle without renumbering all the items. Comment Actions Hah, I had almost suggested an enum with named states that you bumped along as you went and this is functionally equivalent to that. I think this is fine. Comment Actions If the restarts here happen only in case of panic, should we really insist on further shutdown process, or better dump quickly and reboot? Comment Actions Re BASIUC: I don't see us adding a lot (or any) new sections. That's what the even handlers are fo. Given the low number, it's OK, especially since ++ is easy, but +=10 becomes +=5 on an insertion and may be more error prone. Elsewhere this would be a good suggestion, but I'm leading strongly against it here. Re re-entry: I think that would make it more complicated than this simple guardrail but wouldn't make it easier. Re enum: I thought of that, but rejected that as well, what if you forget to change the name? We use a similar technique to this in all the busdma routines to allow easy error exits. Comment Actions The enum would only be useful I think to address kib's worry about future insertion as at least you don't have to bump all the names, that is if you did something like: static enum { PRE_SYNC, SYNC, UPTIME, ... } progress = PRE_SYNC; ... if (progress == PRE_SYNC) { progress++; EVENTHANDLER_INVOKE(shutdown_pre_sync, howto); } ... Then inserting a new event would just meaning inserting a new enum and the new block of code without having to worry about adjusting the conditions in all the subsequent blocks. However, I agree that we aren't likely to introduce new blocks of code in this routine in the future since we generally depend on EVENTHANDLERs for extensibility here instead. Comment Actions Is there anything that prevents two threads from issuing reboot(2) in parallel? I do not see it. With the progress tracking var, the mess there is arguably higher.
Comment Actions Before the changes, life would be bad if that happened. After the change, there's fewer cases that would be bad. But arguing over degrees of badness seems... unwise... At best we can say that panicking while in reboot() is likely more common than racing there, and for that common case this is substantially better. Comment Actions We do perform context switches despite shutting down, otherwise we cannot even do things like complete io requests. Before the changes, some things could be executed twice. I argue that after the changes, some things could be executed twice or not executed at all, depending on what corruption occurs to progress from parallel un-synchronized updates. I think you should use atomic_fetchadd_int() for progress updates and reading its current value.
|