block, scsi: Change the preempt-only flag into a counter
The RQF_PREEMPT flag is used for three purposes: - In the SCSI core, for making sure that power management requests are executed even if a device is in the "quiesced" state. - For domain validation by SCSI drivers that use the parallel port. - In the IDE driver, for IDE preempt requests. Rename "preempt-only" into "pm-only" because the primary purpose of this mode is power management. Since the power management core may but does not have to resume a runtime suspended device before performing system-wide suspend and since a later patch will set "pm-only" mode as long as a block device is runtime suspended, make it possible to set "pm-only" mode from more than one context. Since with this change scsi_device_quiesce() is no longer idempotent, make that function return early if it is called for a quiesced queue. Signed-off-by: Bart Van Assche <bvanassche@acm.org> Acked-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Ming Lei <ming.lei@redhat.com> Cc: Jianchao Wang <jianchao.w.wang@oracle.com> Cc: Johannes Thumshirn <jthumshirn@suse.de> Cc: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:

committed by
Jens Axboe

parent
bca6b067b0
commit
cd84a62e00
@@ -3046,11 +3046,14 @@ scsi_device_quiesce(struct scsi_device *sdev)
|
||||
*/
|
||||
WARN_ON_ONCE(sdev->quiesced_by && sdev->quiesced_by != current);
|
||||
|
||||
blk_set_preempt_only(q);
|
||||
if (sdev->quiesced_by == current)
|
||||
return 0;
|
||||
|
||||
blk_set_pm_only(q);
|
||||
|
||||
blk_mq_freeze_queue(q);
|
||||
/*
|
||||
* Ensure that the effect of blk_set_preempt_only() will be visible
|
||||
* Ensure that the effect of blk_set_pm_only() will be visible
|
||||
* for percpu_ref_tryget() callers that occur after the queue
|
||||
* unfreeze even if the queue was already frozen before this function
|
||||
* was called. See also https://lwn.net/Articles/573497/.
|
||||
@@ -3063,7 +3066,7 @@ scsi_device_quiesce(struct scsi_device *sdev)
|
||||
if (err == 0)
|
||||
sdev->quiesced_by = current;
|
||||
else
|
||||
blk_clear_preempt_only(q);
|
||||
blk_clear_pm_only(q);
|
||||
mutex_unlock(&sdev->state_mutex);
|
||||
|
||||
return err;
|
||||
@@ -3088,7 +3091,7 @@ void scsi_device_resume(struct scsi_device *sdev)
|
||||
mutex_lock(&sdev->state_mutex);
|
||||
WARN_ON_ONCE(!sdev->quiesced_by);
|
||||
sdev->quiesced_by = NULL;
|
||||
blk_clear_preempt_only(sdev->request_queue);
|
||||
blk_clear_pm_only(sdev->request_queue);
|
||||
if (sdev->sdev_state == SDEV_QUIESCE)
|
||||
scsi_device_set_state(sdev, SDEV_RUNNING);
|
||||
mutex_unlock(&sdev->state_mutex);
|
||||
|
Reference in New Issue
Block a user