]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - block/blk-mq-sysfs.c
nbd: use dev_err_ratelimited in io path
[karo-tx-linux.git] / block / blk-mq-sysfs.c
index 3c385b196bc711ddea86489e50f233a9bbc87356..eacd3af72099018c82e0a41fb9460b670d3e2845 100644 (file)
@@ -259,6 +259,47 @@ static ssize_t blk_mq_hw_sysfs_cpus_show(struct blk_mq_hw_ctx *hctx, char *page)
        return ret;
 }
 
+static void blk_mq_stat_clear(struct blk_mq_hw_ctx *hctx)
+{
+       struct blk_mq_ctx *ctx;
+       unsigned int i;
+
+       hctx_for_each_ctx(hctx, ctx, i) {
+               blk_stat_init(&ctx->stat[BLK_STAT_READ]);
+               blk_stat_init(&ctx->stat[BLK_STAT_WRITE]);
+       }
+}
+
+static ssize_t blk_mq_hw_sysfs_stat_store(struct blk_mq_hw_ctx *hctx,
+                                         const char *page, size_t count)
+{
+       blk_mq_stat_clear(hctx);
+       return count;
+}
+
+static ssize_t print_stat(char *page, struct blk_rq_stat *stat, const char *pre)
+{
+       return sprintf(page, "%s samples=%llu, mean=%lld, min=%lld, max=%lld\n",
+                       pre, (long long) stat->nr_samples,
+                       (long long) stat->mean, (long long) stat->min,
+                       (long long) stat->max);
+}
+
+static ssize_t blk_mq_hw_sysfs_stat_show(struct blk_mq_hw_ctx *hctx, char *page)
+{
+       struct blk_rq_stat stat[2];
+       ssize_t ret;
+
+       blk_stat_init(&stat[BLK_STAT_READ]);
+       blk_stat_init(&stat[BLK_STAT_WRITE]);
+
+       blk_hctx_stat_get(hctx, stat);
+
+       ret = print_stat(page, &stat[BLK_STAT_READ], "read :");
+       ret += print_stat(page + ret, &stat[BLK_STAT_WRITE], "write:");
+       return ret;
+}
+
 static struct blk_mq_ctx_sysfs_entry blk_mq_sysfs_dispatched = {
        .attr = {.name = "dispatched", .mode = S_IRUGO },
        .show = blk_mq_sysfs_dispatched_show,
@@ -317,6 +358,11 @@ static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_poll = {
        .show = blk_mq_hw_sysfs_poll_show,
        .store = blk_mq_hw_sysfs_poll_store,
 };
+static struct blk_mq_hw_ctx_sysfs_entry blk_mq_hw_sysfs_stat = {
+       .attr = {.name = "stats", .mode = S_IRUGO | S_IWUSR },
+       .show = blk_mq_hw_sysfs_stat_show,
+       .store = blk_mq_hw_sysfs_stat_store,
+};
 
 static struct attribute *default_hw_ctx_attrs[] = {
        &blk_mq_hw_sysfs_queued.attr,
@@ -327,6 +373,7 @@ static struct attribute *default_hw_ctx_attrs[] = {
        &blk_mq_hw_sysfs_cpus.attr,
        &blk_mq_hw_sysfs_active.attr,
        &blk_mq_hw_sysfs_poll.attr,
+       &blk_mq_hw_sysfs_stat.attr,
        NULL,
 };
 
@@ -393,9 +440,8 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
        return ret;
 }
 
-static void __blk_mq_unregister_disk(struct gendisk *disk)
+static void __blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
 {
-       struct request_queue *q = disk->queue;
        struct blk_mq_hw_ctx *hctx;
        struct blk_mq_ctx *ctx;
        int i, j;
@@ -413,15 +459,15 @@ static void __blk_mq_unregister_disk(struct gendisk *disk)
        kobject_del(&q->mq_kobj);
        kobject_put(&q->mq_kobj);
 
-       kobject_put(&disk_to_dev(disk)->kobj);
+       kobject_put(&dev->kobj);
 
        q->mq_sysfs_init_done = false;
 }
 
-void blk_mq_unregister_disk(struct gendisk *disk)
+void blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
 {
        blk_mq_disable_hotplug();
-       __blk_mq_unregister_disk(disk);
+       __blk_mq_unregister_dev(dev, q);
        blk_mq_enable_hotplug();
 }
 
@@ -443,10 +489,8 @@ static void blk_mq_sysfs_init(struct request_queue *q)
        }
 }
 
-int blk_mq_register_disk(struct gendisk *disk)
+int blk_mq_register_dev(struct device *dev, struct request_queue *q)
 {
-       struct device *dev = disk_to_dev(disk);
-       struct request_queue *q = disk->queue;
        struct blk_mq_hw_ctx *hctx;
        int ret, i;
 
@@ -467,7 +511,7 @@ int blk_mq_register_disk(struct gendisk *disk)
        }
 
        if (ret)
-               __blk_mq_unregister_disk(disk);
+               __blk_mq_unregister_dev(dev, q);
        else
                q->mq_sysfs_init_done = true;
 out:
@@ -475,7 +519,7 @@ out:
 
        return ret;
 }
-EXPORT_SYMBOL_GPL(blk_mq_register_disk);
+EXPORT_SYMBOL_GPL(blk_mq_register_dev);
 
 void blk_mq_sysfs_unregister(struct request_queue *q)
 {