linux/block
Tejun Heo bc90ba093a block: always requeue !fs requests at the front
SCSI marks internal commands with REQ_PREEMPT and push it at the front
of the request queue using blk_execute_rq().  When entering suspended
or frozen state, SCSI devices are quiesced using
scsi_device_quiesce().  In quiesced state, only REQ_PREEMPT requests
are processed.  This is how SCSI blocks other requests out while
suspending and resuming.  As all internal commands are pushed at the
front of the queue, this usually works.

Unfortunately, this interacts badly with ordered requeueing.  To
preserve request order on requeueing (due to busy device, active EH or
other failures), requests are sorted according to ordered sequence on
requeue if IO barrier is in progress.

The following sequence deadlocks.

1. IO barrier sequence issues.

2. Suspend requested.  Queue is quiesced with part or all of IO
   barrier sequence at the front.

3. During suspending or resuming, SCSI issues internal command which
   gets deferred and requeued for some reason.  As the command is
   issued after the IO barrier in #1, ordered requeueing code puts the
   request after IO barrier sequence.

4. The device is ready to process requests again but still is in
   quiesced state and the first request of the queue isn't
   REQ_PREEMPT, so command processing is deadlocked -
   suspending/resuming waits for the issued request to complete while
   the request can't be processed till device is put back into
   running state by resuming.

This can be fixed by always putting !fs requests at the front when
requeueing.

The following thread reports this deadlock.

  http://thread.gmane.org/gmane.linux.kernel/537473

Signed-off-by: Tejun Heo <htejun@gmail.com>
Acked-by: David Greaves <david@dgreaves.com>
Acked-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-06-15 16:12:20 -07:00
..
as-iosched.c kblockd: use flush_work 2007-05-09 12:30:51 -07:00
blktrace.c [PATCH] mark struct file_operations const 3 2007-02-12 09:48:45 -08:00
cfq-iosched.c KMEM_CACHE(): simplify slab cache creation 2007-05-07 12:12:55 -07:00
deadline-iosched.c [BLOCK] Cleanup unused variable passing 2006-12-01 10:42:33 +01:00
elevator.c [PATCH] elevator: elv_list_lock does not need irq disabling 2007-04-30 09:08:17 +02:00
genhd.c genhd: send async notification on media change 2007-05-23 20:14:12 -07:00
ioctl.c mm: remove destroy_dirty_buffers from invalidate_bdev() 2007-05-07 12:12:55 -07:00
Kconfig [PATCH] Centralise definitions of sector_t and blkcnt_t 2006-12-04 19:41:15 -08:00
Kconfig.iosched update I/O sched Kconfig help texts - CFQ is now default, not AS. 2007-02-17 20:08:22 +01:00
ll_rw_blk.c block: always requeue !fs requests at the front 2007-06-15 16:12:20 -07:00
Makefile
noop-iosched.c [BLOCK] Cleanup unused variable passing 2006-12-01 10:42:33 +01:00
scsi_ioctl.c [SCSI] sg: cap reserved_size values at max_sectors 2007-04-17 18:09:56 -04:00