From patchwork Tue May 21 16:04:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akinobu Mita X-Patchwork-Id: 10954225 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 84DA5912 for ; Tue, 21 May 2019 16:04:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 73C062870C for ; Tue, 21 May 2019 16:04:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 67BCA289B8; Tue, 21 May 2019 16:04:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 046A7288C6 for ; Tue, 21 May 2019 16:04:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727044AbfEUQEa (ORCPT ); Tue, 21 May 2019 12:04:30 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:33256 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726900AbfEUQEa (ORCPT ); Tue, 21 May 2019 12:04:30 -0400 Received: by mail-pg1-f194.google.com with SMTP id h17so8829079pgv.0 for ; Tue, 21 May 2019 09:04:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6dlMq3dpaZqEx6RvkbThMUhOu6jgvPwAdvzh6RwJDA0=; b=UXbb6DZCMg+n2Zx4oEbLKC8bmid3+/k3Q2MXADkFHbjAjtQDs68vUSqOkHxpLdQQvj IdSCqNvmOTIJNEcjROZ73h3Vsfwb4gEpftRpcfjlCDKuv/HjhEmSfPKkVGB0Jef0u37Y IcThgB2sa6uYiQJu/yqord6qk3e6N8MUhRdo4zLDNInQ75oXXcKiaXUO1iW0yxYcuQWA N/YRhhWvRJoEAynJcR2lGQRXhNQu3i/ICwOMRizqN5PedpjyfhYlxG+MAFzt8Sxdpl/B bfMwNdRr2GmgENA2xPAEYuTbDXgZdO+2Q7TDQHESah0Juvy/BFdw+lnlTf60RLKJJYpX zSYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=6dlMq3dpaZqEx6RvkbThMUhOu6jgvPwAdvzh6RwJDA0=; b=SRT00aom+J9x9ZLqXxV+se7rDH7kqCLj/ALowZBRhyvMMfkGNX8Jut4NB6SqyPI9Ld dW6oH+cCyeycssX14ACRMlFiazsARYZCszfbbSqf8Utr2N+H7p2JRgOZlxLJ83cCRxgH 4xvAGpFQZ9NYvSB4ZugmmNDJQMOYFcZFWGzrAtM6gn1/+84TfqGU1W1lcoCoKdx1v7X/ mVqbDqDj9s3Lo2/A1UdFI10ucPMl33YaY6Pp34zF3BHyk6igxxDBuoL9+hm1qoVkYzuw 5FfP6JtbWk4lBB+mNwU4MXtfyjMeAqnz4nCYdqfKDhkEE6yMEp7kxtAYLP5NCmftPJSr FY4Q== X-Gm-Message-State: APjAAAVKwucaYx6sStbWjJxSMUEWh1u7Wlgq8K4T+UK3x+738dXDCnVU jonYt2rialw3JH1XNkhPGcc= X-Google-Smtp-Source: APXvYqyUUrUZ+4NnabA9Wx9gAGu/svtfuvfgqSe7HwMr/XlguJFBuG5TdL72j8yys3dc1aV5Up1BAA== X-Received: by 2002:a62:ac0c:: with SMTP id v12mr5965733pfe.59.1558454669807; Tue, 21 May 2019 09:04:29 -0700 (PDT) Received: from mita-MS-7A45.lan ([240f:34:212d:1:9cd0:73e8:b74a:624e]) by smtp.gmail.com with ESMTPSA id j5sm28954786pfa.15.2019.05.21.09.04.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 21 May 2019 09:04:29 -0700 (PDT) From: Akinobu Mita To: linux-nvme@lists.infradead.org, linux-pm@vger.kernel.org Cc: Keith Busch Subject: [PATCH v2 1/4] nvme: Export get and set features Date: Wed, 22 May 2019 01:04:06 +0900 Message-Id: <1558454649-28783-2-git-send-email-akinobu.mita@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1558454649-28783-1-git-send-email-akinobu.mita@gmail.com> References: <1558454649-28783-1-git-send-email-akinobu.mita@gmail.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Keith Busch Future use intends to make use of features, so export these functions. And since their implementation is identical except for the opcode, provide a new convenience function that implement each. Signed-off-by: Keith Busch --- drivers/nvme/host/core.c | 22 +++++++++++++++++++--- drivers/nvme/host/nvme.h | 4 ++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index d352145..c04df80 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1113,15 +1113,15 @@ static struct nvme_id_ns *nvme_identify_ns(struct nvme_ctrl *ctrl, return id; } -static int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11, - void *buffer, size_t buflen, u32 *result) +static int nvme_features(struct nvme_ctrl *dev, u8 op, unsigned fid, + unsigned dword11, void *buffer, size_t buflen, u32 *result) { struct nvme_command c; union nvme_result res; int ret; memset(&c, 0, sizeof(c)); - c.features.opcode = nvme_admin_set_features; + c.features.opcode = op; c.features.fid = cpu_to_le32(fid); c.features.dword11 = cpu_to_le32(dword11); @@ -1132,6 +1132,22 @@ static int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword return ret; } +int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11, + void *buffer, size_t buflen, u32 *result) +{ + return nvme_features(dev, nvme_admin_set_features, fid, dword11, buffer, + buflen, result); +} +EXPORT_SYMBOL_GPL(nvme_set_features); + +int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11, + void *buffer, size_t buflen, u32 *result) +{ + return nvme_features(dev, nvme_admin_get_features, fid, dword11, buffer, + buflen, result); +} +EXPORT_SYMBOL_GPL(nvme_get_features); + int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count) { u32 q_count = (*count - 1) | ((*count - 1) << 16); diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 56bba7a..bb673b8 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -459,6 +459,10 @@ int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, union nvme_result *result, void *buffer, unsigned bufflen, unsigned timeout, int qid, int at_head, blk_mq_req_flags_t flags, bool poll); +int nvme_set_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11, + void *buffer, size_t buflen, u32 *result); +int nvme_get_features(struct nvme_ctrl *dev, unsigned fid, unsigned dword11, + void *buffer, size_t buflen, u32 *result); int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count); void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); int nvme_reset_ctrl(struct nvme_ctrl *ctrl); From patchwork Tue May 21 16:04:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akinobu Mita X-Patchwork-Id: 10954227 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 709A3912 for ; Tue, 21 May 2019 16:04:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5E03C2898C for ; Tue, 21 May 2019 16:04:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5253F28AB2; Tue, 21 May 2019 16:04:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5EC222898C for ; Tue, 21 May 2019 16:04:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728283AbfEUQEg (ORCPT ); Tue, 21 May 2019 12:04:36 -0400 Received: from mail-pg1-f196.google.com ([209.85.215.196]:40445 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726900AbfEUQEf (ORCPT ); Tue, 21 May 2019 12:04:35 -0400 Received: by mail-pg1-f196.google.com with SMTP id d30so8810055pgm.7 for ; Tue, 21 May 2019 09:04:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=sSr8nkvct0PINiUcW2z/dRf5WMflIfwH+kfGGvza1dA=; b=EN9xdML3GPWW6if/DegN7gnOgJ/ylDKpImbGaqXsyTNCLifEbwPhS/OxnGik4pX0Go AI+uDJoeRd3biujIuMzne3A4rZ9q/3mN0NdoPKPHHnnZYKmzSmeJS+RE/Fh6Fvgd4i+Y 7td+8ayR0ipQgJeOoFdNuBqkEOlZgynvRBavv14Y6nEXXnwE2jXF+i6S/7aPGs7nmP+h cooOC+rYMXaEEGXM0eyY+auxLfph+4aN4+PVSQ+fgwenUgc4BIj4MXwUopW007JXVka4 0AioyRFxQMl2WLceLDE8hBi+qVyF5+zdnMIbhhDkBcx0NjGIraUDDlONpR0WoliUmhYC PqeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=sSr8nkvct0PINiUcW2z/dRf5WMflIfwH+kfGGvza1dA=; b=eVr4yYLnG3s426hg4HE3mZtM6Z8vo92162iD+Cln2/ZYm/Whz6OS2Dyauzp1fYgH4X yFs1If5tbp1bKlDcrqTuepKz0F1icL7QzL/xpqLw8ynzxW7bvs3UvQACR3RfDOi9Tjpt 8EvReq+HJHTa7j83nVpbWmnGYISZBgDh6Inw4U1hdoSWlWHQkcinplziZTtKPT9Rg6MU 9kktzHziIEUqkckqKrVLYy4F9vyJu2vavJLOkbdDXXZh+OjJTvpMchvqIR0Zhpl5/34J R4lGUtoMoH8YvwoyYqfdyk7+FqCFM8wTGVeTR44rcIGxnshO0ug2RUN4mHS/Dc4KCky4 J62w== X-Gm-Message-State: APjAAAWc/BRSwp54M12TVic8zpEHQQq/kY2sKjUcJ1ZW7G4CpFLb2+y/ sYsz5cwllWyBkTfHkHbwjm0= X-Google-Smtp-Source: APXvYqxsW/G05VwkA4xBnoiJwkdmOQdzA2cxqKxNOk0EPdogZeJzhC9oJNqzYzwlZHG3FA0Qp8jyAQ== X-Received: by 2002:a65:64c9:: with SMTP id t9mr82695090pgv.221.1558454674300; Tue, 21 May 2019 09:04:34 -0700 (PDT) Received: from mita-MS-7A45.lan ([240f:34:212d:1:9cd0:73e8:b74a:624e]) by smtp.gmail.com with ESMTPSA id j5sm28954786pfa.15.2019.05.21.09.04.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 21 May 2019 09:04:33 -0700 (PDT) From: Akinobu Mita To: linux-nvme@lists.infradead.org, linux-pm@vger.kernel.org Cc: Akinobu Mita , Zhang Rui , Eduardo Valentin , Daniel Lezcano , Keith Busch , Jens Axboe , Christoph Hellwig , Sagi Grimberg , Minwoo Im , Kenneth Heitke , Chaitanya Kulkarni Subject: [PATCH v2 2/4] nvme: add thermal zone infrastructure Date: Wed, 22 May 2019 01:04:07 +0900 Message-Id: <1558454649-28783-3-git-send-email-akinobu.mita@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1558454649-28783-1-git-send-email-akinobu.mita@gmail.com> References: <1558454649-28783-1-git-send-email-akinobu.mita@gmail.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The NVMe controller reports up to nine temperature values in the SMART / Health log page (the composite temperature and temperature sensor 1 through temperature sensor 8). The temperature threshold feature (Feature Identifier 04h) configures the asynchronous event request command to complete when the temperature is crossed its corresponding temperature threshold. This adds infrastructure to provide these temperatures and thresholds via thermal zone devices. The nvme_thermal_zones_register() creates up to nine thermal zone devices for all implemented temperature sensors including the composite temperature. /sys/class/thermal/thermal_zone[0-*]: |---temp: Temperature |---trip_point_0_temp: Over temperature threshold The thermal_zone[0-*] contains a symlink to the corresponding nvme device. On the other hand, the following symlinks to the thermal zone devices are created in the nvme device sysfs directory. - nvme_temp0: Composite temperature - nvme_temp1: Temperature sensor 1 ... - nvme_temp8: Temperature sensor 8 The nvme_thermal_zones_unregister() removes the registered thermal zone devices and symlinks. Cc: Zhang Rui Cc: Eduardo Valentin Cc: Daniel Lezcano Cc: Keith Busch Cc: Jens Axboe Cc: Christoph Hellwig Cc: Sagi Grimberg Cc: Minwoo Im Cc: Kenneth Heitke Cc: Chaitanya Kulkarni Signed-off-by: Akinobu Mita --- * v2 - s/correspoinding/corresponding/ typo in commit log - Borrowed nvme_get_features() from Keith's patch - Temperature threshold notification is splitted into another patch - Change the data type of 'sensor' to unsigned - Add BUILD_BUG_ON for the array size of tzdev member in nvme_ctrl - Add WARN_ON_ONCE for paranoid checks - Fix off-by-one error in nvme_get_temp - Validate 'sensor' where the value is actually used - Define and utilize two enums related to the temperature threshold feature - Remove hysteresis value for this trip point and don't utilize the under temperature threshold - Print error message for thermal_zone_device_register() failure - Add function comments for nvme_thermal_zones_{,un}register - Suppress non-fatal errors from nvme_thermal_zones_register() - Add comment about implemented temperature sensors - Instead of creating a new 'thermal_work', append async smart event's action to the existing async_event_work - Add comment for tzdev member in nvme_ctrl drivers/nvme/host/core.c | 265 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/nvme/host/nvme.h | 27 +++++ include/linux/nvme.h | 5 + 3 files changed, 297 insertions(+) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index c04df80..0ec303c 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -2179,6 +2179,271 @@ static void nvme_set_latency_tolerance(struct device *dev, s32 val) } } +#ifdef CONFIG_THERMAL + +static int nvme_get_temp(struct nvme_ctrl *ctrl, unsigned int sensor, int *temp) +{ + struct nvme_smart_log *log; + int ret; + + BUILD_BUG_ON(ARRAY_SIZE(log->temp_sensor) + 1 != + ARRAY_SIZE(ctrl->tzdev)); + + if (WARN_ON_ONCE(sensor > ARRAY_SIZE(log->temp_sensor))) + return -EINVAL; + + log = kzalloc(sizeof(*log), GFP_KERNEL); + if (!log) + return -ENOMEM; + + ret = nvme_get_log(ctrl, NVME_NSID_ALL, NVME_LOG_SMART, 0, + log, sizeof(*log), 0); + if (ret) { + ret = ret > 0 ? -EINVAL : ret; + goto free_log; + } + + if (sensor) + *temp = le16_to_cpu(log->temp_sensor[sensor - 1]); + else + *temp = get_unaligned_le16(log->temperature); + + if (!*temp) + ret = -EINVAL; + +free_log: + kfree(log); + + return ret; +} + +static unsigned int nvme_tz_type_to_sensor(const char *type) +{ + unsigned int sensor; + + if (sscanf(type, "nvme_temp%u", &sensor) != 1) + return UINT_MAX; + + return sensor; +} + +#define KELVIN_TO_MILLICELSIUS(t) DECI_KELVIN_TO_MILLICELSIUS((t) * 10) +#define MILLICELSIUS_TO_KELVIN(t) ((MILLICELSIUS_TO_DECI_KELVIN(t) + 5) / 10) + +static int nvme_tz_get_temp(struct thermal_zone_device *tzdev, + int *temp) +{ + unsigned int sensor = nvme_tz_type_to_sensor(tzdev->type); + struct nvme_ctrl *ctrl = tzdev->devdata; + int ret; + + ret = nvme_get_temp(ctrl, sensor, temp); + if (!ret) + *temp = KELVIN_TO_MILLICELSIUS(*temp); + + return ret; +} + +static int nvme_tz_get_trip_type(struct thermal_zone_device *tzdev, + int trip, enum thermal_trip_type *type) +{ + *type = THERMAL_TRIP_ACTIVE; + + return 0; +} + +static int nvme_get_over_temp_thresh(struct nvme_ctrl *ctrl, + unsigned int sensor, int *temp) +{ + unsigned int threshold = sensor << NVME_TEMP_THRESH_SELECT_SHIFT; + int status; + int ret; + + if (WARN_ON_ONCE(sensor >= ARRAY_SIZE(ctrl->tzdev))) + return -EINVAL; + + ret = nvme_get_features(ctrl, NVME_FEAT_TEMP_THRESH, threshold, NULL, 0, + &status); + if (!ret) + *temp = status & NVME_TEMP_THRESH_MASK; + + return ret > 0 ? -EINVAL : ret; +} + +static int nvme_set_over_temp_thresh(struct nvme_ctrl *ctrl, + unsigned int sensor, int temp) +{ + unsigned int threshold = sensor << NVME_TEMP_THRESH_SELECT_SHIFT; + int status; + int ret; + + if (WARN_ON_ONCE(sensor >= ARRAY_SIZE(ctrl->tzdev))) + return -EINVAL; + + if (temp > NVME_TEMP_THRESH_MASK) + return -EINVAL; + + threshold |= temp & NVME_TEMP_THRESH_MASK; + + ret = nvme_set_features(ctrl, NVME_FEAT_TEMP_THRESH, threshold, NULL, 0, + &status); + + return ret > 0 ? -EINVAL : ret; +} + +static int nvme_tz_get_trip_temp(struct thermal_zone_device *tzdev, + int trip, int *temp) +{ + unsigned int sensor = nvme_tz_type_to_sensor(tzdev->type); + struct nvme_ctrl *ctrl = tzdev->devdata; + int ret; + + ret = nvme_get_over_temp_thresh(ctrl, sensor, temp); + if (!ret) + *temp = KELVIN_TO_MILLICELSIUS(*temp); + + return ret; +} + +static int nvme_tz_set_trip_temp(struct thermal_zone_device *tzdev, + int trip, int temp) +{ + unsigned int sensor = nvme_tz_type_to_sensor(tzdev->type); + struct nvme_ctrl *ctrl = tzdev->devdata; + + temp = MILLICELSIUS_TO_KELVIN(temp); + + return nvme_set_over_temp_thresh(ctrl, sensor, temp); +} + +static struct thermal_zone_device_ops nvme_tz_ops = { + .get_temp = nvme_tz_get_temp, + .get_trip_type = nvme_tz_get_trip_type, + .get_trip_temp = nvme_tz_get_trip_temp, + .set_trip_temp = nvme_tz_set_trip_temp, +}; + +static struct thermal_zone_params nvme_tz_params = { + .governor_name = "user_space", + .no_hwmon = true, +}; + +static struct thermal_zone_device * +nvme_thermal_zone_register(struct nvme_ctrl *ctrl, unsigned int sensor) +{ + struct thermal_zone_device *tzdev; + char type[THERMAL_NAME_LENGTH]; + int ret; + + snprintf(type, sizeof(type), "nvme_temp%d", sensor); + + tzdev = thermal_zone_device_register(type, 1, 1, ctrl, &nvme_tz_ops, + &nvme_tz_params, 0, 0); + if (IS_ERR(tzdev)) { + dev_err(ctrl->device, + "Failed to register thermal zone device: %ld\n", + PTR_ERR(tzdev)); + return tzdev; + } + + ret = sysfs_create_link(&ctrl->ctrl_device.kobj, + &tzdev->device.kobj, type); + if (ret) + goto device_unregister; + + ret = sysfs_create_link(&tzdev->device.kobj, + &ctrl->ctrl_device.kobj, "device"); + if (ret) + goto remove_link; + + return tzdev; + +remove_link: + sysfs_remove_link(&ctrl->ctrl_device.kobj, type); +device_unregister: + thermal_zone_device_unregister(tzdev); + + return ERR_PTR(ret); +} + +/** + * nvme_thermal_zones_register() - register nvme thermal zone devices + * @ctrl: controller instance + * + * This function creates up to nine thermal zone devices for all implemented + * temperature sensors including the composite temperature. + * Each thermal zone device provides a single trip point temperature that is + * associated with an over temperature threshold. + */ +int nvme_thermal_zones_register(struct nvme_ctrl *ctrl) +{ + struct nvme_smart_log *log; + int ret; + int i; + + log = kzalloc(sizeof(*log), GFP_KERNEL); + if (!log) + return 0; /* non-fatal error */ + + ret = nvme_get_log(ctrl, NVME_NSID_ALL, NVME_LOG_SMART, 0, + log, sizeof(*log), 0); + if (ret) { + dev_err(ctrl->device, "Failed to get SMART log: %d\n", ret); + ret = ret > 0 ? -EINVAL : ret; + goto free_log; + } + + for (i = 0; i < ARRAY_SIZE(ctrl->tzdev); i++) { + struct thermal_zone_device *tzdev; + + /* + * All implemented temperature sensors report a non-zero value + * in temperature sensor fields in the smart log page. + */ + if (i && !le16_to_cpu(log->temp_sensor[i - 1])) + continue; + if (ctrl->tzdev[i]) + continue; + + tzdev = nvme_thermal_zone_register(ctrl, i); + if (!IS_ERR(tzdev)) + ctrl->tzdev[i] = tzdev; + } + +free_log: + kfree(log); + + return ret; +} +EXPORT_SYMBOL_GPL(nvme_thermal_zones_register); + +/** + * nvme_thermal_zones_unregister() - unregister nvme thermal zone devices + * @ctrl: controller instance + * + * This function removes the registered thermal zone devices and symlinks. + */ +void nvme_thermal_zones_unregister(struct nvme_ctrl *ctrl) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ctrl->tzdev); i++) { + struct thermal_zone_device *tzdev = ctrl->tzdev[i]; + + if (!tzdev) + continue; + + sysfs_remove_link(&tzdev->device.kobj, "device"); + sysfs_remove_link(&ctrl->ctrl_device.kobj, tzdev->type); + thermal_zone_device_unregister(tzdev); + + ctrl->tzdev[i] = NULL; + } +} +EXPORT_SYMBOL_GPL(nvme_thermal_zones_unregister); + +#endif /* CONFIG_THERMAL */ + struct nvme_core_quirk_entry { /* * NVMe model and firmware strings are padded with spaces. For diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index bb673b8..0bc4e85 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -15,6 +15,7 @@ #include #include #include +#include extern unsigned int nvme_io_timeout; #define NVME_IO_TIMEOUT (nvme_io_timeout * HZ) @@ -248,6 +249,14 @@ struct nvme_ctrl { struct page *discard_page; unsigned long discard_page_busy; + +#ifdef CONFIG_THERMAL + /* + * tzdev[0]: composite temperature + * tzdev[1-8]: temperature sensor 1 through 8 + */ + struct thermal_zone_device *tzdev[9]; +#endif }; enum nvme_iopolicy { @@ -559,6 +568,24 @@ static inline void nvme_mpath_stop(struct nvme_ctrl *ctrl) } #endif /* CONFIG_NVME_MULTIPATH */ +#ifdef CONFIG_THERMAL + +int nvme_thermal_zones_register(struct nvme_ctrl *ctrl); +void nvme_thermal_zones_unregister(struct nvme_ctrl *ctrl); + +#else + +static inline int nvme_thermal_zones_register(struct nvme_ctrl *ctrl) +{ + return 0; +} + +static inline void nvme_thermal_zones_unregister(struct nvme_ctrl *ctrl) +{ +} + +#endif /* CONFIG_THERMAL */ + #ifdef CONFIG_NVM int nvme_nvm_register(struct nvme_ns *ns, char *disk_name, int node); void nvme_nvm_unregister(struct nvme_ns *ns); diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 658ac75..54f0a13 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -780,6 +780,11 @@ struct nvme_write_zeroes_cmd { /* Features */ +enum { + NVME_TEMP_THRESH_MASK = 0xffff, + NVME_TEMP_THRESH_SELECT_SHIFT = 16, +}; + struct nvme_feat_auto_pst { __le64 entries[32]; }; From patchwork Tue May 21 16:04:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akinobu Mita X-Patchwork-Id: 10954231 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4DBA913AD for ; Tue, 21 May 2019 16:04:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3E46128877 for ; Tue, 21 May 2019 16:04:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3224928A3C; Tue, 21 May 2019 16:04:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B3ACD2889B for ; Tue, 21 May 2019 16:04:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728597AbfEUQEk (ORCPT ); Tue, 21 May 2019 12:04:40 -0400 Received: from mail-pl1-f196.google.com ([209.85.214.196]:38796 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726900AbfEUQEj (ORCPT ); Tue, 21 May 2019 12:04:39 -0400 Received: by mail-pl1-f196.google.com with SMTP id f97so8642516plb.5 for ; Tue, 21 May 2019 09:04:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=wQFG8hw3y3EIs2QpnKA67CdoA7uCJM+M7ssUQOFNLw8=; b=i0+RdiALkQzzsbo6liTzoG7avWVdVxZzLhgx3Zh6KUZDrdLDq8+3A21zLJcalT5tAe RtBw9250vMHrbAsxL68KHF4YobIsqlUsph8BK82pfPYM165MrcgfAhmNo1ThTVQgPSnZ sEDY8iTGzThjHdCBvxYM5iAhHTHPNr1NsqoluLGdZuzo5K1TPcVgPqOCSy+kkJY3AOxn x07aziY7s8sFxXmf6AnCCk377ssvAfySPCBegJhBZKHSjYRkoCTIM54J6jJM4xsD6KqU khQ3UvV/a3ZEKAU/m15hT6Eogk8OI9A23eQjHh3zXALyCME1neq8WZi8bDRT1EivmfVA UNPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=wQFG8hw3y3EIs2QpnKA67CdoA7uCJM+M7ssUQOFNLw8=; b=pCGd7sVvppxrfud4nFjWPZAzZYKQ8x1rhL4z2JDaQZXclG2EvNByAworwQaIDRSEvF 0srRsabxDjVZy0T0jRvyz2NbyGn+RZBaqrUn5UKnaodylk5onVBMBTEXvBce33/54TKE 59U3fXsKc1tvW+FxMGxkK/dbNk/0wMBqlAGVFvyvUvRGcj9n383Zv50OausYLEFeGsQD zyGXR5HpMkuNM3I78arEnmXanSyhgt6ZX/wte9hyCWocXtUb0+ibD9iL82YXgvwAu9lw D3BCGM+/7yobtb88uZDXYdpqrGggLCfW2JAQHGk+Kzli9xP2F4OzbYWirL+wLM8j/689 5bng== X-Gm-Message-State: APjAAAUT0dYPS0J2pybIKEQw9zlYwtfy6QJbin4Cx72IlmJJaxq9QHTR GpgNzuKCjAjyJ3W+ACCRE4o= X-Google-Smtp-Source: APXvYqwvWcDIl+aU/XA5TANKkfW/YI2ev5NCjho/Az9gHQL6o/RAfqGH1SFq1Bdb3sFt20t5XqDvIA== X-Received: by 2002:a17:902:e9:: with SMTP id a96mr57111148pla.37.1558454679338; Tue, 21 May 2019 09:04:39 -0700 (PDT) Received: from mita-MS-7A45.lan ([240f:34:212d:1:9cd0:73e8:b74a:624e]) by smtp.gmail.com with ESMTPSA id j5sm28954786pfa.15.2019.05.21.09.04.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 21 May 2019 09:04:38 -0700 (PDT) From: Akinobu Mita To: linux-nvme@lists.infradead.org, linux-pm@vger.kernel.org Cc: Akinobu Mita , Zhang Rui , Eduardo Valentin , Daniel Lezcano , Keith Busch , Jens Axboe , Christoph Hellwig , Sagi Grimberg , Minwoo Im , Kenneth Heitke , Chaitanya Kulkarni Subject: [PATCH v2 3/4] nvme: notify thermal framework when temperature threshold events occur Date: Wed, 22 May 2019 01:04:08 +0900 Message-Id: <1558454649-28783-4-git-send-email-akinobu.mita@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1558454649-28783-1-git-send-email-akinobu.mita@gmail.com> References: <1558454649-28783-1-git-send-email-akinobu.mita@gmail.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 Cc: Eduardo Valentin Cc: Daniel Lezcano Cc: Keith Busch Cc: Jens Axboe Cc: Christoph Hellwig Cc: Sagi Grimberg Cc: Minwoo Im Cc: Kenneth Heitke Cc: Chaitanya Kulkarni Signed-off-by: Akinobu Mita --- * 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(+) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 0ec303c..a86f9f4 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -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); } diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 54f0a13..8e7d599 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -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, From patchwork Tue May 21 16:04:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akinobu Mita X-Patchwork-Id: 10954233 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CCAB1912 for ; Tue, 21 May 2019 16:04:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BCBAC28AB2 for ; Tue, 21 May 2019 16:04:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B10FA28A7E; Tue, 21 May 2019 16:04:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4B91528A7E for ; Tue, 21 May 2019 16:04:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728608AbfEUQEp (ORCPT ); Tue, 21 May 2019 12:04:45 -0400 Received: from mail-pg1-f195.google.com ([209.85.215.195]:41715 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726900AbfEUQEp (ORCPT ); Tue, 21 May 2019 12:04:45 -0400 Received: by mail-pg1-f195.google.com with SMTP id z3so8807063pgp.8 for ; Tue, 21 May 2019 09:04:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=il/JXoP4aW4WFFHOxr0Tpp4Ev1osrOA1IE5f6L08DkI=; b=vcQdl09QHQy5NCYrsBFsiiAUnQpK6sJjCqv3YPoyJcfJnHY6edGZLWqmsdMWoE5qpC FUtKaDv9Qm3MYF+cwwS2rQUr3eEzqSZCSalIBV/qrebvVtSiwpRL5G+WrxJ9SyGMGeT2 LEXiDMuzONxJ1irNpO+YU/6RsdTtjrFTwvD4p0gUKWZXIB3+C2UzPELQNvmguuxVIhKS PEEq1+gxJP/kAPD8sOPPT2FptzjD8+vR9pwo7x2HU0nnVui6gedrIZR3FiekjYJ6XFUR zYGHyGFS1Y7JAdD8BcuyU0Vj8RKoaP9iWAk6vCX6Hn9/54J6VY7mUZ5rYKFjzHIyKkWr D7LA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=il/JXoP4aW4WFFHOxr0Tpp4Ev1osrOA1IE5f6L08DkI=; b=XiCkg65EKmvYy34iPCV7PjnubASzzomhApXWSpt1kSQjzfzzO2HlRydzo60l1O/va3 z16AZrCxO1KFUxbbEvvWXgKrGxCf+TVSTtN3bkAPQ8WGmV8nDhV7AHtp4YJIN4iTL+SA 9/0HAimrMbvuLcsA86YZhE9O7Z6K0rOtmlt1oRgPNF6sQ88xKt7J7VsS3/iwK2GFQkY5 eRV7dWnDLlw3yvZXyUjkKfVNC60HfTsMuMu/bHq+88ww3Y3CU7PWxwBVOUTGRJ3PITHW xGD77KhJzLRb3OrBu8+lkAP0Q+lvBuk/HFgyPfTwTdM7Uj7p4oywi+HlILAZnbXf63As 3C1Q== X-Gm-Message-State: APjAAAWZPhr6dCuLfQiXIBNIQe1UVDb08tOK8Xa43KCdAAc673zbT1Mt kcoqmapignZhDbn7hwHXeq8= X-Google-Smtp-Source: APXvYqwX1tzSTRG+WCXtNpV2F+N566SicxZ0ovg2pY8O3qxjQzcztQeDDyBKAexFfbKzwzd7zWXzlA== X-Received: by 2002:a63:ee0a:: with SMTP id e10mr69278554pgi.28.1558454684956; Tue, 21 May 2019 09:04:44 -0700 (PDT) Received: from mita-MS-7A45.lan ([240f:34:212d:1:9cd0:73e8:b74a:624e]) by smtp.gmail.com with ESMTPSA id j5sm28954786pfa.15.2019.05.21.09.04.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 21 May 2019 09:04:44 -0700 (PDT) From: Akinobu Mita To: linux-nvme@lists.infradead.org, linux-pm@vger.kernel.org Cc: Akinobu Mita , Zhang Rui , Eduardo Valentin , Daniel Lezcano , Keith Busch , Jens Axboe , Christoph Hellwig , Sagi Grimberg , Minwoo Im , Kenneth Heitke , Chaitanya Kulkarni Subject: [PATCH v2 4/4] nvme-pci: support thermal zone Date: Wed, 22 May 2019 01:04:09 +0900 Message-Id: <1558454649-28783-5-git-send-email-akinobu.mita@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1558454649-28783-1-git-send-email-akinobu.mita@gmail.com> References: <1558454649-28783-1-git-send-email-akinobu.mita@gmail.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This enables to use thermal zone interfaces for NVMe temperature sensors. Cc: Zhang Rui Cc: Eduardo Valentin Cc: Daniel Lezcano Cc: Keith Busch Cc: Jens Axboe Cc: Christoph Hellwig Cc: Sagi Grimberg Cc: Minwoo Im Cc: Kenneth Heitke Cc: Chaitanya Kulkarni Signed-off-by: Akinobu Mita --- * v2 - Call nvme_thermal_zones_unregister() earlier than the last reference release drivers/nvme/host/pci.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 04084b9..108b022 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -2555,6 +2555,10 @@ static void nvme_reset_work(struct work_struct *work) dev->ctrl.opal_dev = NULL; } + result = nvme_thermal_zones_register(&dev->ctrl); + if (result < 0) + goto out; + if (dev->ctrl.oacs & NVME_CTRL_OACS_DBBUF_SUPP) { result = nvme_dbbuf_dma_alloc(dev); if (result) @@ -2833,6 +2837,7 @@ static void nvme_remove(struct pci_dev *pdev) flush_work(&dev->ctrl.reset_work); nvme_stop_ctrl(&dev->ctrl); nvme_remove_namespaces(&dev->ctrl); + nvme_thermal_zones_unregister(&dev->ctrl); nvme_dev_disable(dev, true, false); nvme_release_cmb(dev); nvme_free_host_mem(dev);