• B
    block, scsi: Make SCSI quiesce and resume work reliably · 3a0a5299
    Bart Van Assche 提交于
    The contexts from which a SCSI device can be quiesced or resumed are:
    * Writing into /sys/class/scsi_device/*/device/state.
    * SCSI parallel (SPI) domain validation.
    * The SCSI device power management methods. See also scsi_bus_pm_ops.
    
    It is essential during suspend and resume that neither the filesystem
    state nor the filesystem metadata in RAM changes. This is why while
    the hibernation image is being written or restored that SCSI devices
    are quiesced. The SCSI core quiesces devices through scsi_device_quiesce()
    and scsi_device_resume(). In the SDEV_QUIESCE state execution of
    non-preempt requests is deferred. This is realized by returning
    BLKPREP_DEFER from inside scsi_prep_state_check() for quiesced SCSI
    devices. Avoid that a full queue prevents power management requests
    to be submitted by deferring allocation of non-preempt requests for
    devices in the quiesced state. This patch has been tested by running
    the following commands and by verifying that after each resume the
    fio job was still running:
    
    for ((i=0; i<10; i++)); do
      (
        cd /sys/block/md0/md &&
        while true; do
          [ "$(<sync_action)" = "idle" ] && echo check > sync_action
          sleep 1
        done
      ) &
      pids=($!)
      for d in /sys/class/block/sd*[a-z]; do
        bdev=${d#/sys/class/block/}
        hcil=$(readlink "$d/device")
        hcil=${hcil#../../../}
        echo 4 > "$d/queue/nr_requests"
        echo 1 > "/sys/class/scsi_device/$hcil/device/queue_depth"
        fio --name="$bdev" --filename="/dev/$bdev" --buffered=0 --bs=512 \
          --rw=randread --ioengine=libaio --numjobs=4 --iodepth=16       \
          --iodepth_batch=1 --thread --loops=$((2**31)) &
        pids+=($!)
      done
      sleep 1
      echo "$(date) Hibernating ..." >>hibernate-test-log.txt
      systemctl hibernate
      sleep 10
      kill "${pids[@]}"
      echo idle > /sys/block/md0/md/sync_action
      wait
      echo "$(date) Done." >>hibernate-test-log.txt
    done
    Reported-by: NOleksandr Natalenko <oleksandr@natalenko.name>
    References: "I/O hangs after resuming from suspend-to-ram" (https://marc.info/?l=linux-block&m=150340235201348).
    Signed-off-by: NBart Van Assche <bart.vanassche@wdc.com>
    Reviewed-by: NHannes Reinecke <hare@suse.com>
    Tested-by: NMartin Steigerwald <martin@lichtvoll.de>
    Tested-by: NOleksandr Natalenko <oleksandr@natalenko.name>
    Cc: Martin K. Petersen <martin.petersen@oracle.com>
    Cc: Ming Lei <ming.lei@redhat.com>
    Cc: Christoph Hellwig <hch@lst.de>
    Cc: Johannes Thumshirn <jthumshirn@suse.de>
    Signed-off-by: NJens Axboe <axboe@kernel.dk>
    3a0a5299
block_dev.c 53.1 KB