from block layer perspective
not request_fn based, blk-mq based instead., thus bypassing io scheduler. using one hw queue, so mapping all per-cpu queues into that signle hw queue. requests from generic block layer will first be put on the per-cpu queues and delay work will merge all the requests from sw queues into the hw queue and send to virtio_queue_rq to process it.
from virtio point of view
one virt queue
a small set of virtio_blk_config
out (ro) and in buffer (writable). in for read, both used for write (order - out,in)
kick doesn't mean flush, because host may still buffer it.
sync part:
submit_bio -> generic_make_request -> blk_mq_make_request -> blk_mq_run_hw_queue -> kblockd_schedule_delayed_work
delayed work:
blk_mq_work_fn -> __blk_mq_run_hw_queue -> virtio_queue_rq