lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220224090654.54671-10-jianchao.wan9@gmail.com>
Date:   Thu, 24 Feb 2022 17:06:47 +0800
From:   "Wang Jianchao (Kuaishou)" <jianchao.wan9@...il.com>
To:     Jens Axboe <axboe@...nel.dk>
Cc:     Josef Bacik <jbacik@...com>, Tejun Heo <tj@...nel.org>,
        Bart Van Assche <bvanassche@....org>,
        linux-block@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [RFC V5 09/16] blk-wbt: show wbt_lat_us sysfs interface only when wbt is opened

Add 'wbt_lat_us' to block device' queue sysfs only when we open
'wbt' blk-rq-qos policy. And do some code cleanup as we needn't
to export those wbt interfaces.

Signed-off-by: Wang Jianchao (Kuaishou) <jianchao.wan9@...il.com>
---
 block/blk-sysfs.c |  71 ----------------
 block/blk-wbt.c   | 201 +++++++++++++++++++++++++++-------------------
 block/blk-wbt.h   |  28 -------
 block/blk.h       |   6 ++
 4 files changed, 125 insertions(+), 181 deletions(-)

diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 052b5f03fc73..1b321edd7ba7 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -20,12 +20,6 @@
 #include "blk-wbt.h"
 #include "blk-throttle.h"
 
-struct queue_sysfs_entry {
-	struct attribute attr;
-	ssize_t (*show)(struct request_queue *, char *);
-	ssize_t (*store)(struct request_queue *, const char *, size_t);
-};
-
 static ssize_t
 queue_var_show(unsigned long var, char *page)
 {
@@ -47,19 +41,6 @@ queue_var_store(unsigned long *var, const char *page, size_t count)
 	return count;
 }
 
-static ssize_t queue_var_store64(s64 *var, const char *page)
-{
-	int err;
-	s64 v;
-
-	err = kstrtos64(page, 10, &v);
-	if (err < 0)
-		return err;
-
-	*var = v;
-	return 0;
-}
-
 static ssize_t queue_requests_show(struct request_queue *q, char *page)
 {
 	return queue_var_show(q->nr_requests, page);
@@ -461,56 +442,6 @@ static ssize_t queue_io_timeout_store(struct request_queue *q, const char *page,
 	return count;
 }
 
-static ssize_t queue_wb_lat_show(struct request_queue *q, char *page)
-{
-	if (!wbt_opened(q))
-		return -EINVAL;
-
-	return sprintf(page, "%llu\n", div_u64(wbt_get_min_lat(q), 1000));
-}
-
-static ssize_t queue_wb_lat_store(struct request_queue *q, const char *page,
-				  size_t count)
-{
-	ssize_t ret;
-	s64 val;
-
-	ret = queue_var_store64(&val, page);
-	if (ret < 0)
-		return ret;
-	if (val < -1)
-		return -EINVAL;
-
-	if (!wbt_opened(q)) {
-		ret = wbt_init(q);
-		if (ret)
-			return ret;
-	}
-
-	if (val == -1)
-		val = wbt_default_latency_nsec(q);
-	else if (val >= 0)
-		val *= 1000ULL;
-
-	if (wbt_get_min_lat(q) == val)
-		return count;
-
-	/*
-	 * Ensure that the queue is idled, in case the latency update
-	 * ends up either enabling or disabling wbt completely. We can't
-	 * have IO inflight if that happens.
-	 */
-	blk_mq_freeze_queue(q);
-	blk_mq_quiesce_queue(q);
-
-	wbt_set_min_lat(q, val);
-
-	blk_mq_unquiesce_queue(q);
-	blk_mq_unfreeze_queue(q);
-
-	return count;
-}
-
 static ssize_t queue_wc_show(struct request_queue *q, char *page)
 {
 	if (test_bit(QUEUE_FLAG_WC, &q->queue_flags))
@@ -604,7 +535,6 @@ QUEUE_RW_ENTRY(queue_wc, "write_cache");
 QUEUE_RO_ENTRY(queue_fua, "fua");
 QUEUE_RO_ENTRY(queue_dax, "dax");
 QUEUE_RW_ENTRY(queue_io_timeout, "io_timeout");
-QUEUE_RW_ENTRY(queue_wb_lat, "wbt_lat_usec");
 QUEUE_RO_ENTRY(queue_virt_boundary_mask, "virt_boundary_mask");
 
 #ifdef CONFIG_BLK_DEV_THROTTLING_LOW
@@ -661,7 +591,6 @@ static struct attribute *queue_attrs[] = {
 	&queue_wc_entry.attr,
 	&queue_fua_entry.attr,
 	&queue_dax_entry.attr,
-	&queue_wb_lat_entry.attr,
 	&queue_poll_delay_entry.attr,
 	&queue_io_timeout_entry.attr,
 #ifdef CONFIG_BLK_DEV_THROTTLING_LOW
diff --git a/block/blk-wbt.c b/block/blk-wbt.c
index 44a920d83475..bbec3b394273 100644
--- a/block/blk-wbt.c
+++ b/block/blk-wbt.c
@@ -24,7 +24,9 @@
 #include <linux/slab.h>
 #include <linux/backing-dev.h>
 #include <linux/swap.h>
+#include <linux/sysfs.h>
 
+#include "blk.h"
 #include "blk-wbt.h"
 #include "blk-rq-qos.h"
 
@@ -38,15 +40,6 @@ static inline struct rq_qos *wbt_rq_qos(struct request_queue *q)
 	return rq_qos_get(q, wbt_rqos_ops.id);
 }
 
-bool wbt_opened(struct request_queue *q)
-{
-	struct rq_qos *rqos = wbt_rq_qos(q);
-
-	rq_qos_put(rqos);
-
-	return !!rqos;
-}
-
 static inline void wbt_clear_state(struct request *rq)
 {
 	rq->wbt_flags = 0;
@@ -438,33 +431,6 @@ static void wbt_update_limits(struct rq_wb *rwb)
 	rwb_wake_all(rwb);
 }
 
-u64 wbt_get_min_lat(struct request_queue *q)
-{
-	struct rq_qos *rqos = wbt_rq_qos(q);
-	u64 nsec;
-
-	if (!rqos)
-		return 0;
-
-	nsec = RQWB(rqos)->min_lat_nsec;
-	rq_qos_put(rqos);
-
-	return  nsec;
-}
-
-void wbt_set_min_lat(struct request_queue *q, u64 val)
-{
-	struct rq_qos *rqos = wbt_rq_qos(q);
-
-	if (!rqos)
-		return;
-	RQWB(rqos)->min_lat_nsec = val;
-	RQWB(rqos)->enable_state = WBT_STATE_ON_MANUAL;
-	wbt_update_limits(RQWB(rqos));
-	rq_qos_put(rqos);
-}
-
-
 static bool close_io(struct rq_wb *rwb)
 {
 	const unsigned long now = jiffies;
@@ -660,32 +626,7 @@ void wbt_set_write_cache(struct request_queue *q, bool write_cache_on)
 	}
 }
 
-/*
- * Enable wbt if defaults are configured that way
- */
-void wbt_enable_default(struct request_queue *q)
-{
-	struct rq_qos *rqos = wbt_rq_qos(q);
-
-	/* Throttling already enabled? */
-	if (rqos) {
-		if (RQWB(rqos)->enable_state == WBT_STATE_OFF_DEFAULT)
-			RQWB(rqos)->enable_state = WBT_STATE_ON_DEFAULT;
-
-		rq_qos_put(rqos);
-		return;
-	}
-
-	/* Queue not registered? Maybe shutting down... */
-	if (!blk_queue_registered(q))
-		return;
-
-	if (queue_is_mq(q) && IS_ENABLED(CONFIG_BLK_WBT_MQ))
-		wbt_init(q);
-}
-EXPORT_SYMBOL_GPL(wbt_enable_default);
-
-u64 wbt_default_latency_nsec(struct request_queue *q)
+static u64 wbt_default_latency_nsec(struct request_queue *q)
 {
 	/*
 	 * We default to 2msec for non-rotational storage, and 75msec
@@ -716,7 +657,67 @@ static void wbt_queue_depth_changed(struct rq_qos *rqos)
 	wbt_update_limits(RQWB(rqos));
 }
 
-static void wbt_exit(struct rq_qos *rqos)
+static ssize_t wbt_lat_show(struct request_queue *q, char *page)
+{
+	struct rq_qos *rqos = wbt_rq_qos(q);
+	ssize_t ret;
+
+	ret = sprintf(page, "%llu\n", div_u64(RQWB(rqos)->min_lat_nsec, 1000));
+
+	rq_qos_put(rqos);
+
+	return ret;
+}
+
+static ssize_t wbt_lat_store(struct request_queue *q, const char *page,
+				  size_t count)
+{
+	struct rq_qos *rqos;
+	struct rq_wb *rwb;
+	ssize_t ret;
+	s64 val;
+
+	ret = kstrtos64(page, 10, &val);
+	if (ret < 0)
+		return ret;
+
+	if (val < -1)
+		return -EINVAL;
+
+	if (val == -1)
+		val = wbt_default_latency_nsec(q);
+	else if (val >= 0)
+		val *= 1000ULL;
+
+	rqos = wbt_rq_qos(q);
+	rwb = RQWB(rqos);
+
+	if (rwb->min_lat_nsec == val)
+		goto out;
+	/*
+	 * Ensure that the queue is idled, in case the latency update
+	 * ends up either enabling or disabling wbt completely. We can't
+	 * have IO inflight if that happens.
+	 */
+	blk_mq_freeze_queue(q);
+	blk_mq_quiesce_queue(q);
+
+	rwb->min_lat_nsec = val;
+	rwb->enable_state = WBT_STATE_ON_MANUAL;
+	wbt_update_limits(rwb);
+
+	blk_mq_unquiesce_queue(q);
+	blk_mq_unfreeze_queue(q);
+
+out:
+	rq_qos_put(rqos);
+	return count;
+}
+
+static struct queue_sysfs_entry wbt_attr =
+	__ATTR(wbt_lat_usec, 0644, wbt_lat_show, wbt_lat_store);
+
+static void __wbt_exit(struct rq_qos *rqos)
 {
 	struct rq_wb *rwb = RQWB(rqos);
 	struct request_queue *q = rqos->q;
@@ -727,6 +728,12 @@ static void wbt_exit(struct rq_qos *rqos)
 	kfree(rwb);
 }
 
+static void wbt_exit(struct rq_qos *rqos)
+{
+	sysfs_remove_file(&rqos->q->kobj, &wbt_attr.attr);
+	__wbt_exit(rqos);
+}
+
 /*
  * Disable wbt, if enabled by default.
  */
@@ -835,26 +842,10 @@ static const struct blk_mq_debugfs_attr wbt_debugfs_attrs[] = {
 };
 #endif
 
-static struct rq_qos_ops wbt_rqos_ops = {
-	.name = "wbt",
-	.throttle = wbt_wait,
-	.issue = wbt_issue,
-	.track = wbt_track,
-	.requeue = wbt_requeue,
-	.done = wbt_done,
-	.cleanup = wbt_cleanup,
-	.queue_depth_changed = wbt_queue_depth_changed,
-	.exit = wbt_exit,
-	.init = wbt_init,
-#ifdef CONFIG_BLK_DEBUG_FS
-	.debugfs_attrs = wbt_debugfs_attrs,
-#endif
-};
-
-int wbt_init(struct request_queue *q)
+static int wbt_init(struct request_queue *q)
 {
 	struct rq_wb *rwb;
-	int i;
+	int i, ret;
 
 	rwb = kzalloc(sizeof(*rwb), GFP_KERNEL);
 	if (!rwb)
@@ -886,9 +877,54 @@ int wbt_init(struct request_queue *q)
 	wbt_queue_depth_changed(&rwb->rqos);
 	wbt_set_write_cache(q, test_bit(QUEUE_FLAG_WC, &q->queue_flags));
 
-	return 0;
+	ret = sysfs_create_file(&q->kobj, &wbt_attr.attr);
+	if (ret < 0)
+		__wbt_exit(&rwb->rqos);
+
+	return ret;
 }
 
+static struct rq_qos_ops wbt_rqos_ops = {
+	.name = "wbt",
+	.throttle = wbt_wait,
+	.issue = wbt_issue,
+	.track = wbt_track,
+	.requeue = wbt_requeue,
+	.done = wbt_done,
+	.cleanup = wbt_cleanup,
+	.queue_depth_changed = wbt_queue_depth_changed,
+	.exit = wbt_exit,
+	.init = wbt_init,
+#ifdef CONFIG_BLK_DEBUG_FS
+	.debugfs_attrs = wbt_debugfs_attrs,
+#endif
+};
+
+/*
+ * Enable wbt if defaults are configured that way
+ */
+void wbt_enable_default(struct request_queue *q)
+{
+	struct rq_qos *rqos = wbt_rq_qos(q);
+
+	/* Throttling already enabled? */
+	if (rqos) {
+		if (RQWB(rqos)->enable_state == WBT_STATE_OFF_DEFAULT)
+			RQWB(rqos)->enable_state = WBT_STATE_ON_DEFAULT;
+
+		rq_qos_put(rqos);
+		return;
+	}
+
+	/* Queue not registered? Maybe shutting down... */
+	if (!blk_queue_registered(q))
+		return;
+
+	if (queue_is_mq(q) && IS_ENABLED(CONFIG_BLK_WBT_MQ))
+		wbt_init(q);
+}
+EXPORT_SYMBOL_GPL(wbt_enable_default);
+
 static __init int wbt_mod_init(void)
 {
 	return rq_qos_register(&wbt_rqos_ops);
@@ -898,5 +934,6 @@ static __exit void wbt_mod_exit(void)
 {
 	return rq_qos_unregister(&wbt_rqos_ops);
 }
+
 module_init(wbt_mod_init);
 module_exit(wbt_mod_exit);
diff --git a/block/blk-wbt.h b/block/blk-wbt.h
index f128dcf662db..b9ed3f373b5a 100644
--- a/block/blk-wbt.h
+++ b/block/blk-wbt.h
@@ -88,32 +88,16 @@ static inline unsigned int wbt_inflight(struct rq_wb *rwb)
 
 #ifdef CONFIG_BLK_WBT
 
-bool wbt_opened(struct request_queue *q);
-int wbt_init(struct request_queue *);
 void wbt_disable_default(struct request_queue *);
 void wbt_enable_default(struct request_queue *);
 
-u64 wbt_get_min_lat(struct request_queue *q);
-void wbt_set_min_lat(struct request_queue *q, u64 val);
-
 void wbt_set_write_cache(struct request_queue *, bool);
 
-u64 wbt_default_latency_nsec(struct request_queue *);
-
 #else
 
-bool wbt_opened(struct request_queue *q)
-{
-	return false;
-}
-
 static inline void wbt_track(struct request *rq, enum wbt_flags flags)
 {
 }
-static inline int wbt_init(struct request_queue *q)
-{
-	return -EINVAL;
-}
 static inline void wbt_disable_default(struct request_queue *q)
 {
 }
@@ -123,18 +107,6 @@ static inline void wbt_enable_default(struct request_queue *q)
 static inline void wbt_set_write_cache(struct request_queue *q, bool wc)
 {
 }
-static inline u64 wbt_get_min_lat(struct request_queue *q)
-{
-	return 0;
-}
-static inline void wbt_set_min_lat(struct request_queue *q, u64 val)
-{
-}
-static inline u64 wbt_default_latency_nsec(struct request_queue *q)
-{
-	return 0;
-}
-
 #endif /* CONFIG_BLK_WBT */
 
 #endif
diff --git a/block/blk.h b/block/blk.h
index 1a314257b6a3..2ec7510c080c 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -14,6 +14,12 @@ struct elevator_type;
 
 extern struct dentry *blk_debugfs_root;
 
+struct queue_sysfs_entry {
+	struct attribute attr;
+	ssize_t (*show)(struct request_queue *, char *);
+	ssize_t (*store)(struct request_queue *, const char *, size_t);
+};
+
 struct blk_flush_queue {
 	unsigned int		flush_pending_idx:1;
 	unsigned int		flush_running_idx:1;
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ