Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da87591b authored by Kai-Heng Feng's avatar Kai-Heng Feng Committed by Christoph Hellwig
Browse files

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



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>
parent 24b7f059
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -1342,7 +1342,7 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)
	 * transitioning between power states.  Therefore, when running
	 * in any given state, we will enter the next lower-power
	 * 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.
	 *
	 * We will not autonomously enter any non-operational state for
@@ -1387,7 +1387,7 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)
		 * lowest-power state, not the number of states.
		 */
		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)
				table->entries[state] = target;
@@ -1408,12 +1408,15 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)
			      NVME_PS_FLAGS_NON_OP_STATE))
				continue;

			total_latency_us =
				(u64)le32_to_cpu(ctrl->psd[state].entry_lat) +
				+ le32_to_cpu(ctrl->psd[state].exit_lat);
			if (total_latency_us > ctrl->ps_max_latency_us)
			exit_latency_us =
				(u64)le32_to_cpu(ctrl->psd[state].exit_lat);
			if (exit_latency_us > ctrl->ps_max_latency_us)
				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
			 * target for higher power states.