* [PATCH 0/2] Export more queue state information through debugfs
@ 2017-03-30 18:21 Bart Van Assche
2017-03-30 18:21 ` [PATCH 1/2] blk-mq: Export queue state through /sys/kernel/debug/block/*/state Bart Van Assche
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Bart Van Assche @ 2017-03-30 18:21 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-block, Bart Van Assche
Hello Jens,
This is a short patch series with one patch that exports the queue state
and another patch that shows symbolic names for hctx state and flags
instead of a numerical bitmask.
Please consider these patches for kernel v4.12.
Thanks,
Bart.
Changes compared to v2:
- Introduced function blk_flags_show() in patch 1.
- Modified error message in patch 1 such that it shows the names of the
valid commands.
- Added patch "blk-mq: Show symbolic names for hctx state and flags"
Changes compared to v1:
- Constified blk_queue_flag_name.
- Left out QUEUE_FLAG_VIRT because it is a synonym of QUEUE_FLAG_NONROT.
- Check array size before reading from blk_queue_flag_name[].
- Add functionality to restart a block layer queue.
Bart Van Assche (2):
blk-mq: Export queue state through /sys/kernel/debug/block/*/state
blk-mq: Show symbolic names for hctx state and flags
block/blk-mq-debugfs.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 140 insertions(+), 3 deletions(-)
--
2.12.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/2] blk-mq: Export queue state through /sys/kernel/debug/block/*/state
2017-03-30 18:21 [PATCH 0/2] Export more queue state information through debugfs Bart Van Assche
@ 2017-03-30 18:21 ` Bart Van Assche
2017-03-31 23:23 ` [PATCH v4 " Bart Van Assche
2017-03-30 18:21 ` [PATCH 2/2] blk-mq: Show symbolic names for hctx state and flags Bart Van Assche
2017-04-10 18:28 ` [PATCH 0/2] Export more queue state information through debugfs Jens Axboe
2 siblings, 1 reply; 10+ messages in thread
From: Bart Van Assche @ 2017-03-30 18:21 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-block, Bart Van Assche, Omar Sandoval, Hannes Reinecke
Make it possible to check whether or not a block layer queue has
been stopped. Make it possible to start and to run a blk-mq queue
from user space.
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Hannes Reinecke <hare@suse.com>
---
block/blk-mq-debugfs.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 107 insertions(+)
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
index 4b3f962a9c7a..9e86056d47cd 100644
--- a/block/blk-mq-debugfs.c
+++ b/block/blk-mq-debugfs.c
@@ -43,6 +43,110 @@ static int blk_mq_debugfs_seq_open(struct inode *inode, struct file *file,
return ret;
}
+static int blk_flags_show(struct seq_file *m, const unsigned long flags,
+ const char *const *flag_name, int flag_name_count)
+{
+ bool sep = false;
+ int i;
+
+ for (i = 0; i < sizeof(flags) * BITS_PER_BYTE; i++) {
+ if (!(flags & BIT(i)))
+ continue;
+ if (sep)
+ seq_puts(m, " ");
+ sep = true;
+ if (i < flag_name_count && flag_name[i])
+ seq_puts(m, flag_name[i]);
+ else
+ seq_printf(m, "%d", i);
+ }
+ seq_puts(m, "\n");
+ return 0;
+}
+
+static const char *const blk_queue_flag_name[] = {
+ [QUEUE_FLAG_QUEUED] = "QUEUED",
+ [QUEUE_FLAG_STOPPED] = "STOPPED",
+ [QUEUE_FLAG_SYNCFULL] = "SYNCFULL",
+ [QUEUE_FLAG_ASYNCFULL] = "ASYNCFULL",
+ [QUEUE_FLAG_DYING] = "DYING",
+ [QUEUE_FLAG_BYPASS] = "BYPASS",
+ [QUEUE_FLAG_BIDI] = "BIDI",
+ [QUEUE_FLAG_NOMERGES] = "NOMERGES",
+ [QUEUE_FLAG_SAME_COMP] = "SAME_COMP",
+ [QUEUE_FLAG_FAIL_IO] = "FAIL_IO",
+ [QUEUE_FLAG_STACKABLE] = "STACKABLE",
+ [QUEUE_FLAG_NONROT] = "NONROT",
+ [QUEUE_FLAG_IO_STAT] = "IO_STAT",
+ [QUEUE_FLAG_DISCARD] = "DISCARD",
+ [QUEUE_FLAG_NOXMERGES] = "NOXMERGES",
+ [QUEUE_FLAG_ADD_RANDOM] = "ADD_RANDOM",
+ [QUEUE_FLAG_SECERASE] = "SECERASE",
+ [QUEUE_FLAG_SAME_FORCE] = "SAME_FORCE",
+ [QUEUE_FLAG_DEAD] = "DEAD",
+ [QUEUE_FLAG_INIT_DONE] = "INIT_DONE",
+ [QUEUE_FLAG_NO_SG_MERGE] = "NO_SG_MERGE",
+ [QUEUE_FLAG_POLL] = "POLL",
+ [QUEUE_FLAG_WC] = "WC",
+ [QUEUE_FLAG_FUA] = "FUA",
+ [QUEUE_FLAG_FLUSH_NQ] = "FLUSH_NQ",
+ [QUEUE_FLAG_DAX] = "DAX",
+ [QUEUE_FLAG_STATS] = "STATS",
+ [QUEUE_FLAG_RESTART] = "RESTART",
+ [QUEUE_FLAG_POLL_STATS] = "POLL_STATS",
+ [QUEUE_FLAG_REGISTERED] = "REGISTERED",
+};
+
+static int blk_queue_flags_show(struct seq_file *m, void *v)
+{
+ struct request_queue *q = m->private;
+
+ blk_flags_show(m, q->queue_flags, blk_queue_flag_name,
+ ARRAY_SIZE(blk_queue_flag_name));
+ return 0;
+}
+
+static ssize_t blk_queue_flags_store(struct file *file, const char __user *ubuf,
+ size_t len, loff_t *offp)
+{
+ struct request_queue *q = file_inode(file)->i_private;
+ char op[16] = { }, *s;
+
+ len = min(len, sizeof(op) - 1);
+ if (copy_from_user(op, ubuf, len))
+ return -EFAULT;
+ s = op;
+ strsep(&s, " \t\n"); /* strip trailing whitespace */
+ if (strcmp(op, "run") == 0) {
+ blk_mq_run_hw_queues(q, true);
+ } else if (strcmp(op, "start") == 0) {
+ blk_mq_start_stopped_hw_queues(q, true);
+ } else {
+ pr_err("%s: unsupported operation %s. Use either 'run' or 'start'\n",
+ __func__, op);
+ return -EINVAL;
+ }
+ return len;
+}
+
+static int blk_queue_flags_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, blk_queue_flags_show, inode->i_private);
+}
+
+static const struct file_operations blk_queue_flags_fops = {
+ .open = blk_queue_flags_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = blk_queue_flags_store,
+};
+
+static const struct blk_mq_debugfs_attr blk_queue_attrs[] = {
+ {"state", 0600, &blk_queue_flags_fops},
+ {},
+};
+
static void print_stat(struct seq_file *m, struct blk_rq_stat *stat)
{
if (stat->nr_samples) {
@@ -735,6 +839,9 @@ int blk_mq_debugfs_register_hctxs(struct request_queue *q)
if (!q->debugfs_dir)
return -ENOENT;
+ if (!debugfs_create_files(q->debugfs_dir, q, blk_queue_attrs))
+ goto err;
+
q->mq_debugfs_dir = debugfs_create_dir("mq", q->debugfs_dir);
if (!q->mq_debugfs_dir)
goto err;
--
2.12.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/2] blk-mq: Show symbolic names for hctx state and flags
2017-03-30 18:21 [PATCH 0/2] Export more queue state information through debugfs Bart Van Assche
2017-03-30 18:21 ` [PATCH 1/2] blk-mq: Export queue state through /sys/kernel/debug/block/*/state Bart Van Assche
@ 2017-03-30 18:21 ` Bart Van Assche
2017-04-10 18:28 ` [PATCH 0/2] Export more queue state information through debugfs Jens Axboe
2 siblings, 0 replies; 10+ messages in thread
From: Bart Van Assche @ 2017-03-30 18:21 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-block, Bart Van Assche, Omar Sandoval, Hannes Reinecke
Instead of showing the hctx state and flags as numbers, show the
names of the flags.
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Hannes Reinecke <hare@suse.com>
---
block/blk-mq-debugfs.c | 37 ++++++++++++++++++++++++++++++++++---
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
index 9e86056d47cd..91d09f58a596 100644
--- a/block/blk-mq-debugfs.c
+++ b/block/blk-mq-debugfs.c
@@ -183,11 +183,19 @@ static const struct file_operations queue_poll_stat_fops = {
.release = single_release,
};
+static const char *const hctx_state_name[] = {
+ [BLK_MQ_S_STOPPED] = "STOPPED",
+ [BLK_MQ_S_TAG_ACTIVE] = "TAG_ACTIVE",
+ [BLK_MQ_S_SCHED_RESTART] = "SCHED_RESTART",
+ [BLK_MQ_S_TAG_WAITING] = "TAG_WAITING",
+
+};
static int hctx_state_show(struct seq_file *m, void *v)
{
struct blk_mq_hw_ctx *hctx = m->private;
- seq_printf(m, "0x%lx\n", hctx->state);
+ blk_flags_show(m, hctx->state, hctx_state_name,
+ ARRAY_SIZE(hctx_state_name));
return 0;
}
@@ -203,11 +211,34 @@ static const struct file_operations hctx_state_fops = {
.release = single_release,
};
+static const char *const alloc_policy_name[] = {
+ [BLK_TAG_ALLOC_FIFO] = "fifo",
+ [BLK_TAG_ALLOC_RR] = "rr",
+};
+
+static const char *const hctx_flag_name[] = {
+ [ilog2(BLK_MQ_F_SHOULD_MERGE)] = "SHOULD_MERGE",
+ [ilog2(BLK_MQ_F_TAG_SHARED)] = "TAG_SHARED",
+ [ilog2(BLK_MQ_F_SG_MERGE)] = "SG_MERGE",
+ [ilog2(BLK_MQ_F_BLOCKING)] = "BLOCKING",
+ [ilog2(BLK_MQ_F_NO_SCHED)] = "NO_SCHED",
+};
+
static int hctx_flags_show(struct seq_file *m, void *v)
{
struct blk_mq_hw_ctx *hctx = m->private;
-
- seq_printf(m, "0x%lx\n", hctx->flags);
+ const int alloc_policy = BLK_MQ_FLAG_TO_ALLOC_POLICY(hctx->flags);
+
+ seq_puts(m, "alloc_policy=");
+ if (alloc_policy < ARRAY_SIZE(alloc_policy_name) &&
+ alloc_policy_name[alloc_policy])
+ seq_puts(m, alloc_policy_name[alloc_policy]);
+ else
+ seq_printf(m, "%d", alloc_policy);
+ seq_puts(m, " ");
+ blk_flags_show(m,
+ hctx->flags ^ BLK_ALLOC_POLICY_TO_MQ_FLAG(alloc_policy),
+ hctx_flag_name, ARRAY_SIZE(hctx_flag_name));
return 0;
}
--
2.12.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 1/2] blk-mq: Export queue state through /sys/kernel/debug/block/*/state
2017-03-30 18:21 ` [PATCH 1/2] blk-mq: Export queue state through /sys/kernel/debug/block/*/state Bart Van Assche
@ 2017-03-31 23:23 ` Bart Van Assche
2017-04-01 8:05 ` Hannes Reinecke
0 siblings, 1 reply; 10+ messages in thread
From: Bart Van Assche @ 2017-03-31 23:23 UTC (permalink / raw)
To: Bart Van Assche, Jens Axboe; +Cc: linux-block, Omar Sandoval, Hannes Reinecke
Make it possible to check whether or not a block layer queue has=0A=
been stopped. Make it possible to start and to run a blk-mq queue=0A=
from user space.=0A=
=0A=
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>=0A=
Cc: Omar Sandoval <osandov@fb.com>=0A=
Cc: Hannes Reinecke <hare@suse.com>=0A=
=0A=
---=0A=
=0A=
Changes compared to v3:=0A=
- Return -ENOENT for attempts to run or start a queue after it has reached =
the=0A=
state "dead". This is needed to avoid a use-after-free and potentially a =
kernel=0A=
crash.=0A=
=0A=
---=0A=
=0A=
block/blk-mq-debugfs.c | 114 +++++++++++++++++++++++++++++++++++++++++++++=
++++=0A=
1 file changed, 114 insertions(+)=0A=
=0A=
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c=0A=
index 4b3f962a9c7a..bd3afa4e1602 100644=0A=
--- a/block/blk-mq-debugfs.c=0A=
+++ b/block/blk-mq-debugfs.c=0A=
@@ -43,6 +43,117 @@ static int blk_mq_debugfs_seq_open(struct inode *inode,=
struct file *file,=0A=
return ret;=0A=
}=0A=
=0A=
+static int blk_flags_show(struct seq_file *m, const unsigned long flags,=
=0A=
+ const char *const *flag_name, int flag_name_count)=0A=
+{=0A=
+ bool sep =3D false;=0A=
+ int i;=0A=
+=0A=
+ for (i =3D 0; i < sizeof(flags) * BITS_PER_BYTE; i++) {=0A=
+ if (!(flags & BIT(i)))=0A=
+ continue;=0A=
+ if (sep)=0A=
+ seq_puts(m, " ");=0A=
+ sep =3D true;=0A=
+ if (i < flag_name_count && flag_name[i])=0A=
+ seq_puts(m, flag_name[i]);=0A=
+ else=0A=
+ seq_printf(m, "%d", i);=0A=
+ }=0A=
+ seq_puts(m, "\n");=0A=
+ return 0;=0A=
+}=0A=
+=0A=
+static const char *const blk_queue_flag_name[] =3D {=0A=
+ [QUEUE_FLAG_QUEUED] =3D "QUEUED",=0A=
+ [QUEUE_FLAG_STOPPED] =3D "STOPPED",=0A=
+ [QUEUE_FLAG_SYNCFULL] =3D "SYNCFULL",=0A=
+ [QUEUE_FLAG_ASYNCFULL] =3D "ASYNCFULL",=0A=
+ [QUEUE_FLAG_DYING] =3D "DYING",=0A=
+ [QUEUE_FLAG_BYPASS] =3D "BYPASS",=0A=
+ [QUEUE_FLAG_BIDI] =3D "BIDI",=0A=
+ [QUEUE_FLAG_NOMERGES] =3D "NOMERGES",=0A=
+ [QUEUE_FLAG_SAME_COMP] =3D "SAME_COMP",=0A=
+ [QUEUE_FLAG_FAIL_IO] =3D "FAIL_IO",=0A=
+ [QUEUE_FLAG_STACKABLE] =3D "STACKABLE",=0A=
+ [QUEUE_FLAG_NONROT] =3D "NONROT",=0A=
+ [QUEUE_FLAG_IO_STAT] =3D "IO_STAT",=0A=
+ [QUEUE_FLAG_DISCARD] =3D "DISCARD",=0A=
+ [QUEUE_FLAG_NOXMERGES] =3D "NOXMERGES",=0A=
+ [QUEUE_FLAG_ADD_RANDOM] =3D "ADD_RANDOM",=0A=
+ [QUEUE_FLAG_SECERASE] =3D "SECERASE",=0A=
+ [QUEUE_FLAG_SAME_FORCE] =3D "SAME_FORCE",=0A=
+ [QUEUE_FLAG_DEAD] =3D "DEAD",=0A=
+ [QUEUE_FLAG_INIT_DONE] =3D "INIT_DONE",=0A=
+ [QUEUE_FLAG_NO_SG_MERGE] =3D "NO_SG_MERGE",=0A=
+ [QUEUE_FLAG_POLL] =3D "POLL",=0A=
+ [QUEUE_FLAG_WC] =3D "WC",=0A=
+ [QUEUE_FLAG_FUA] =3D "FUA",=0A=
+ [QUEUE_FLAG_FLUSH_NQ] =3D "FLUSH_NQ",=0A=
+ [QUEUE_FLAG_DAX] =3D "DAX",=0A=
+ [QUEUE_FLAG_STATS] =3D "STATS",=0A=
+ [QUEUE_FLAG_POLL_STATS] =3D "POLL_STATS",=0A=
+ [QUEUE_FLAG_REGISTERED] =3D "REGISTERED",=0A=
+};=0A=
+=0A=
+static int blk_queue_flags_show(struct seq_file *m, void *v)=0A=
+{=0A=
+ struct request_queue *q =3D m->private;=0A=
+=0A=
+ blk_flags_show(m, q->queue_flags, blk_queue_flag_name,=0A=
+ ARRAY_SIZE(blk_queue_flag_name));=0A=
+ return 0;=0A=
+}=0A=
+=0A=
+static ssize_t blk_queue_flags_store(struct file *file, const char __user =
*ubuf,=0A=
+ size_t len, loff_t *offp)=0A=
+{=0A=
+ struct request_queue *q =3D file_inode(file)->i_private;=0A=
+ char op[16] =3D { }, *s;=0A=
+=0A=
+ /*=0A=
+ * The debugfs attributes are removed after blk_cleanup_queue() has=0A=
+ * called blk_mq_free_queue(). Return if QUEUE_FLAG_DEAD has been set=0A=
+ * to avoid triggering a use-after-free.=0A=
+ */=0A=
+ if (blk_queue_dead(q))=0A=
+ return -ENOENT;=0A=
+=0A=
+ len =3D min(len, sizeof(op) - 1);=0A=
+ if (copy_from_user(op, ubuf, len))=0A=
+ return -EFAULT;=0A=
+ s =3D op;=0A=
+ strsep(&s, " \t\n"); /* strip trailing whitespace */=0A=
+ if (strcmp(op, "run") =3D=3D 0) {=0A=
+ blk_mq_run_hw_queues(q, true);=0A=
+ } else if (strcmp(op, "start") =3D=3D 0) {=0A=
+ blk_mq_start_stopped_hw_queues(q, true);=0A=
+ } else {=0A=
+ pr_err("%s: unsupported operation %s. Use either 'run' or 'start'\n",=0A=
+ __func__, op);=0A=
+ return -EINVAL;=0A=
+ }=0A=
+ return len;=0A=
+}=0A=
+=0A=
+static int blk_queue_flags_open(struct inode *inode, struct file *file)=0A=
+{=0A=
+ return single_open(file, blk_queue_flags_show, inode->i_private);=0A=
+}=0A=
+=0A=
+static const struct file_operations blk_queue_flags_fops =3D {=0A=
+ .open =3D blk_queue_flags_open,=0A=
+ .read =3D seq_read,=0A=
+ .llseek =3D seq_lseek,=0A=
+ .release =3D single_release,=0A=
+ .write =3D blk_queue_flags_store,=0A=
+};=0A=
+=0A=
+static const struct blk_mq_debugfs_attr blk_queue_attrs[] =3D {=0A=
+ {"state", 0600, &blk_queue_flags_fops},=0A=
+ {},=0A=
+};=0A=
+=0A=
static void print_stat(struct seq_file *m, struct blk_rq_stat *stat)=0A=
{=0A=
if (stat->nr_samples) {=0A=
@@ -735,6 +846,9 @@ int blk_mq_debugfs_register_hctxs(struct request_queue =
*q)=0A=
if (!q->debugfs_dir)=0A=
return -ENOENT;=0A=
=0A=
+ if (!debugfs_create_files(q->debugfs_dir, q, blk_queue_attrs))=0A=
+ goto err;=0A=
+=0A=
q->mq_debugfs_dir =3D debugfs_create_dir("mq", q->debugfs_dir);=0A=
if (!q->mq_debugfs_dir)=0A=
goto err;=0A=
-- =0A=
2.12.0=0A=
=0A=
=0A=
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/2] blk-mq: Export queue state through /sys/kernel/debug/block/*/state
2017-03-31 23:23 ` [PATCH v4 " Bart Van Assche
@ 2017-04-01 8:05 ` Hannes Reinecke
0 siblings, 0 replies; 10+ messages in thread
From: Hannes Reinecke @ 2017-04-01 8:05 UTC (permalink / raw)
To: Bart Van Assche, Jens Axboe; +Cc: linux-block, Omar Sandoval
On 04/01/2017 01:23 AM, Bart Van Assche wrote:
> Make it possible to check whether or not a block layer queue has
> been stopped. Make it possible to start and to run a blk-mq queue
> from user space.
>
> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
> Cc: Omar Sandoval <osandov@fb.com>
> Cc: Hannes Reinecke <hare@suse.com>
>
> ---
>
> Changes compared to v3:
> - Return -ENOENT for attempts to run or start a queue after it has reached the
> state "dead". This is needed to avoid a use-after-free and potentially a kernel
> crash.
>
> ---
>
> block/blk-mq-debugfs.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 114 insertions(+)
>
> diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
> index 4b3f962a9c7a..bd3afa4e1602 100644
> --- a/block/blk-mq-debugfs.c
> +++ b/block/blk-mq-debugfs.c
> @@ -43,6 +43,117 @@ static int blk_mq_debugfs_seq_open(struct inode *inode, struct file *file,
> return ret;
> }
>
> +static int blk_flags_show(struct seq_file *m, const unsigned long flags,
> + const char *const *flag_name, int flag_name_count)
> +{
> + bool sep = false;
> + int i;
> +
> + for (i = 0; i < sizeof(flags) * BITS_PER_BYTE; i++) {
> + if (!(flags & BIT(i)))
> + continue;
> + if (sep)
> + seq_puts(m, " ");
> + sep = true;
> + if (i < flag_name_count && flag_name[i])
> + seq_puts(m, flag_name[i]);
> + else
> + seq_printf(m, "%d", i);
> + }
> + seq_puts(m, "\n");
> + return 0;
> +}
> +
> +static const char *const blk_queue_flag_name[] = {
> + [QUEUE_FLAG_QUEUED] = "QUEUED",
> + [QUEUE_FLAG_STOPPED] = "STOPPED",
> + [QUEUE_FLAG_SYNCFULL] = "SYNCFULL",
> + [QUEUE_FLAG_ASYNCFULL] = "ASYNCFULL",
> + [QUEUE_FLAG_DYING] = "DYING",
> + [QUEUE_FLAG_BYPASS] = "BYPASS",
> + [QUEUE_FLAG_BIDI] = "BIDI",
> + [QUEUE_FLAG_NOMERGES] = "NOMERGES",
> + [QUEUE_FLAG_SAME_COMP] = "SAME_COMP",
> + [QUEUE_FLAG_FAIL_IO] = "FAIL_IO",
> + [QUEUE_FLAG_STACKABLE] = "STACKABLE",
> + [QUEUE_FLAG_NONROT] = "NONROT",
> + [QUEUE_FLAG_IO_STAT] = "IO_STAT",
> + [QUEUE_FLAG_DISCARD] = "DISCARD",
> + [QUEUE_FLAG_NOXMERGES] = "NOXMERGES",
> + [QUEUE_FLAG_ADD_RANDOM] = "ADD_RANDOM",
> + [QUEUE_FLAG_SECERASE] = "SECERASE",
> + [QUEUE_FLAG_SAME_FORCE] = "SAME_FORCE",
> + [QUEUE_FLAG_DEAD] = "DEAD",
> + [QUEUE_FLAG_INIT_DONE] = "INIT_DONE",
> + [QUEUE_FLAG_NO_SG_MERGE] = "NO_SG_MERGE",
> + [QUEUE_FLAG_POLL] = "POLL",
> + [QUEUE_FLAG_WC] = "WC",
> + [QUEUE_FLAG_FUA] = "FUA",
> + [QUEUE_FLAG_FLUSH_NQ] = "FLUSH_NQ",
> + [QUEUE_FLAG_DAX] = "DAX",
> + [QUEUE_FLAG_STATS] = "STATS",
> + [QUEUE_FLAG_POLL_STATS] = "POLL_STATS",
> + [QUEUE_FLAG_REGISTERED] = "REGISTERED",
> +};
> +
> +static int blk_queue_flags_show(struct seq_file *m, void *v)
> +{
> + struct request_queue *q = m->private;
> +
> + blk_flags_show(m, q->queue_flags, blk_queue_flag_name,
> + ARRAY_SIZE(blk_queue_flag_name));
> + return 0;
> +}
> +
> +static ssize_t blk_queue_flags_store(struct file *file, const char __user *ubuf,
> + size_t len, loff_t *offp)
> +{
> + struct request_queue *q = file_inode(file)->i_private;
> + char op[16] = { }, *s;
> +
> + /*
> + * The debugfs attributes are removed after blk_cleanup_queue() has
> + * called blk_mq_free_queue(). Return if QUEUE_FLAG_DEAD has been set
> + * to avoid triggering a use-after-free.
> + */
> + if (blk_queue_dead(q))
> + return -ENOENT;
> +
> + len = min(len, sizeof(op) - 1);
> + if (copy_from_user(op, ubuf, len))
> + return -EFAULT;
> + s = op;
> + strsep(&s, " \t\n"); /* strip trailing whitespace */
> + if (strcmp(op, "run") == 0) {
> + blk_mq_run_hw_queues(q, true);
> + } else if (strcmp(op, "start") == 0) {
> + blk_mq_start_stopped_hw_queues(q, true);
> + } else {
> + pr_err("%s: unsupported operation %s. Use either 'run' or 'start'\n",
> + __func__, op);
> + return -EINVAL;
> + }
> + return len;
> +}
> +
I would have added 'stop' for completeness, but that's probably for very
specific cases only.
Reviewed-by: Hannes Reinecke <hare@suse.com>
Cheers,
Hannes
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] Export more queue state information through debugfs
2017-03-30 18:21 [PATCH 0/2] Export more queue state information through debugfs Bart Van Assche
2017-03-30 18:21 ` [PATCH 1/2] blk-mq: Export queue state through /sys/kernel/debug/block/*/state Bart Van Assche
2017-03-30 18:21 ` [PATCH 2/2] blk-mq: Show symbolic names for hctx state and flags Bart Van Assche
@ 2017-04-10 18:28 ` Jens Axboe
2017-04-10 18:40 ` Bart Van Assche
2 siblings, 1 reply; 10+ messages in thread
From: Jens Axboe @ 2017-04-10 18:28 UTC (permalink / raw)
To: Bart Van Assche; +Cc: linux-block
On 03/30/2017 12:21 PM, Bart Van Assche wrote:
> Hello Jens,
>
> This is a short patch series with one patch that exports the queue state
> and another patch that shows symbolic names for hctx state and flags
> instead of a numerical bitmask.
>
> Please consider these patches for kernel v4.12.
Thanks, added for 4.12.
--
Jens Axboe
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] Export more queue state information through debugfs
2017-04-10 18:28 ` [PATCH 0/2] Export more queue state information through debugfs Jens Axboe
@ 2017-04-10 18:40 ` Bart Van Assche
2017-04-10 20:00 ` Omar Sandoval
0 siblings, 1 reply; 10+ messages in thread
From: Bart Van Assche @ 2017-04-10 18:40 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-block
On 04/10/2017 11:28 AM, Jens Axboe wrote:
> On 03/30/2017 12:21 PM, Bart Van Assche wrote:
>> This is a short patch series with one patch that exports the queue state
>> and another patch that shows symbolic names for hctx state and flags
>> instead of a numerical bitmask.
>>
>> Please consider these patches for kernel v4.12.
>
> Thanks, added for 4.12.
Hello Jens,
Thanks! This infrastructure was essential while analyzing queue stalls.
After I had posted this series I improved and extended the blk-mq debugfs
functionality further. Please consider including the patch below in v4.12.
Thanks,
Bart.
From: Bart Van Assche <bart.vanassche@sandisk.com>
Subject: [PATCH] blk-mq: Two fixes for the code that exports the queue state
Remove the array entry for QUEUE_FLAG_RESTART since that flag has
been removed after the blk-mq-debugfs patch that introduced this
array entry was posted.
Avoid that querying the queue state of a dead queue triggers a
kernel crash.
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
---
block/blk-mq-debugfs.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
index 91d09f58a596..a1ce823578c7 100644
--- a/block/blk-mq-debugfs.c
+++ b/block/blk-mq-debugfs.c
@@ -92,7 +92,6 @@ static const char *const blk_queue_flag_name[] = {
[QUEUE_FLAG_FLUSH_NQ] = "FLUSH_NQ",
[QUEUE_FLAG_DAX] = "DAX",
[QUEUE_FLAG_STATS] = "STATS",
- [QUEUE_FLAG_RESTART] = "RESTART",
[QUEUE_FLAG_POLL_STATS] = "POLL_STATS",
[QUEUE_FLAG_REGISTERED] = "REGISTERED",
};
@@ -112,6 +111,14 @@ static ssize_t blk_queue_flags_store(struct file *file, const char __user *ubuf,
struct request_queue *q = file_inode(file)->i_private;
char op[16] = { }, *s;
+ /*
+ * The debugfs attributes are removed after blk_cleanup_queue() has
+ * called blk_mq_free_queue(). Return if QUEUE_FLAG_DEAD has been set
+ * to avoid triggering a use-after-free.
+ */
+ if (blk_queue_dead(q))
+ return -ENOENT;
+
len = min(len, sizeof(op) - 1);
if (copy_from_user(op, ubuf, len))
return -EFAULT;
--
2.12.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] Export more queue state information through debugfs
2017-04-10 18:40 ` Bart Van Assche
@ 2017-04-10 20:00 ` Omar Sandoval
2017-04-10 20:12 ` Bart Van Assche
0 siblings, 1 reply; 10+ messages in thread
From: Omar Sandoval @ 2017-04-10 20:00 UTC (permalink / raw)
To: Bart Van Assche; +Cc: Jens Axboe, linux-block
On Mon, Apr 10, 2017 at 11:40:49AM -0700, Bart Van Assche wrote:
> On 04/10/2017 11:28 AM, Jens Axboe wrote:
> > On 03/30/2017 12:21 PM, Bart Van Assche wrote:
> >> This is a short patch series with one patch that exports the queue state
> >> and another patch that shows symbolic names for hctx state and flags
> >> instead of a numerical bitmask.
> >>
> >> Please consider these patches for kernel v4.12.
> >
> > Thanks, added for 4.12.
>
> Hello Jens,
>
> Thanks! This infrastructure was essential while analyzing queue stalls.
>
> After I had posted this series I improved and extended the blk-mq debugfs
> functionality further. Please consider including the patch below in v4.12.
>
> Thanks,
>
> Bart.
>
>
> From: Bart Van Assche <bart.vanassche@sandisk.com>
> Subject: [PATCH] blk-mq: Two fixes for the code that exports the queue state
>
> Remove the array entry for QUEUE_FLAG_RESTART since that flag has
> been removed after the blk-mq-debugfs patch that introduced this
> array entry was posted.
>
> Avoid that querying the queue state of a dead queue triggers a
> kernel crash.
>
> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
> ---
> block/blk-mq-debugfs.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
> index 91d09f58a596..a1ce823578c7 100644
> --- a/block/blk-mq-debugfs.c
> +++ b/block/blk-mq-debugfs.c
> @@ -92,7 +92,6 @@ static const char *const blk_queue_flag_name[] = {
> [QUEUE_FLAG_FLUSH_NQ] = "FLUSH_NQ",
> [QUEUE_FLAG_DAX] = "DAX",
> [QUEUE_FLAG_STATS] = "STATS",
> - [QUEUE_FLAG_RESTART] = "RESTART",
> [QUEUE_FLAG_POLL_STATS] = "POLL_STATS",
> [QUEUE_FLAG_REGISTERED] = "REGISTERED",
> };
> @@ -112,6 +111,14 @@ static ssize_t blk_queue_flags_store(struct file *file, const char __user *ubuf,
> struct request_queue *q = file_inode(file)->i_private;
> char op[16] = { }, *s;
>
> + /*
> + * The debugfs attributes are removed after blk_cleanup_queue() has
> + * called blk_mq_free_queue(). Return if QUEUE_FLAG_DEAD has been set
> + * to avoid triggering a use-after-free.
> + */
> + if (blk_queue_dead(q))
> + return -ENOENT;
> +
Can you just move blk_queue_flags_fops to blk_mq_debugfs_queue_attrs
instead of adding blk_queue_attrs?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] Export more queue state information through debugfs
2017-04-10 20:00 ` Omar Sandoval
@ 2017-04-10 20:12 ` Bart Van Assche
2017-04-10 20:21 ` Omar Sandoval
0 siblings, 1 reply; 10+ messages in thread
From: Bart Van Assche @ 2017-04-10 20:12 UTC (permalink / raw)
To: osandov; +Cc: linux-block, axboe
On Mon, 2017-04-10 at 13:00 -0700, Omar Sandoval wrote:
> Can you just move blk_queue_flags_fops to blk_mq_debugfs_queue_attrs
> instead of adding blk_queue_attrs?
Hello Omar,
Are you aware that that change will move the "state" attribute one level
down in the hierarchy? blk_mq_debugfs_queue_attrs attributes are created
under "mq" while blk_queue_flags_fops attributes are created at the same
level as the "mq" attribute. I had added blk_queue_flags_fops because the
"state" attribute is not related to blk-mq. That attribute is also relevant
for single-queue block layer queues.
Bart.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] Export more queue state information through debugfs
2017-04-10 20:12 ` Bart Van Assche
@ 2017-04-10 20:21 ` Omar Sandoval
0 siblings, 0 replies; 10+ messages in thread
From: Omar Sandoval @ 2017-04-10 20:21 UTC (permalink / raw)
To: Bart Van Assche; +Cc: linux-block, axboe
On Mon, Apr 10, 2017 at 08:12:00PM +0000, Bart Van Assche wrote:
> On Mon, 2017-04-10 at 13:00 -0700, Omar Sandoval wrote:
> > Can you just move blk_queue_flags_fops to blk_mq_debugfs_queue_attrs
> > instead of adding blk_queue_attrs?
>
> Hello Omar,
>
> Are you aware that that change will move the "state" attribute one level
> down in the hierarchy? blk_mq_debugfs_queue_attrs attributes are created
> under "mq" while blk_queue_flags_fops attributes are created at the same
> level as the "mq" attribute. I had added blk_queue_flags_fops because the
> "state" attribute is not related to blk-mq. That attribute is also relevant
> for single-queue block layer queues.
Yes, I am aware of that. We don't set up debugfs for single-queue queues
anyways, so the top-level directory is really just for blktrace. It
simplifies the lifetime and cleanup to have everything under mq, so
please move it there.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2017-04-10 20:21 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-30 18:21 [PATCH 0/2] Export more queue state information through debugfs Bart Van Assche
2017-03-30 18:21 ` [PATCH 1/2] blk-mq: Export queue state through /sys/kernel/debug/block/*/state Bart Van Assche
2017-03-31 23:23 ` [PATCH v4 " Bart Van Assche
2017-04-01 8:05 ` Hannes Reinecke
2017-03-30 18:21 ` [PATCH 2/2] blk-mq: Show symbolic names for hctx state and flags Bart Van Assche
2017-04-10 18:28 ` [PATCH 0/2] Export more queue state information through debugfs Jens Axboe
2017-04-10 18:40 ` Bart Van Assche
2017-04-10 20:00 ` Omar Sandoval
2017-04-10 20:12 ` Bart Van Assche
2017-04-10 20:21 ` Omar Sandoval
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).