K 10 svn:author V 3 avg K 8 svn:date V 27 2011-05-09T07:05:06.067236Z K 7 svn:log V 2141 re-implement hard stopping of CPUs and use it enforce panic(9) context Hard stopping changes: - stop_cpus_hard interface is intentionally narrowed to always act on all other cpus - stop_cpus_hard keeps its own accounting of stopped cpus completely disregarding soft stopping of cpus (pausing, suspending) - no recursion whatsoever is allowed for stop_cpus_hard; all callers must check if they are already in "super" mode - protect stop function with spinlock context - avoid potential deadlock between two cpus already being in nmi context (e.g. because of hardware) and trying to stop each other by checking the stopped bit while spinning on stopper lock; this is possibly an arch-specific thing [x86]; The last item is what I call a cross-cpu deadlock avoidance approach. General idea: if a CPU can't grab a lock protecting cross-/intra-CPU interactions, then while spinning on the lock the CPU should check for incoming cross-CPU events possibly posted by a CPU that currently holds the lock. In this scheme an IPI is used only to interrupt a CPU so that it can notice a new event, but the actual event should be passed via the memory (a bit in a cpu set - like newly introduced hard_stopping_cpus, or some other variable). Panic context changes: - ensure that only one (panic-ing) CPU runs after panic(9) call by stopping other CPUs using stop_cpus_hard() - disable interrupts/preemption early in panic(9) and do re-enable (this most probably breaks sync-on-panic behavior) - allow a panic-ing thread to penetrate all locks and never sleep on conditions (lockmgr locks are exempt actually): o mutex, spin mutex, rwlock, rmlock, sx: allow lock/unlock operations to unconditionally succeed for a thread in panic [jhb] o tsleep, msleep (msleep_spin, _sleep): return success without waiting for a thread in panic [jhb] o cv code already does that when panisctr != NULL - boot(): do not rebind to bsp if panic-ing [mdf] - in all places where we want to stop other cpus first check if they are not stopped already cpu_reset() and cpustop_hard_handler() are only (re-)implemented for amd64 at the moment. END