From patchwork Mon Jul 22 14:59:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akinobu Mita X-Patchwork-Id: 11052579 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 6D70E14DB for ; Mon, 22 Jul 2019 14:59:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5C9862856D for ; Mon, 22 Jul 2019 14:59:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4AC9528249; Mon, 22 Jul 2019 14:59:42 +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=unavailable 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 8E2C328249 for ; Mon, 22 Jul 2019 14:59:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726792AbfGVO7l (ORCPT ); Mon, 22 Jul 2019 10:59:41 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:35491 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725899AbfGVO7k (ORCPT ); Mon, 22 Jul 2019 10:59:40 -0400 Received: by mail-pg1-f194.google.com with SMTP id s1so11477335pgr.2; Mon, 22 Jul 2019 07:59:40 -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=Z9Utqtp4JPU+YCjrm338t9IQ0s/s9njFI2YRpyIL7NA=; b=g8N6b6t0MXUx7JSWktwWKLdQ67m1RMhzNT5ZumjxxxG2DihO7jo+VFN8fIJOy9yRSI n9f6oWix1A/wD3gClWLh3RFmchipbAFOH/RvyI/iZ4r1GmZnRgGgdCGRKr8tqwzyJ39o Bw82iqu64mGvNN1HTSpaxqISR1R8jkXzr2VA+PiZp/Kf6F84OxqywRabt13RJy6os7I8 vMSV6CKt1JZL+4A8T9TWgfoSsa+mAJIGCi53We0K3nTkQT5E95WZI9s+gh2/axBS9aql Ck2z/CVFqYSRHiNFsLzDqXaW9zH+n25a7HTYLlGxzsWt3zqKUaG0Gcoxd+V05kvq2Pyy IVfA== 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=Z9Utqtp4JPU+YCjrm338t9IQ0s/s9njFI2YRpyIL7NA=; b=mlkvNgxkVTQVcRRIQu6TgMu2Q/aU2JX6gIKBy/kMf9kydvOlpOyh1OQWNsD+KS6p8+ n2IgzKingORc8Hb8Jm44wdiWSbz8YnIQLBeiua1ddnFGR7GTG83KOdI81MN4V+cE+auB XhRopZ4TgMsjW4C0MC8kj5HiLfIQwhj5T0/pjKxx0FIS035tZVMX6M5zqYzQTDo/M5Yt zSTG8iRjFTagOTk2MrWnH7dazcY5y8BHl9aS7zg6TDMVF8tUu8EcoQeXoJUhX8T9oyM+ RXSdECa6GYpxd/k/kC23SjaYvsSzMYgPWuUJWnE0GKGhxCw8ukZ+RZ/9MB4ArPm4Px3b ipww== X-Gm-Message-State: APjAAAW2S6UB6yXI+wpdWpLNkToGy4wjw72AU7F1EqxMZ8/1SIYe9JD0 QANJocMjE9xQ1grBotJsH7YwiUym X-Google-Smtp-Source: APXvYqy1jFjcAuIfmmZjMUqvRWBsHQguTrL7DHQyMC6hO7Fr4Ti0C3MT42kyabFOBsox5hPv0TCCmQ== X-Received: by 2002:a63:24c1:: with SMTP id k184mr73567214pgk.120.1563807579526; Mon, 22 Jul 2019 07:59:39 -0700 (PDT) Received: from mita-MS-7A45.lan (KD027092233113.ppp-bb.dion.ne.jp. [27.92.233.113]) by smtp.gmail.com with ESMTPSA id a16sm42533174pfd.68.2019.07.22.07.59.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 22 Jul 2019 07:59:39 -0700 (PDT) From: Akinobu Mita To: linux-block@vger.kernel.org, linux-leds@vger.kernel.org, linux-nvme@lists.infradead.org, linux-scsi@vger.kernel.org Cc: Akinobu Mita , Frank Steiner , Jacek Anaszewski , Pavel Machek , Dan Murphy , Jens Axboe , "James E.J. Bottomley" , "Martin K. Petersen" Subject: [PATCH v2 1/3] block: introduce LED block device activity trigger Date: Mon, 22 Jul 2019 23:59:10 +0900 Message-Id: <1563807552-23498-2-git-send-email-akinobu.mita@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1563807552-23498-1-git-send-email-akinobu.mita@gmail.com> References: <1563807552-23498-1-git-send-email-akinobu.mita@gmail.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This allows LEDs to be controlled by block device activity. We already have ledtrig-disk (LED disk activity trigger), but the lower level disk drivers need to utilize ledtrig_disk_activity() to make the LED blink. The LED block device trigger doesn't require the lower level drivers to have any instrumentation. The activity is collected by polling the disk stats. Example: echo block-nvme0n1 > /sys/class/leds/diy/trigger Cc: Frank Steiner Cc: Jacek Anaszewski Cc: Pavel Machek Cc: Dan Murphy Cc: Jens Axboe Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Signed-off-by: Akinobu Mita --- block/genhd.c | 2 + drivers/leds/trigger/Kconfig | 7 ++ drivers/leds/trigger/Makefile | 1 + drivers/leds/trigger/ledtrig-blk.c | 225 +++++++++++++++++++++++++++++++++++++ include/linux/genhd.h | 3 + include/linux/leds.h | 27 +++++ 6 files changed, 265 insertions(+) create mode 100644 drivers/leds/trigger/ledtrig-blk.c diff --git a/block/genhd.c b/block/genhd.c index 54f1f0d3..1c68861 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -745,6 +745,7 @@ static void __device_add_disk(struct device *parent, struct gendisk *disk, disk_add_events(disk); blk_integrity_add(disk); + ledtrig_blk_register(disk); } void device_add_disk(struct device *parent, struct gendisk *disk, @@ -766,6 +767,7 @@ void del_gendisk(struct gendisk *disk) struct disk_part_iter piter; struct hd_struct *part; + ledtrig_blk_unregister(disk); blk_integrity_del(disk); disk_del_events(disk); diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig index ce9429c..74ce25d 100644 --- a/drivers/leds/trigger/Kconfig +++ b/drivers/leds/trigger/Kconfig @@ -144,4 +144,11 @@ config LEDS_TRIGGER_AUDIO the audio mute and mic-mute changes. If unsure, say N +config LEDS_TRIGGER_BLOCK + bool "LED Block device Trigger" + depends on BLOCK + help + This allows LEDs to be controlled by block device activity. + If unsure, say Y. + endif # LEDS_TRIGGERS diff --git a/drivers/leds/trigger/Makefile b/drivers/leds/trigger/Makefile index 733a83e..60200eb 100644 --- a/drivers/leds/trigger/Makefile +++ b/drivers/leds/trigger/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_LEDS_TRIGGER_PANIC) += ledtrig-panic.o obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o obj-$(CONFIG_LEDS_TRIGGER_PATTERN) += ledtrig-pattern.o obj-$(CONFIG_LEDS_TRIGGER_AUDIO) += ledtrig-audio.o +obj-$(CONFIG_LEDS_TRIGGER_BLOCK) += ledtrig-blk.o diff --git a/drivers/leds/trigger/ledtrig-blk.c b/drivers/leds/trigger/ledtrig-blk.c new file mode 100644 index 0000000..d5808c9 --- /dev/null +++ b/drivers/leds/trigger/ledtrig-blk.c @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: GPL-2.0 +// LED Kernel Blockdev Trigger +// Derived from ledtrig-netdev.c + +#include +#include +#include +#include +#include "../leds.h" + +enum ledtrig_blk_attr { + LEDTRIG_BLK_READ, + LEDTRIG_BLK_WRITE, + LEDTRIG_BLK_DISCARD +}; + +struct ledtrig_blk_data { + struct delayed_work work; + struct led_classdev *led_cdev; + + atomic_t interval; + u64 last_activity; + + unsigned long mode; +}; + +static ssize_t ledtrig_blk_attr_show(struct device *dev, char *buf, + enum ledtrig_blk_attr attr) +{ + struct ledtrig_blk_data *trig_data = led_trigger_get_drvdata(dev); + + return sprintf(buf, "%u\n", test_bit(attr, &trig_data->mode)); +} + +static ssize_t ledtrig_blk_attr_store(struct device *dev, const char *buf, + size_t size, enum ledtrig_blk_attr attr) +{ + struct ledtrig_blk_data *trig_data = led_trigger_get_drvdata(dev); + unsigned long state; + int ret; + + ret = kstrtoul(buf, 0, &state); + if (ret) + return ret; + + if (state) + set_bit(attr, &trig_data->mode); + else + clear_bit(attr, &trig_data->mode); + + return size; +} + +static ssize_t read_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return ledtrig_blk_attr_show(dev, buf, LEDTRIG_BLK_READ); +} +static ssize_t read_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + return ledtrig_blk_attr_store(dev, buf, size, LEDTRIG_BLK_READ); +} +static DEVICE_ATTR_RW(read); + +static ssize_t write_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return ledtrig_blk_attr_show(dev, buf, LEDTRIG_BLK_WRITE); +} +static ssize_t write_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + return ledtrig_blk_attr_store(dev, buf, size, LEDTRIG_BLK_WRITE); +} +static DEVICE_ATTR_RW(write); + +static ssize_t discard_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return ledtrig_blk_attr_show(dev, buf, LEDTRIG_BLK_DISCARD); +} +static ssize_t discard_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + return ledtrig_blk_attr_store(dev, buf, size, LEDTRIG_BLK_DISCARD); +} +static DEVICE_ATTR_RW(discard); + +static ssize_t interval_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ledtrig_blk_data *trig_data = led_trigger_get_drvdata(dev); + + return sprintf(buf, "%u\n", + jiffies_to_msecs(atomic_read(&trig_data->interval))); +} +static ssize_t interval_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct ledtrig_blk_data *trig_data = led_trigger_get_drvdata(dev); + unsigned long value; + int ret; + + ret = kstrtoul(buf, 0, &value); + if (ret) + return ret; + + /* impose some basic bounds on the timer interval */ + if (value >= 5 && value <= 10000) { + cancel_delayed_work_sync(&trig_data->work); + atomic_set(&trig_data->interval, msecs_to_jiffies(value)); + schedule_delayed_work(&trig_data->work, + atomic_read(&trig_data->interval) * 2); + } + + return size; +} +static DEVICE_ATTR_RW(interval); + +static struct attribute *ledtrig_blk_attrs[] = { + &dev_attr_read.attr, + &dev_attr_write.attr, + &dev_attr_discard.attr, + &dev_attr_interval.attr, + NULL +}; +ATTRIBUTE_GROUPS(ledtrig_blk); + +static void ledtrig_blk_work(struct work_struct *work) +{ + struct ledtrig_blk_data *trig_data = + container_of(work, struct ledtrig_blk_data, work.work); + struct gendisk *disk = container_of(trig_data->led_cdev->trigger, + struct gendisk, led.trig); + u64 activity = 0; + + if (test_bit(LEDTRIG_BLK_READ, &trig_data->mode)) + activity += part_stat_read(&disk->part0, ios[STAT_READ]); + if (test_bit(LEDTRIG_BLK_WRITE, &trig_data->mode)) + activity += part_stat_read(&disk->part0, ios[STAT_WRITE]); + if (test_bit(LEDTRIG_BLK_DISCARD, &trig_data->mode)) + activity += part_stat_read(&disk->part0, ios[STAT_DISCARD]); + + if (trig_data->last_activity != activity) { + unsigned long interval; + + led_stop_software_blink(trig_data->led_cdev); + interval = jiffies_to_msecs(atomic_read(&trig_data->interval)); + led_blink_set_oneshot(trig_data->led_cdev, &interval, &interval, + 0); + + trig_data->last_activity = activity; + } + + schedule_delayed_work(&trig_data->work, + atomic_read(&trig_data->interval) * 2); +} + +static int ledtrig_blk_activate(struct led_classdev *led_cdev) +{ + struct ledtrig_blk_data *trig_data; + + trig_data = kzalloc(sizeof(*trig_data), GFP_KERNEL); + if (!trig_data) + return -ENOMEM; + + trig_data->mode = BIT(LEDTRIG_BLK_READ) | BIT(LEDTRIG_BLK_WRITE) | + BIT(LEDTRIG_BLK_DISCARD); + + atomic_set(&trig_data->interval, msecs_to_jiffies(50)); + trig_data->last_activity = 0; + trig_data->led_cdev = led_cdev; + + INIT_DELAYED_WORK(&trig_data->work, ledtrig_blk_work); + + led_set_trigger_data(led_cdev, trig_data); + + schedule_delayed_work(&trig_data->work, + atomic_read(&trig_data->interval) * 2); + + return 0; +} + +static void ledtrig_blk_deactivate(struct led_classdev *led_cdev) +{ + struct ledtrig_blk_data *trig_data = led_get_trigger_data(led_cdev); + + cancel_delayed_work_sync(&trig_data->work); + kfree(trig_data); +} + +int ledtrig_blk_register(struct gendisk *disk) +{ + int ret; + + disk->led.trig.name = kasprintf(GFP_KERNEL, "block-%s", + disk->disk_name); + if (!disk->led.trig.name) + return -ENOMEM; + + disk->led.trig.activate = ledtrig_blk_activate; + disk->led.trig.deactivate = ledtrig_blk_deactivate; + disk->led.trig.groups = ledtrig_blk_groups; + + ret = led_trigger_register(&disk->led.trig); + if (ret) { + kfree(disk->led.trig.name); + disk->led.trig.name = NULL; + } + + return ret; +} +EXPORT_SYMBOL_GPL(ledtrig_blk_register); + +void ledtrig_blk_unregister(struct gendisk *disk) +{ + if (!disk->led.trig.name) + return; + + led_trigger_unregister(&disk->led.trig); + kfree(disk->led.trig.name); + disk->led.trig.name = NULL; +} +EXPORT_SYMBOL_GPL(ledtrig_blk_unregister); diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 8b5330d..b2c934e 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #ifdef CONFIG_BLOCK @@ -219,6 +220,8 @@ struct gendisk { int node_id; struct badblocks *bb; struct lockdep_map lockdep_map; + + struct ledtrig_blk led; }; static inline struct gendisk *part_to_disk(struct hd_struct *part) diff --git a/include/linux/leds.h b/include/linux/leds.h index 9b2bf57..395fa61 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -517,4 +517,31 @@ static inline void ledtrig_audio_set(enum led_audio type, } #endif +struct gendisk; + +#ifdef CONFIG_LEDS_TRIGGER_BLOCK + +struct ledtrig_blk { + struct led_trigger trig; +}; + +int ledtrig_blk_register(struct gendisk *disk); +void ledtrig_blk_unregister(struct gendisk *disk); + +#else + +struct ledtrig_blk { +}; + +static inline int ledtrig_blk_register(struct gendisk *disk) +{ + return 0; +} + +static inline void ledtrig_blk_unregister(struct gendisk *disk) +{ +} + +#endif /* CONFIG_LEDS_TRIGGER_BLOCK */ + #endif /* __LINUX_LEDS_H_INCLUDED */ From patchwork Mon Jul 22 14:59:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akinobu Mita X-Patchwork-Id: 11052581 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 C2364746 for ; Mon, 22 Jul 2019 14:59:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B2603212D9 for ; Mon, 22 Jul 2019 14:59:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A69072842E; Mon, 22 Jul 2019 14:59:51 +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 2CA94212D9 for ; Mon, 22 Jul 2019 14:59:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726809AbfGVO7u (ORCPT ); Mon, 22 Jul 2019 10:59:50 -0400 Received: from mail-pl1-f196.google.com ([209.85.214.196]:36839 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725899AbfGVO7u (ORCPT ); Mon, 22 Jul 2019 10:59:50 -0400 Received: by mail-pl1-f196.google.com with SMTP id k8so19336113plt.3; Mon, 22 Jul 2019 07:59:50 -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=KA1oHbf5AMmxiV0udJaNL+9jpzt1sO1/94tgTVwHPuU=; b=HTBPjmcCLPRJk5zA/PwD52IgrOZz5DgvIPTBdD1fyePEgBUWP7doAm8VdR3PGw1fA7 NJile9oMFoHdWtGpD2w68+44WHdla5npQDnFEiFm8hgyyiSOUTXCPazPenVZd+NdEFYw PRbd8B1nFOHd5wMjBzjZk+Ydkou60Z0edwdNm9EoFn3v8J3mmdvdUBb2akL6uhbd4d0c tpYV3QFUWY/Wc665JGiXHMzYB0N2gGY7VpxWDxjyNBgOMRbmDeeifSwpCPCIZOh8jYp/ ZHvTV0DXNZkEcDqE2y6t3LC6IMDaZi3BXIQkjRdm4TFzp/fTP17bRuMk+9DjlsJe5nD+ /5ag== 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=KA1oHbf5AMmxiV0udJaNL+9jpzt1sO1/94tgTVwHPuU=; b=UdSwmP77xel5nMdbySk0D+dH+TACHJBE8yciwYwQpMmEHAKjOfMhyiOMYC9NxRTVKz ZFsr/RUWfZ/urF/Pq17TYC2DGIrXRtmQo/1MdEngDa6by2guOhXEENJvRt6nPCM4rnW6 +qNRDfPMz4+KvXJX7Z91DEkUAd2Ofaar+khtCAea1IhqxyxC3CNoVTjrt8RYZS5ieD2d XkGSLvMo5VYBNtQZqPGNPHTmb/rzFiC4vPgulJLFVeZe48R/cpyaMYFDT/JPoHAk4dLJ xA+F0eNCDg8NxR4+FOkcYWXQgDgzWwKvrQN0ugU3bO11X8tiFDpGTztcfT67H52rtIeY 5XfA== X-Gm-Message-State: APjAAAUoYezG8tBTeZxokyILfdQQ1zJ+2GQzumaeIcZVxvZ5cHBYW0OY UsQ4QbD2muPc9NYi+F7VkDm7Iuhf X-Google-Smtp-Source: APXvYqwhqAhgaFbhJQ1eHJw8AEBtYiAZ8bPwNSOU0oXSkMOCIcnFBI4r/zMG23rwhQXF4p3wLDeQbg== X-Received: by 2002:a17:902:8509:: with SMTP id bj9mr76505337plb.79.1563807589710; Mon, 22 Jul 2019 07:59:49 -0700 (PDT) Received: from mita-MS-7A45.lan (KD027092233113.ppp-bb.dion.ne.jp. [27.92.233.113]) by smtp.gmail.com with ESMTPSA id a16sm42533174pfd.68.2019.07.22.07.59.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 22 Jul 2019 07:59:49 -0700 (PDT) From: Akinobu Mita To: linux-block@vger.kernel.org, linux-leds@vger.kernel.org, linux-nvme@lists.infradead.org, linux-scsi@vger.kernel.org Cc: Akinobu Mita , Frank Steiner , Jacek Anaszewski , Pavel Machek , Dan Murphy , Jens Axboe , "James E.J. Bottomley" , "Martin K. Petersen" Subject: [PATCH v2 2/3] ledtrig-blk: add interface to stop and restart polling disk stats Date: Mon, 22 Jul 2019 23:59:11 +0900 Message-Id: <1563807552-23498-3-git-send-email-akinobu.mita@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1563807552-23498-1-git-send-email-akinobu.mita@gmail.com> References: <1563807552-23498-1-git-send-email-akinobu.mita@gmail.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The LED block device activity trigger periodically polls the disk stats to collect the activity. However, it is pointless to poll while the block device is in quiescent state. This provides an optional interface to stop and restart polling disk stats for the lower-level block drivers. Cc: Frank Steiner Cc: Jacek Anaszewski Cc: Pavel Machek Cc: Dan Murphy Cc: Jens Axboe Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Signed-off-by: Akinobu Mita --- drivers/leds/trigger/ledtrig-blk.c | 37 +++++++++++++++++++++++++++++++++++-- include/linux/leds.h | 11 +++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/drivers/leds/trigger/ledtrig-blk.c b/drivers/leds/trigger/ledtrig-blk.c index d5808c9..6b826ed 100644 --- a/drivers/leds/trigger/ledtrig-blk.c +++ b/drivers/leds/trigger/ledtrig-blk.c @@ -153,8 +153,9 @@ static void ledtrig_blk_work(struct work_struct *work) trig_data->last_activity = activity; } - schedule_delayed_work(&trig_data->work, - atomic_read(&trig_data->interval) * 2); + if (atomic_read(&disk->led.enable_count)) + schedule_delayed_work(&trig_data->work, + atomic_read(&trig_data->interval) * 2); } static int ledtrig_blk_activate(struct led_classdev *led_cdev) @@ -190,6 +191,36 @@ static void ledtrig_blk_deactivate(struct led_classdev *led_cdev) kfree(trig_data); } +void ledtrig_blk_disable(struct gendisk *disk) +{ + if (disk) + atomic_dec(&disk->led.enable_count); +} +EXPORT_SYMBOL_GPL(ledtrig_blk_disable); + +void ledtrig_blk_enable(struct gendisk *disk) +{ + struct led_classdev *led_cdev; + + if (!disk) + return; + + atomic_inc(&disk->led.enable_count); + + read_lock(&disk->led.trig.leddev_list_lock); + + list_for_each_entry(led_cdev, &disk->led.trig.led_cdevs, trig_list) { + struct ledtrig_blk_data *trig_data = + led_get_trigger_data(led_cdev); + + schedule_delayed_work(&trig_data->work, + atomic_read(&trig_data->interval) * 2); + } + + read_unlock(&disk->led.trig.leddev_list_lock); +} +EXPORT_SYMBOL_GPL(ledtrig_blk_enable); + int ledtrig_blk_register(struct gendisk *disk) { int ret; @@ -203,6 +234,8 @@ int ledtrig_blk_register(struct gendisk *disk) disk->led.trig.deactivate = ledtrig_blk_deactivate; disk->led.trig.groups = ledtrig_blk_groups; + atomic_set(&disk->led.enable_count, 1); + ret = led_trigger_register(&disk->led.trig); if (ret) { kfree(disk->led.trig.name); diff --git a/include/linux/leds.h b/include/linux/leds.h index 395fa61..fd2eb7c 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -523,8 +523,11 @@ struct gendisk; struct ledtrig_blk { struct led_trigger trig; + atomic_t enable_count; }; +void ledtrig_blk_enable(struct gendisk *disk); +void ledtrig_blk_disable(struct gendisk *disk); int ledtrig_blk_register(struct gendisk *disk); void ledtrig_blk_unregister(struct gendisk *disk); @@ -533,6 +536,14 @@ void ledtrig_blk_unregister(struct gendisk *disk); struct ledtrig_blk { }; +static inline void ledtrig_blk_enable(struct gendisk *disk) +{ +} + +static inline void ledtrig_blk_disable(struct gendisk *disk) +{ +} + static inline int ledtrig_blk_register(struct gendisk *disk) { return 0; From patchwork Mon Jul 22 14:59:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Akinobu Mita X-Patchwork-Id: 11052585 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 B6805746 for ; Mon, 22 Jul 2019 15:00:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A6DF228451 for ; Mon, 22 Jul 2019 15:00:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A4D972857F; Mon, 22 Jul 2019 15:00:04 +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 299B928451 for ; Mon, 22 Jul 2019 15:00:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726819AbfGVPAD (ORCPT ); Mon, 22 Jul 2019 11:00:03 -0400 Received: from mail-pl1-f193.google.com ([209.85.214.193]:40807 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725899AbfGVPAD (ORCPT ); Mon, 22 Jul 2019 11:00:03 -0400 Received: by mail-pl1-f193.google.com with SMTP id a93so19279671pla.7; Mon, 22 Jul 2019 08:00:03 -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=H/mgA5Q6Tay1+ixdoqgmaZ9E59OoWK8q1G0jb5mfWTU=; b=T/wva0ycJqMHPLQKhAXy5V2lfzKN76yWpvWsrPHtca0NDIyzmovmqZgvwVqF14v2L8 fBrD47foZqJBwmOlF5kvBbL5MtnGVvtp6/bOZvyElrrjnl63poUJtgV/ycVD0VAkKCe0 IJWuezmPWL2Onh1qDU+eD3K5ATWu2YrINCgSIrdoGFLXUa5IyTfvzNGUJAblJbCNi3p5 8fPvWMfBE8yA5Y1Gts097/nIort/T/1wP1L1J4wFIhOKveGGWVIYyN8/YbCTc6HmCYI5 r7xdAi1ReLdIIJwpHR+9VK//9e7Uz4d7vSNv9p/9skFEMIpNHEgnPE1wGq4kbPK2N+3H Pqlw== 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=H/mgA5Q6Tay1+ixdoqgmaZ9E59OoWK8q1G0jb5mfWTU=; b=qk9NDY1hPvmnCl8i9A0F9d2RFvKbdlcFeA4u9M8vuU8PMSwhvQkg25xHCNDWCggQcs Af//vCouwZJaVuAP3WvlLMVVpm/ayRbNU7jOaz+XMEskCKAvNKZxQ9NNXd8Q8HX0n9EN oi2pQZmKYxmvwFbf8SNL9Xh99iXv15f0IfEGvvd1iHeTs1e/lYx0tZHcm+QfEekK5HbN bPyeeY+eT081Y7tjDRW7Qr7U0O5+imXEuZgKRiaUNTAQbsJ5n0ICM3ne6koy340LBEl9 nENBOCwaqCPHB9gSpW/4xLkAIqASyfUIJW7G1q5gtVOBk/lm5ZRT7do56hPbsQm0m9KZ 3Ndw== X-Gm-Message-State: APjAAAV2WpQwxynm//oihyc7koHoml4T3btjtw/ju+CXI6JKqaYhzsN9 08Kc4x45b5JbZMSqC5cYi6Jpi8wV X-Google-Smtp-Source: APXvYqxgJ+C74y1G4cEu9kZN1sEr0LOAv6Ih4XmhsV8n8HLqX2VM3eQps23ZbUAPOuHVbaq3um9WrQ== X-Received: by 2002:a17:902:8ec3:: with SMTP id x3mr74560918plo.313.1563807602716; Mon, 22 Jul 2019 08:00:02 -0700 (PDT) Received: from mita-MS-7A45.lan (KD027092233113.ppp-bb.dion.ne.jp. [27.92.233.113]) by smtp.gmail.com with ESMTPSA id a16sm42533174pfd.68.2019.07.22.07.59.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 22 Jul 2019 08:00:02 -0700 (PDT) From: Akinobu Mita To: linux-block@vger.kernel.org, linux-leds@vger.kernel.org, linux-nvme@lists.infradead.org, linux-scsi@vger.kernel.org Cc: Akinobu Mita , Frank Steiner , Jacek Anaszewski , Pavel Machek , Dan Murphy , Jens Axboe , "James E.J. Bottomley" , "Martin K. Petersen" Subject: [PATCH v2 3/3] scsi: sd: stop polling disk stats by ledtrig-blk during runtime suspend Date: Mon, 22 Jul 2019 23:59:12 +0900 Message-Id: <1563807552-23498-4-git-send-email-akinobu.mita@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1563807552-23498-1-git-send-email-akinobu.mita@gmail.com> References: <1563807552-23498-1-git-send-email-akinobu.mita@gmail.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The LED block device activity trigger periodically polls the disk stats to collect the activity. However, it is pointless to poll while the scsi device is in runtime suspend. This stops polling disk stats when the device is successfully runtime suspended, and restarts polling when the device is successfully runtime resumed. Cc: Frank Steiner Cc: Jacek Anaszewski Cc: Pavel Machek Cc: Dan Murphy Cc: Jens Axboe Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Signed-off-by: Akinobu Mita --- drivers/scsi/sd.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 149d406..5f73142 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3538,7 +3538,7 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) { struct scsi_disk *sdkp = dev_get_drvdata(dev); struct scsi_sense_hdr sshdr; - int ret = 0; + int ret; if (!sdkp) /* E.g.: runtime suspend following sd_remove() */ return 0; @@ -3550,18 +3550,16 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) if (ret) { /* ignore OFFLINE device */ if (ret == -ENODEV) - return 0; - - if (!scsi_sense_valid(&sshdr) || - sshdr.sense_key != ILLEGAL_REQUEST) - return ret; + goto success; /* * sshdr.sense_key == ILLEGAL_REQUEST means this drive * doesn't support sync. There's not much to do and * suspend shouldn't fail. */ - ret = 0; + if (!scsi_sense_valid(&sshdr) || + sshdr.sense_key != ILLEGAL_REQUEST) + return ret; } } @@ -3569,11 +3567,14 @@ static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); /* an error is not worth aborting a system sleep */ ret = sd_start_stop_device(sdkp, 0); - if (ignore_stop_errors) - ret = 0; + if (ret && !ignore_stop_errors) + return ret; } - return ret; +success: + ledtrig_blk_disable(sdkp->disk); + + return 0; } static int sd_suspend_system(struct device *dev) @@ -3589,19 +3590,24 @@ static int sd_suspend_runtime(struct device *dev) static int sd_resume(struct device *dev) { struct scsi_disk *sdkp = dev_get_drvdata(dev); - int ret; if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */ return 0; - if (!sdkp->device->manage_start_stop) - return 0; + if (sdkp->device->manage_start_stop) { + int ret; + + sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); + ret = sd_start_stop_device(sdkp, 1); + if (ret) + return ret; - sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); - ret = sd_start_stop_device(sdkp, 1); - if (!ret) opal_unlock_from_suspend(sdkp->opal_dev); - return ret; + } + + ledtrig_blk_enable(sdkp->disk); + + return 0; } /**