[PATCH] nvme-sysfs: add tmt1 and tmt2 attributes

Tokunori Ikegami ikegami.t at gmail.com
Sat Nov 9 22:32:52 PST 2024


The throttling temperature feature not supported by hwmon.
So add temperature feature values as sysfs attributes.

Signed-off-by: Tokunori Ikegami <ikegami.t at gmail.com>
---
 drivers/nvme/host/sysfs.c | 90 +++++++++++++++++++++++++++++++++++++++
 include/linux/nvme.h      |  5 +++
 2 files changed, 95 insertions(+)

diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c
index b68a9e5f1ea3..d376b51e67b3 100644
--- a/drivers/nvme/host/sysfs.c
+++ b/drivers/nvme/host/sysfs.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/nvme-auth.h>
+#include <linux/units.h>
 
 #include "nvme.h"
 #include "fabrics.h"
@@ -664,6 +665,93 @@ 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 nvme_ctrl_tmt_show(struct device *dev, bool tmt2,
+				  struct device_attribute *attr, char *buf)
+{
+	struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
+	int ret;
+	u32 status;
+	long val;
+
+	ret = nvme_get_features(ctrl, NVME_FEAT_HCTM, 0, NULL, 0, &status);
+	if (ret)
+		return sysfs_emit(buf, "error\n");
+
+	if (tmt2)
+		val = status & NVME_HCTM_TMT_MASK;
+	else
+		val = status >> NVME_HCTM_TMT1_SHIFT;
+	if (!val)
+		return sysfs_emit(buf, "off\n");
+
+	return sysfs_emit(buf, "%ld\n", kelvin_to_millicelsius(val));
+}
+
+static ssize_t nvme_ctrl_tmt_store(struct device *dev,
+				   struct device_attribute *attr, bool tmt2,
+				   const char *buf, size_t count)
+{
+	struct nvme_ctrl *ctrl = dev_get_drvdata(dev);
+	unsigned int v = 0;
+	int err;
+	int ret;
+	u32 status;
+
+	err = kstrtou32(buf, 10, &v);
+	if (err)
+		return err;
+
+	if (tmt2)
+		v <<= NVME_HCTM_TMT1_SHIFT;
+
+	ret = nvme_get_features(ctrl, NVME_FEAT_HCTM, 0, NULL, 0, &status);
+	if (ret > 0)
+		return -EIO;
+	if (ret < 0)
+		return ret;
+
+	if (tmt2)
+		v |= status << NVME_HCTM_TMT1_SHIFT;
+	else
+		v |= status & NVME_HCTM_TMT_MASK;
+
+	ret = nvme_set_features(ctrl, NVME_FEAT_HCTM, v, NULL, 0, NULL);
+	if (ret > 0)
+		return -EIO;
+
+	return count;
+}
+
+static ssize_t nvme_ctrl_tmt1_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	return nvme_ctrl_tmt_show(dev, false, attr, buf);
+}
+
+static ssize_t nvme_ctrl_tmt1_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	return nvme_ctrl_tmt_store(dev, attr, false, buf, count);
+}
+static DEVICE_ATTR(tmt1, S_IRUGO | S_IWUSR, nvme_ctrl_tmt1_show,
+		   nvme_ctrl_tmt1_store);
+
+static ssize_t nvme_ctrl_tmt2_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	return nvme_ctrl_tmt_show(dev, true, attr, buf);
+}
+
+static ssize_t nvme_ctrl_tmt2_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	return nvme_ctrl_tmt_store(dev, attr, true, buf, count);
+}
+static DEVICE_ATTR(tmt2, S_IRUGO | S_IWUSR, nvme_ctrl_tmt2_show,
+		   nvme_ctrl_tmt2_store);
+
 static struct attribute *nvme_dev_attrs[] = {
 	&dev_attr_reset_controller.attr,
 	&dev_attr_rescan_controller.attr,
@@ -692,6 +780,8 @@ static struct attribute *nvme_dev_attrs[] = {
 	&dev_attr_dhchap_ctrl_secret.attr,
 #endif
 	&dev_attr_adm_passthru_err_log_enabled.attr,
+	&dev_attr_tmt1.attr,
+	&dev_attr_tmt2.attr,
 	NULL
 };
 
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index b58d9405d65e..89db23b57e6d 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -1144,6 +1144,11 @@ enum {
 	NVME_ENABLE_LBAFEE	= 1,
 };
 
+enum {
+	NVME_HCTM_TMT_MASK	= 0xffff,
+	NVME_HCTM_TMT1_SHIFT	= 16,
+};
+
 /* Admin commands */
 
 enum nvme_admin_opcode {
-- 
2.45.2




More information about the Linux-nvme mailing list