Stage1 - Undo the vm_mtx stuff Alfred put in in order to try a new approach (with permission from Alfred).
Stage1b - Introduce GIANT_ macros (see later on) to strictly manage moving things out from under Giant and to create a debugging infrastructure whereby Giant can be turned off for subsystems on a subsystem-by-subsystem (or syscall-by-syscall) basis, depending, allowing you to nominally boot the machine up 'safely', and then mess around with Giant to test recent work.
Stage2 - Add fine-grained Mutexes for vm_page access, vm_object access, vm_map access, and struct buf access.
Stage3 - Use GIANT_DEPRECATED to move certain VM syscalls out from under Giant.
Stage4 - Attempt to fine-grain-mutex the IO subsystem (initiation and completion), and try to move more things out from under giant using GIANT_DEPRECATED.
undovm2.diff - (THIS HAS BEEN COMMITTED) VM mutex backout in preparation for introduction of a better way. This patch also introduces a number macros to make the status of Giant in various routines crystal clear. GIANT_REQUIRED, START/END_GIANT_DEPRECATED, and START/END_GIANT_OPTIONAL.
GIANT_REQUIRED is used to assert that Giant must be held on entry to this routine. It also asserts that no prior routine in the call stack is within a GIANT_DEPRECATED or GIANT_OPTIONAL section.
someprocedure() { declarations; GIANT_REQUIRED; ... }
GIANT_DEPRECATED asserts that this routine should now be MP SAFE, but Giant is obtained or not obtained based on a sysctl for debugging purposes. No subroutine lower in the call stack may require giant (or they will panic, even if we have the sysctl set to get giant here). That is, you cannot use the GIANT_DEPRECATED macros in a procedure unless you believe Giant can truely be ripped out. Note: you must declare a sysctl variable to control Giant here. The sysctl variable should default to '1' to enable Giant through the booting process, allowing the developer/tester to then turn it off to test the subsystem.
someprocedure() { declarations; START_GIANT_DEPRECATED(sysctlvarname); /* must occur just after decls */ (code) /* code must fall through to or goto the END_ side of the macro */ END_GIANT_DEPRECATED; }
GIANT_OPTIONAL asserts that this routine is MP safe but that Giant might be held due to higher level routines not being MP safe. This routine does NOT obtain Giant. No subroutine lower in the call stack may require giant (or they will panic, even if we own Giant at the time). i.e. if you assert that giant is optional here, then giant obviously cannot be required in a deeper routine.
someprocedure() { declarations; (possible code) START_GIANT_OPTIONAL; (code) /* code must fall through to or goto the END side of the macro */ END_GIANT_OPTIONAL; (possible code) }