@@ -430,9 +430,14 @@ static ssize_t queue_poll_store(struct request_queue *q, const char *page,
{
unsigned long poll_on;
ssize_t ret;
+ struct gendisk *disk = queue_to_disk(q);
- if (!q->tag_set || q->tag_set->nr_maps <= HCTX_TYPE_POLL ||
- !q->tag_set->map[HCTX_TYPE_POLL].nr_queues)
+ if (!queue_is_mq(q) && !(disk->flags & GENHD_FL_CAP_BIO_POLL))
+ return -EINVAL;
+
+ if (queue_is_mq(q) && (!q->tag_set ||
+ q->tag_set->nr_maps <= HCTX_TYPE_POLL ||
+ !q->tag_set->map[HCTX_TYPE_POLL].nr_queues))
return -EINVAL;
ret = queue_var_store(&poll_on, page, count);
@@ -442,6 +447,11 @@ static ssize_t queue_poll_store(struct request_queue *q, const char *page,
if (poll_on) {
blk_queue_flag_set(QUEUE_FLAG_POLL, q);
} else {
+ /*
+ * For bio queue, it is safe to just freeze bio submission
+ * activity because we don't read FLAG_POLL after bio is
+ * submitted.
+ */
blk_mq_freeze_queue(q);
blk_queue_flag_clear(QUEUE_FLAG_POLL, q);
blk_mq_unfreeze_queue(q);
@@ -104,6 +104,8 @@ struct partition_meta_info {
#define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 0x0100
#define GENHD_FL_NO_PART_SCAN 0x0200
#define GENHD_FL_HIDDEN 0x0400
+/* only valid for bio based disk */
+#define GENHD_FL_CAP_BIO_POLL 0x0800
enum {
DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */
Prepare for supporting bio based io polling. If one disk is capable of bio polling, we allow user to control FLAG_POLL via sysfs. Suggested-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ming Lei <ming.lei@redhat.com> --- block/blk-sysfs.c | 14 ++++++++++++-- include/linux/genhd.h | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-)