From: Jeffle Xu <jeffl...@linux.alibaba.com>

This method can be used to check if bio-based device supports IO polling
or not. For mq devices, checking for hw queue in polling mode is
adequate, while the sanity check shall be implementation specific for
bio-based devices. For example, dm device needs to check if all
underlying devices are capable of IO polling.

Though bio-based device may have done the sanity check during the
device initialization phase, cacheing the result of this sanity check
(such as by cacheing in the queue_flags) may not work. Because for dm
devices, users could change the state of the underlying devices through
'/sys/block/<dev>/io_poll', bypassing the dm device above. In this case,
the cached result of the very beginning sanity check could be
out-of-date. Thus the sanity check needs to be done every time 'io_poll'
is to be modified.

Signed-off-by: Jeffle Xu <jeffl...@linux.alibaba.com>
---
 block/blk-sysfs.c      | 14 +++++++++++---
 include/linux/blkdev.h |  1 +
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 0f4f0c8a7825..367c1d9a55c6 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -426,9 +426,17 @@ static ssize_t queue_poll_store(struct request_queue *q, 
const char *page,
        unsigned long poll_on;
        ssize_t ret;
 
-       if (!q->tag_set || q->tag_set->nr_maps <= HCTX_TYPE_POLL ||
-           !q->tag_set->map[HCTX_TYPE_POLL].nr_queues)
-               return -EINVAL;
+       if (queue_is_mq(q)) {
+               if (!q->tag_set || q->tag_set->nr_maps <= HCTX_TYPE_POLL ||
+                   !q->tag_set->map[HCTX_TYPE_POLL].nr_queues)
+                       return -EINVAL;
+       } else {
+               struct gendisk *disk = queue_to_disk(q);
+
+               if (!disk->fops->poll_capable ||
+                   !disk->fops->poll_capable(disk))
+                       return -EINVAL;
+       }
 
        ret = queue_var_store(&poll_on, page, count);
        if (ret < 0)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index bfab74b45f15..a46f975f2a2f 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1881,6 +1881,7 @@ struct block_device_operations {
        int (*report_zones)(struct gendisk *, sector_t sector,
                        unsigned int nr_zones, report_zones_cb cb, void *data);
        char *(*devnode)(struct gendisk *disk, umode_t *mode);
+       bool (*poll_capable)(struct gendisk *disk);
        struct module *owner;
        const struct pr_ops *pr_ops;
 };
-- 
2.29.2

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel

Reply via email to