Commit fab335a3 authored by Kai-Heng Feng's avatar Kai-Heng Feng Committed by Kleber Sacilotto de Souza

nvme: only consider exit latency when choosing useful non-op power states

BugLink: https://bugs.launchpad.net/bugs/1664602

When a NVMe is in non-op states, the latency is exlat.
The latency will be enlat + exlat only when the NVMe tries to transit
from operational state right atfer it begins to transit to
non-operational state, which should be a rare case.

Therefore, as Andy Lutomirski suggests, use exlat only when deciding power
states to trainsit to.
Signed-off-by: default avatarKai-Heng Feng <kai.heng.feng@canonical.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
(backported from commit da87591b)
Signed-off-by: default avatarKai-Heng Feng <kai.heng.feng@canonical.com>
Acked-By: default avatarAceLan Kao <acelan.kao@canonical.com>
Acked-By: default avatarShrirang Bagul <shrirang.bagul@canonical.com>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
parent ef6a4d76
...@@ -894,8 +894,8 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl) ...@@ -894,8 +894,8 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)
* heuristic: we are willing to spend at most 2% of the time * heuristic: we are willing to spend at most 2% of the time
* transitioning between power states. Therefore, when running * transitioning between power states. Therefore, when running
* in any given state, we will enter the next lower-power * in any given state, we will enter the next lower-power
* non-operational state after waiting 100 * (enlat + exlat) * non-operational state after waiting 50 * (enlat + exlat)
* microseconds, as long as that state's total latency is under * microseconds, as long as that state's exit latency is under
* the requested maximum latency. * the requested maximum latency.
* *
* We will not autonomously enter any non-operational state for * We will not autonomously enter any non-operational state for
...@@ -937,7 +937,7 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl) ...@@ -937,7 +937,7 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)
* lowest-power state, not the number of states. * lowest-power state, not the number of states.
*/ */
for (state = (int)ctrl->npss; state >= 0; state--) { for (state = (int)ctrl->npss; state >= 0; state--) {
u64 total_latency_us, transition_ms; u64 total_latency_us, exit_latency_us, transition_ms;
if (target) if (target)
table->entries[state] = target; table->entries[state] = target;
...@@ -958,12 +958,15 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl) ...@@ -958,12 +958,15 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)
NVME_PS_FLAGS_NON_OP_STATE)) NVME_PS_FLAGS_NON_OP_STATE))
continue; continue;
total_latency_us = exit_latency_us =
(u64)le32_to_cpu(ctrl->psd[state].entry_lat) + (u64)le32_to_cpu(ctrl->psd[state].exit_lat);
+ le32_to_cpu(ctrl->psd[state].exit_lat); if (exit_latency_us > ctrl->ps_max_latency_us)
if (total_latency_us > ctrl->ps_max_latency_us)
continue; continue;
total_latency_us =
exit_latency_us +
le32_to_cpu(ctrl->psd[state].entry_lat);
/* /*
* This state is good. Use it as the APST idle * This state is good. Use it as the APST idle
* target for higher power states. * target for higher power states.
......
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