From: Liao Xuan <liaoxuan@hygon.cn>
NVMe devices are commonly left trained at the maximum PCIe link rate
even when there is little or no I/O activity, which wastes power in
both the device and the surrounding platform.
This series adds adaptive PCIe link rate switching to the NVMe host
driver. The link is downgraded to a configurable minimum rate when
I/O activity is low to save power, and upgraded back to the maximum
supported rate as soon as the workload requires it, so that peak
performance is maintained under load.
The amount of transferred data is accumulated on the submission path
with per-CPU counters and evaluated by a per-controller timer. The
switch threshold is derived from the bandwidth of the minimum and
maximum link rates such that the extra time required to transfer the
data at the minimum rate does not exceed the estimated link retraining
time. The controller queues are frozen while the link is retrained
and resumed afterwards, so no I/O is lost or times out during the
switch.
The main functions of each patch are as follows:
1. Patch 1 adds the core switching functionality. It uses the target
link speed interface of the PCIe bandwidth controller, which is
exported for this purpose.
2. Patch 2 adds hysteresis and idle detection to the switching policy.
The link is upgraded immediately once the threshold is exceeded, but
only downgraded after a number of consecutive below-threshold windows,
which prevents excessive rate toggling under fluctuating workloads.
Monitoring is stopped after a period of inactivity and re-armed by the
next I/O.
3. Patch 3 exposes the switching parameters (enable, monitor_interval,
min_speed, up_threshold, down_threshold) via sysfs so that the
power/performance trade-off can be tuned at runtime without a reboot.
The feature is currently enabled on Hygon platforms.
Liao Xuan (3):
nvme: Add adaptive PCIe link rate switching function
nvme: Add hysteresis and idle detection to link rate switching
nvme: Expose link rate switching tunables via sysfs
drivers/nvme/host/Kconfig | 10 +
drivers/nvme/host/Makefile | 1 +
drivers/nvme/host/core.c | 4 +
drivers/nvme/host/nvme.h | 50 ++++
drivers/nvme/host/pci.c | 4 +
drivers/nvme/host/speed_switch.c | 424 +++++++++++++++++++++++++++++++
drivers/nvme/host/sysfs.c | 143 +++++++++++
drivers/pci/pcie/bwctrl.c | 1 +
8 files changed, 637 insertions(+)
create mode 100644 drivers/nvme/host/speed_switch.c
--
2.43.0