Commit 76a5af84 authored by Kai-Heng Feng's avatar Kai-Heng Feng Committed by Jens Axboe

nvme: explicitly disable APST on quirked devices

A user reports APST is enabled, even when the NVMe is quirked or with
option "default_ps_max_latency_us=0".

The current logic will not set APST if the device is quirked. But the
NVMe in question will enable APST automatically.

Separate the logic "apst is supported" and "to enable apst", so we can
use the latter one to explicitly disable APST at initialiaztion.

BugLink: https://bugs.launchpad.net/bugs/1699004Signed-off-by: default avatarKai-Heng Feng <kai.heng.feng@canonical.com>
Reviewed-by: default avatarAndy Lutomirski <luto@kernel.org>
Signed-off-by: default avatarKeith Busch <keith.busch@intel.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 7aa1f427
...@@ -1549,7 +1549,7 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl) ...@@ -1549,7 +1549,7 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)
if (!table) if (!table)
return; return;
if (ctrl->ps_max_latency_us == 0) { if (!ctrl->apst_enabled || ctrl->ps_max_latency_us == 0) {
/* Turn off APST. */ /* Turn off APST. */
apste = 0; apste = 0;
dev_dbg(ctrl->device, "APST disabled\n"); dev_dbg(ctrl->device, "APST disabled\n");
...@@ -1716,7 +1716,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) ...@@ -1716,7 +1716,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
u64 cap; u64 cap;
int ret, page_shift; int ret, page_shift;
u32 max_hw_sectors; u32 max_hw_sectors;
u8 prev_apsta; bool prev_apst_enabled;
ret = ctrl->ops->reg_read32(ctrl, NVME_REG_VS, &ctrl->vs); ret = ctrl->ops->reg_read32(ctrl, NVME_REG_VS, &ctrl->vs);
if (ret) { if (ret) {
...@@ -1784,16 +1784,17 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) ...@@ -1784,16 +1784,17 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
ctrl->kas = le16_to_cpu(id->kas); ctrl->kas = le16_to_cpu(id->kas);
ctrl->npss = id->npss; ctrl->npss = id->npss;
prev_apsta = ctrl->apsta; ctrl->apsta = id->apsta;
prev_apst_enabled = ctrl->apst_enabled;
if (ctrl->quirks & NVME_QUIRK_NO_APST) { if (ctrl->quirks & NVME_QUIRK_NO_APST) {
if (force_apst && id->apsta) { if (force_apst && id->apsta) {
dev_warn(ctrl->device, "forcibly allowing APST due to nvme_core.force_apst -- use at your own risk\n"); dev_warn(ctrl->device, "forcibly allowing APST due to nvme_core.force_apst -- use at your own risk\n");
ctrl->apsta = 1; ctrl->apst_enabled = true;
} else { } else {
ctrl->apsta = 0; ctrl->apst_enabled = false;
} }
} else { } else {
ctrl->apsta = id->apsta; ctrl->apst_enabled = id->apsta;
} }
memcpy(ctrl->psd, id->psd, sizeof(ctrl->psd)); memcpy(ctrl->psd, id->psd, sizeof(ctrl->psd));
...@@ -1823,9 +1824,9 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) ...@@ -1823,9 +1824,9 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
kfree(id); kfree(id);
if (ctrl->apsta && !prev_apsta) if (ctrl->apst_enabled && !prev_apst_enabled)
dev_pm_qos_expose_latency_tolerance(ctrl->device); dev_pm_qos_expose_latency_tolerance(ctrl->device);
else if (!ctrl->apsta && prev_apsta) else if (!ctrl->apst_enabled && prev_apst_enabled)
dev_pm_qos_hide_latency_tolerance(ctrl->device); dev_pm_qos_hide_latency_tolerance(ctrl->device);
nvme_configure_apst(ctrl); nvme_configure_apst(ctrl);
......
...@@ -167,6 +167,7 @@ struct nvme_ctrl { ...@@ -167,6 +167,7 @@ struct nvme_ctrl {
/* Power saving configuration */ /* Power saving configuration */
u64 ps_max_latency_us; u64 ps_max_latency_us;
bool apst_enabled;
u32 hmpre; u32 hmpre;
u32 hmmin; u32 hmmin;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment