Skip to content

Commit

Permalink
nvme: Add APST payload overriding
Browse files Browse the repository at this point in the history
The apst_data tunable allows APST configuration to be adjusted
during controller initialization.  It accepts an array of encoded
integers, each defining specific transition parameters.

Signed-off-by: Alexey Sukhoguzov <[email protected]>
  • Loading branch information
eseipi committed Oct 31, 2024
1 parent ae098ac commit b574aae
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 7 deletions.
12 changes: 12 additions & 0 deletions share/man/man4/nvme.4
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,18 @@ hw.nvme.apst_enable=1
.Ed
.Pp
The default vendor-provided settings, if any, will be applied.
To override this, set the following tunable:
.Bd -literal -offset indent
hw.nvme.apst_data
.Ed
.Pp
The string must contain up to 32 encoded integers, e.g. "0x6418 0
0 0x3e820".
Each value corresponds to a specific available power state starting
from the lowest, and defines the target state (bits 3..7) to
transition to, as well as the idle time in milliseconds (bits 8..31)
to wait before that transition.
Bits 0..2 must be zero.
.Pp
The
.Xr nvd 4
Expand Down
21 changes: 14 additions & 7 deletions sys/dev/nvme/nvme_ctrlr.c
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,7 @@ nvme_ctrlr_configure_apst(struct nvme_controller *ctrlr)
struct nvme_completion_poll_status status;
uint64_t *data;
int data_size = 32 * sizeof(*data);
int i, read_size;
bool enable;

if (TUNABLE_BOOL_FETCH("hw.nvme.apst_enable", &enable) == 0 ||
Expand All @@ -902,14 +903,20 @@ nvme_ctrlr_configure_apst(struct nvme_controller *ctrlr)
if ((data = malloc(data_size, M_NVME, M_WAITOK | M_ZERO)) == NULL)
goto fail;

status.done = 0;
nvme_ctrlr_cmd_get_feature(ctrlr,
NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION, 0,
data, data_size, nvme_completion_poll_cb, &status);
if (getenv_array("hw.nvme.apst_data", data, data_size,
&read_size, sizeof(*data), GETENV_UNSIGNED) != 0) {
for (i = 0; i < read_size / sizeof(*data); ++i)
data[i] = htole64(data[i]);
} else {
status.done = 0;
nvme_ctrlr_cmd_get_feature(ctrlr,
NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION, 0,
data, data_size, nvme_completion_poll_cb, &status);

nvme_completion_poll(&status);
if (nvme_completion_is_error(&status.cpl))
goto fail;
nvme_completion_poll(&status);
if (nvme_completion_is_error(&status.cpl))
goto fail;
}

status.done = 0;
nvme_ctrlr_cmd_set_feature(ctrlr,
Expand Down

0 comments on commit b574aae

Please sign in to comment.