@@ -1184,6 +1184,9 @@ static void nvme_enable_aen(struct nvme_ctrl *ctrl)
u32 result, supported_aens = ctrl->oaes & NVME_AEN_SUPPORTED;
int status;
+ if (IS_ENABLED(CONFIG_THERMAL))
+ supported_aens |= NVME_SMART_CRIT_TEMPERATURE;
+
if (!supported_aens)
return;
@@ -2442,6 +2445,22 @@ void nvme_thermal_zones_unregister(struct nvme_ctrl *ctrl)
}
EXPORT_SYMBOL_GPL(nvme_thermal_zones_unregister);
+static void nvme_thermal_notify_framework(struct nvme_ctrl *ctrl)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ctrl->tzdev); i++) {
+ if (ctrl->tzdev[i])
+ thermal_notify_framework(ctrl->tzdev[i], 0);
+ }
+}
+
+#else
+
+static void nvme_thermal_notify_framework(struct nvme_ctrl *ctrl)
+{
+}
+
#endif /* CONFIG_THERMAL */
struct nvme_core_quirk_entry {
@@ -3857,6 +3876,16 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl)
}
EXPORT_SYMBOL_GPL(nvme_remove_namespaces);
+static void nvme_handle_aen_smart(struct nvme_ctrl *ctrl, u32 result)
+{
+ u32 aer_type = result & NVME_AER_TYPE_MASK;
+ u32 aer_info = (result >> NVME_AER_INFO_SHIFT) & NVME_AER_INFO_MASK;
+
+ if (aer_type == NVME_AER_SMART &&
+ aer_info == NVME_AER_SMART_TEMP_THRESH)
+ nvme_thermal_notify_framework(ctrl);
+}
+
static void nvme_aen_uevent(struct nvme_ctrl *ctrl)
{
char *envp[2] = { NULL, NULL };
@@ -3878,6 +3907,7 @@ static void nvme_async_event_work(struct work_struct *work)
struct nvme_ctrl *ctrl =
container_of(work, struct nvme_ctrl, async_event_work);
+ nvme_handle_aen_smart(ctrl, ctrl->aen_result);
nvme_aen_uevent(ctrl);
ctrl->ops->submit_async_event(ctrl);
}
@@ -507,6 +507,7 @@ enum {
};
enum {
+ NVME_AER_TYPE_MASK = 0x7,
NVME_AER_ERROR = 0,
NVME_AER_SMART = 1,
NVME_AER_NOTICE = 2,
@@ -515,6 +516,12 @@ enum {
};
enum {
+ NVME_AER_INFO_SHIFT = 8,
+ NVME_AER_INFO_MASK = 0xff,
+ NVME_AER_SMART_TEMP_THRESH = 0x01,
+};
+
+enum {
NVME_AER_NOTICE_NS_CHANGED = 0x00,
NVME_AER_NOTICE_FW_ACT_STARTING = 0x01,
NVME_AER_NOTICE_ANA = 0x03,
This enables the reporting of asynchronous events from the controller when the temperature reached or exceeded a temperature threshold. In the case of the temperature threshold conditions, this notifies the thermal framework. Cc: Zhang Rui <rui.zhang@intel.com> Cc: Eduardo Valentin <edubezval@gmail.com> Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Cc: Keith Busch <keith.busch@intel.com> Cc: Jens Axboe <axboe@fb.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Sagi Grimberg <sagi@grimberg.me> Cc: Minwoo Im <minwoo.im.dev@gmail.com> Cc: Kenneth Heitke <kenneth.heitke@intel.com> Cc: Chaitanya Kulkarni <Chaitanya.Kulkarni@wdc.com> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> --- * v2 - New patch since v2 - Extracted from 'add thermal zone infrastructure' patch drivers/nvme/host/core.c | 30 ++++++++++++++++++++++++++++++ include/linux/nvme.h | 7 +++++++ 2 files changed, 37 insertions(+)