From: Yaxiong Tian <iambestgod@qq.com>
To: kbusch@kernel.org, axboe@kernel.dk, hch@lst.de, sagi@grimberg.me,
chaitanyak@nvidia.com
Cc: linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org,
Yaxiong Tian <tianyaxiong@kylinos.cn>,
Chaitanya Kulkarni <kch@nvidia.com>
Subject: [PATCH v4 2/3] nvme: add sysfs interface for APST table updates
Date: Thu, 3 Apr 2025 15:22:16 +0800 [thread overview]
Message-ID: <tencent_776C8C1D08FD8F3CE58CD91E7572FEA6970A@qq.com> (raw)
In-Reply-To: <tencent_A9D89C90E6484E0EBFED4F67D6EF4589F506@qq.com>
From: Yaxiong Tian <tianyaxiong@kylinos.cn>
In desktop systems, users can choose between power-saving mode and
performance mode. These two modes involve different trade-offs between
NVMe performance and power efficiency, thus requiring dynamic updates to APST.
Currently, the APST (Autonomous Power State Transition) table can only be
updated during module initialization via module parameters or indirectly
by setting QoS latency requirements. This patch adds a direct sysfs
interface to allow dynamic updates to the APST table at runtime.
The new sysfs entry is created at:
/sys/class/nvme/<controller>/apst_update
This provides more flexibility in power management tuning without
requiring module reload or QoS latency changes.
Example usage:
update nvme module parameters.
echo 1 > /sys/class/nvme/nvme0/apst_update
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Yaxiong Tian <tianyaxiong@kylinos.cn>
---
drivers/nvme/host/core.c | 9 +++++++--
drivers/nvme/host/nvme.h | 2 ++
drivers/nvme/host/sysfs.c | 24 ++++++++++++++++++++++++
3 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index eca0d0d2c2b4..19438da102e5 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2654,7 +2654,7 @@ static bool nvme_apst_get_transition_time(u64 total_latency,
*
* Users can set ps_max_latency_us to zero to turn off APST.
*/
-static int nvme_configure_apst(struct nvme_ctrl *ctrl)
+int nvme_configure_apst(struct nvme_ctrl *ctrl)
{
struct nvme_feat_auto_pst *table;
unsigned apste = 0;
@@ -2779,8 +2779,11 @@ static void nvme_set_latency_tolerance(struct device *dev, s32 val)
if (ctrl->ps_max_latency_us != latency) {
ctrl->ps_max_latency_us = latency;
- if (nvme_ctrl_state(ctrl) == NVME_CTRL_LIVE)
+ if (nvme_ctrl_state(ctrl) == NVME_CTRL_LIVE) {
+ mutex_lock(&ctrl->apst_lock);
nvme_configure_apst(ctrl);
+ mutex_unlock(&ctrl->apst_lock);
+ }
}
}
@@ -4853,6 +4856,8 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
ctrl->ka_cmd.common.opcode = nvme_admin_keep_alive;
ctrl->ka_last_check_time = jiffies;
+ mutex_init(&ctrl->apst_lock);
+
BUILD_BUG_ON(NVME_DSM_MAX_RANGES * sizeof(struct nvme_dsm_range) >
PAGE_SIZE);
ctrl->discard_page = alloc_page(GFP_KERNEL);
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 51e078642127..7f8e10f5bf7a 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -385,6 +385,7 @@ struct nvme_ctrl {
key_serial_t tls_pskid;
/* Power saving configuration */
+ struct mutex apst_lock;
u64 ps_max_latency_us;
bool apst_enabled;
@@ -828,6 +829,7 @@ void nvme_unfreeze(struct nvme_ctrl *ctrl);
void nvme_wait_freeze(struct nvme_ctrl *ctrl);
int nvme_wait_freeze_timeout(struct nvme_ctrl *ctrl, long timeout);
void nvme_start_freeze(struct nvme_ctrl *ctrl);
+int nvme_configure_apst(struct nvme_ctrl *ctrl);
static inline enum req_op nvme_req_op(struct nvme_command *cmd)
{
diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c
index 6d31226f7a4f..20146eb4c671 100644
--- a/drivers/nvme/host/sysfs.c
+++ b/drivers/nvme/host/sysfs.c
@@ -684,6 +684,29 @@ static DEVICE_ATTR(dhchap_ctrl_secret, S_IRUGO | S_IWUSR,
nvme_ctrl_dhchap_ctrl_secret_show, nvme_ctrl_dhchap_ctrl_secret_store);
#endif
+static ssize_t apst_update_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
+ bool bool_data = false;
+ int err;
+
+ err = kstrtobool(buf, &bool_data);
+
+ if (err)
+ return err;
+
+ if (bool_data && nvme_ctrl_state(ctrl) == NVME_CTRL_LIVE) {
+ mutex_lock(&ctrl->apst_lock);
+ nvme_configure_apst(ctrl);
+ mutex_unlock(&ctrl->apst_lock);
+ }
+
+ return size;
+}
+static DEVICE_ATTR_WO(apst_update);
+
static struct attribute *nvme_dev_attrs[] = {
&dev_attr_reset_controller.attr,
&dev_attr_rescan_controller.attr,
@@ -712,6 +735,7 @@ static struct attribute *nvme_dev_attrs[] = {
&dev_attr_dhchap_ctrl_secret.attr,
#endif
&dev_attr_adm_passthru_err_log_enabled.attr,
+ &dev_attr_apst_update.attr,
NULL
};
--
2.25.1
next prev parent reply other threads:[~2025-04-03 7:27 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-03 7:21 [PATCH v4 0/3] nvme: Add sysfs interface for APST configuration management Yaxiong Tian
2025-04-03 7:22 ` [PATCH v4 1/3] nvme: Add warning for PST table memory allocation failure in nvme_configure_apst Yaxiong Tian
2025-04-03 7:22 ` Yaxiong Tian [this message]
2025-04-03 7:22 ` [PATCH v4 3/3] nvme: add per-controller sysfs interface for APST configuration Yaxiong Tian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tencent_776C8C1D08FD8F3CE58CD91E7572FEA6970A@qq.com \
--to=iambestgod@qq.com \
--cc=axboe@kernel.dk \
--cc=chaitanyak@nvidia.com \
--cc=hch@lst.de \
--cc=kbusch@kernel.org \
--cc=kch@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=sagi@grimberg.me \
--cc=tianyaxiong@kylinos.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®