b3b3b35a82
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAl/1wNYACgkQONu9yGCS aT64cxAAwwt2H911zFagJCVDfLKXJ4da062n0YcJe3saGSg+mdEkSGYEDxjV6jjM jTzK1W5C49sQ9kzIF43YnYgdULwcXJ76G/uqFjFOlmbRzAKAYgs/3KXesa7S4cp+ LT0fiR7uyViOw1zn4yBIeSnax8uRwT4vR1vV++ILC/7vL6hcnOBOPLxGzUKYlvJQ TD8ZQjeTXe5E7IhE+ztuhJQT+hZr1VERTjoktcfmlUps94uITeKdKYoCCZQ/zYIL IS7OgnAw5RNERHa1JUZruaGFvJORTu8wAfVtgD1VgRUZAe2ziWH6aCeDPaWaLzS5 3U7Rc3Fyf0CRYrhe7mI1J864GIEUAe9V34sGQzaU/ap4SWpLvHbu12ePlb+nLNKF MZmGEd0eZuKKDSx9dlcx8hbfVg99YpI5oOeDvfCJpYx/uxNzzJhO5wkkZxweiN9s XTMUhhkTNkhgYdzn4Y8G9++LLAZpwOImSh3NkntoH+mSVlC+jVBbskz6PdywDjQR ROVpW26t5Ee6uDTrjci5cffbfje2y0r9km5/sbRWUz2YGsqYfAI3FtbH5isNUPOm Q6ucTd+xvmApfp9bn+XYLnbTQEGAD6mAgSmO11CIDsUJUvOTD/2cv861kATJqhXm 01rHgohIG604vERppYC3WWFjh0cdevBvwSOpDi1LIdlgbEF6QY0= =q0Fm -----END PGP SIGNATURE----- Merge 5.4.87 into android11-5.4-lts Changes in 5.4.87 net/sched: sch_taprio: reset child qdiscs before freeing them md/raid10: initialize r10_bio->read_slot before use. thermal/drivers/cpufreq_cooling: Update cpufreq_state only if state has changed ext4: prevent creating duplicate encrypted filenames ubifs: prevent creating duplicate encrypted filenames f2fs: prevent creating duplicate encrypted filenames fscrypt: add fscrypt_is_nokey_name() fscrypt: remove kernel-internal constants from UAPI header vfio/pci: Move dummy_resources_list init in vfio_pci_probe() btrfs: fix race when defragmenting leads to unnecessary IO ext4: don't remount read-only with errors=continue on reboot KVM: x86: avoid incorrect writes to host MSR_IA32_SPEC_CTRL KVM: SVM: relax conditions for allowing MSR_IA32_SPEC_CTRL accesses KVM: x86: reinstate vendor-agnostic check on SPEC_CTRL cpuid bits powerpc/bitops: Fix possible undefined behaviour with fls() and fls64() jffs2: Allow setting rp_size to zero during remounting jffs2: Fix NULL pointer dereference in rp_size fs option parsing scsi: block: Fix a race in the runtime power management code uapi: move constants from <linux/kernel.h> to <linux/const.h> tools headers UAPI: Sync linux/const.h with the kernel headers null_blk: Fix zone size initialization of: fix linker-section match-table corruption cgroup: Fix memory leak when parsing multiple source parameters scsi: cxgb4i: Fix TLS dependency Bluetooth: hci_h5: close serdev device and free hu in h5_close reiserfs: add check for an invalid ih_entry_count misc: vmw_vmci: fix kernel info-leak by initializing dbells in vmci_ctx_get_chkpt_doorbells() media: gp8psk: initialize stats at power control logic f2fs: fix shift-out-of-bounds in sanity_check_raw_super() ALSA: seq: Use bool for snd_seq_queue internal flags ALSA: rawmidi: Access runtime->avail always in spinlock bfs: don't use WARNING: string when it's just info. fcntl: Fix potential deadlock in send_sig{io, urg}() rtc: sun6i: Fix memleak in sun6i_rtc_clk_init module: set MODULE_STATE_GOING state when a module fails to load quota: Don't overflow quota file offsets rtc: pl031: fix resource leak in pl031_probe powerpc: sysdev: add missing iounmap() on error in mpic_msgr_probe() i3c master: fix missing destroy_workqueue() on error in i3c_master_register NFSv4: Fix a pNFS layout related use-after-free race when freeing the inode f2fs: avoid race condition for shrinker count module: delay kobject uevent until after module init call fs/namespace.c: WARN if mnt_count has become negative um: ubd: Submit all data segments atomically tick/sched: Remove bogus boot "safety" check ALSA: pcm: Clear the full allocated memory at hw_params dm verity: skip verity work if I/O error when system is shutting down Linux 5.4.87 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> [EB: fixed fs/crypto/ merge resolution] Signed-off-by: Eric Biggers <ebiggers@google.com> Change-Id: I383fa03a6d3c025d167ab57faebf0d3a59919a00
225 lines
6.8 KiB
C
225 lines
6.8 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
#include <linux/blk-mq.h>
|
|
#include <linux/blk-pm.h>
|
|
#include <linux/blkdev.h>
|
|
#include <linux/pm_runtime.h>
|
|
#include "blk-mq.h"
|
|
#include "blk-mq-tag.h"
|
|
|
|
/**
|
|
* blk_pm_runtime_init - Block layer runtime PM initialization routine
|
|
* @q: the queue of the device
|
|
* @dev: the device the queue belongs to
|
|
*
|
|
* Description:
|
|
* Initialize runtime-PM-related fields for @q and start auto suspend for
|
|
* @dev. Drivers that want to take advantage of request-based runtime PM
|
|
* should call this function after @dev has been initialized, and its
|
|
* request queue @q has been allocated, and runtime PM for it can not happen
|
|
* yet(either due to disabled/forbidden or its usage_count > 0). In most
|
|
* cases, driver should call this function before any I/O has taken place.
|
|
*
|
|
* This function takes care of setting up using auto suspend for the device,
|
|
* the autosuspend delay is set to -1 to make runtime suspend impossible
|
|
* until an updated value is either set by user or by driver. Drivers do
|
|
* not need to touch other autosuspend settings.
|
|
*
|
|
* The block layer runtime PM is request based, so only works for drivers
|
|
* that use request as their IO unit instead of those directly use bio's.
|
|
*/
|
|
void blk_pm_runtime_init(struct request_queue *q, struct device *dev)
|
|
{
|
|
q->dev = dev;
|
|
q->rpm_status = RPM_ACTIVE;
|
|
pm_runtime_set_autosuspend_delay(q->dev, -1);
|
|
pm_runtime_use_autosuspend(q->dev);
|
|
}
|
|
EXPORT_SYMBOL(blk_pm_runtime_init);
|
|
|
|
/**
|
|
* blk_pre_runtime_suspend - Pre runtime suspend check
|
|
* @q: the queue of the device
|
|
*
|
|
* Description:
|
|
* This function will check if runtime suspend is allowed for the device
|
|
* by examining if there are any requests pending in the queue. If there
|
|
* are requests pending, the device can not be runtime suspended; otherwise,
|
|
* the queue's status will be updated to SUSPENDING and the driver can
|
|
* proceed to suspend the device.
|
|
*
|
|
* For the not allowed case, we mark last busy for the device so that
|
|
* runtime PM core will try to autosuspend it some time later.
|
|
*
|
|
* This function should be called near the start of the device's
|
|
* runtime_suspend callback.
|
|
*
|
|
* Return:
|
|
* 0 - OK to runtime suspend the device
|
|
* -EBUSY - Device should not be runtime suspended
|
|
*/
|
|
int blk_pre_runtime_suspend(struct request_queue *q)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (!q->dev)
|
|
return ret;
|
|
|
|
WARN_ON_ONCE(q->rpm_status != RPM_ACTIVE);
|
|
|
|
spin_lock_irq(&q->queue_lock);
|
|
q->rpm_status = RPM_SUSPENDING;
|
|
spin_unlock_irq(&q->queue_lock);
|
|
|
|
/*
|
|
* Increase the pm_only counter before checking whether any
|
|
* non-PM blk_queue_enter() calls are in progress to avoid that any
|
|
* new non-PM blk_queue_enter() calls succeed before the pm_only
|
|
* counter is decreased again.
|
|
*/
|
|
blk_set_pm_only(q);
|
|
ret = -EBUSY;
|
|
/* Switch q_usage_counter from per-cpu to atomic mode. */
|
|
blk_freeze_queue_start(q);
|
|
/*
|
|
* Wait until atomic mode has been reached. Since that
|
|
* involves calling call_rcu(), it is guaranteed that later
|
|
* blk_queue_enter() calls see the pm-only state. See also
|
|
* http://lwn.net/Articles/573497/.
|
|
*/
|
|
percpu_ref_switch_to_atomic_sync(&q->q_usage_counter);
|
|
if (percpu_ref_is_zero(&q->q_usage_counter))
|
|
ret = 0;
|
|
/* Switch q_usage_counter back to per-cpu mode. */
|
|
blk_mq_unfreeze_queue(q);
|
|
|
|
if (ret < 0) {
|
|
spin_lock_irq(&q->queue_lock);
|
|
q->rpm_status = RPM_ACTIVE;
|
|
pm_runtime_mark_last_busy(q->dev);
|
|
spin_unlock_irq(&q->queue_lock);
|
|
|
|
blk_clear_pm_only(q);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
EXPORT_SYMBOL(blk_pre_runtime_suspend);
|
|
|
|
/**
|
|
* blk_post_runtime_suspend - Post runtime suspend processing
|
|
* @q: the queue of the device
|
|
* @err: return value of the device's runtime_suspend function
|
|
*
|
|
* Description:
|
|
* Update the queue's runtime status according to the return value of the
|
|
* device's runtime suspend function and mark last busy for the device so
|
|
* that PM core will try to auto suspend the device at a later time.
|
|
*
|
|
* This function should be called near the end of the device's
|
|
* runtime_suspend callback.
|
|
*/
|
|
void blk_post_runtime_suspend(struct request_queue *q, int err)
|
|
{
|
|
if (!q->dev)
|
|
return;
|
|
|
|
spin_lock_irq(&q->queue_lock);
|
|
if (!err) {
|
|
q->rpm_status = RPM_SUSPENDED;
|
|
} else {
|
|
q->rpm_status = RPM_ACTIVE;
|
|
pm_runtime_mark_last_busy(q->dev);
|
|
}
|
|
spin_unlock_irq(&q->queue_lock);
|
|
|
|
if (err)
|
|
blk_clear_pm_only(q);
|
|
}
|
|
EXPORT_SYMBOL(blk_post_runtime_suspend);
|
|
|
|
/**
|
|
* blk_pre_runtime_resume - Pre runtime resume processing
|
|
* @q: the queue of the device
|
|
*
|
|
* Description:
|
|
* Update the queue's runtime status to RESUMING in preparation for the
|
|
* runtime resume of the device.
|
|
*
|
|
* This function should be called near the start of the device's
|
|
* runtime_resume callback.
|
|
*/
|
|
void blk_pre_runtime_resume(struct request_queue *q)
|
|
{
|
|
if (!q->dev)
|
|
return;
|
|
|
|
spin_lock_irq(&q->queue_lock);
|
|
q->rpm_status = RPM_RESUMING;
|
|
spin_unlock_irq(&q->queue_lock);
|
|
}
|
|
EXPORT_SYMBOL(blk_pre_runtime_resume);
|
|
|
|
/**
|
|
* blk_post_runtime_resume - Post runtime resume processing
|
|
* @q: the queue of the device
|
|
* @err: return value of the device's runtime_resume function
|
|
*
|
|
* Description:
|
|
* Update the queue's runtime status according to the return value of the
|
|
* device's runtime_resume function. If the resume was successful, call
|
|
* blk_set_runtime_active() to do the real work of restarting the queue.
|
|
*
|
|
* This function should be called near the end of the device's
|
|
* runtime_resume callback.
|
|
*/
|
|
void blk_post_runtime_resume(struct request_queue *q, int err)
|
|
{
|
|
if (!q->dev)
|
|
return;
|
|
if (!err) {
|
|
blk_set_runtime_active(q);
|
|
} else {
|
|
spin_lock_irq(&q->queue_lock);
|
|
q->rpm_status = RPM_SUSPENDED;
|
|
spin_unlock_irq(&q->queue_lock);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(blk_post_runtime_resume);
|
|
|
|
/**
|
|
* blk_set_runtime_active - Force runtime status of the queue to be active
|
|
* @q: the queue of the device
|
|
*
|
|
* If the device is left runtime suspended during system suspend the resume
|
|
* hook typically resumes the device and corrects runtime status
|
|
* accordingly. However, that does not affect the queue runtime PM status
|
|
* which is still "suspended". This prevents processing requests from the
|
|
* queue.
|
|
*
|
|
* This function can be used in driver's resume hook to correct queue
|
|
* runtime PM status and re-enable peeking requests from the queue. It
|
|
* should be called before first request is added to the queue.
|
|
*
|
|
* This function is also called by blk_post_runtime_resume() for successful
|
|
* runtime resumes. It does everything necessary to restart the queue.
|
|
*/
|
|
void blk_set_runtime_active(struct request_queue *q)
|
|
{
|
|
int old_status;
|
|
|
|
if (!q->dev)
|
|
return;
|
|
|
|
spin_lock_irq(&q->queue_lock);
|
|
old_status = q->rpm_status;
|
|
q->rpm_status = RPM_ACTIVE;
|
|
pm_runtime_mark_last_busy(q->dev);
|
|
pm_request_autosuspend(q->dev);
|
|
spin_unlock_irq(&q->queue_lock);
|
|
|
|
if (old_status != RPM_ACTIVE)
|
|
blk_clear_pm_only(q);
|
|
}
|
|
EXPORT_SYMBOL(blk_set_runtime_active);
|