blk_run_queues() places queues onto a local list without locking. But
interrupt-time activity in scsi_lib.c will replug these queues, which
involves accessing that list which blk_run_queues() is walking.
Net effect: list corruption and an oops. Very hard to reproduce...
So hold the lock while blk_run_queues() is walking the local list.
The patch was acked by Jens. It also uninlines a few largeish
functions and adds a couple of WARN_ON()s in code which worried me.