Add sysfs knobs for the following parameters: dev_freq_timeout_ms: for clearing up the device frequency limit when latency-intensive block IO is complete This can be used to prevent delayed responses to latency-sensitive block I/O operations when storage device operate at low frequency. By implementing the "dev_freq_timeout_ms", it automatically restores device frequency constraints throug PM QoS. Signed-off-by: Wang Jianzheng <wangjianzheng@xxxxxxxx> --- block/genhd.c | 23 +++++++++++++++++++++++ include/linux/blkdev.h | 2 ++ 2 files changed, 25 insertions(+) diff --git a/block/genhd.c b/block/genhd.c index 9bbc38d12792..9462a81501a8 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -1159,6 +1159,27 @@ static ssize_t partscan_show(struct device *dev, return sysfs_emit(buf, "%u\n", disk_has_partscan(dev_to_disk(dev))); } +static ssize_t dev_freq_timeout_ms_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gendisk *disk = dev_to_disk(dev); + + return sprintf(buf, "%d\n", disk->dev_freq_timeout); +} + +static ssize_t dev_freq_timeout_ms_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct gendisk *disk = dev_to_disk(dev); + int i; + + if (count > 0 && !kstrtoint(buf, 10, &i)) + disk->dev_freq_timeout = i; + + return count; +} + static DEVICE_ATTR(range, 0444, disk_range_show, NULL); static DEVICE_ATTR(ext_range, 0444, disk_ext_range_show, NULL); static DEVICE_ATTR(removable, 0444, disk_removable_show, NULL); @@ -1173,6 +1194,7 @@ static DEVICE_ATTR(inflight, 0444, part_inflight_show, NULL); static DEVICE_ATTR(badblocks, 0644, disk_badblocks_show, disk_badblocks_store); static DEVICE_ATTR(diskseq, 0444, diskseq_show, NULL); static DEVICE_ATTR(partscan, 0444, partscan_show, NULL); +static DEVICE_ATTR_RW(dev_freq_timeout_ms); #ifdef CONFIG_FAIL_MAKE_REQUEST ssize_t part_fail_show(struct device *dev, @@ -1224,6 +1246,7 @@ static struct attribute *disk_attrs[] = { &dev_attr_events_poll_msecs.attr, &dev_attr_diskseq.attr, &dev_attr_partscan.attr, + &dev_attr_dev_freq_timeout_ms.attr, #ifdef CONFIG_FAIL_MAKE_REQUEST &dev_attr_fail.attr, #endif diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index fe1797bbec42..950ad047dd81 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -213,6 +213,8 @@ struct gendisk { u64 diskseq; blk_mode_t open_mode; + int dev_freq_timeout; + /* * Independent sector access ranges. This is always NULL for * devices that do not have multiple independent access ranges. -- 2.34.1