[<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