On Mon, Jan 13, 2020 at 03:00:40PM -0700, Jens Axboe wrote: > On 1/13/20 2:58 PM, Matthew Wilcox wrote: > > On Mon, Jan 13, 2020 at 06:00:52PM +0000, Chris Mason wrote: > >> This is true, I didn't explain that part well ;) Depending on > >> compression etc we might end up poking the xarray inside the actual IO > >> functions, but the main difference is that btrfs is building a single > >> bio. You're moving the plug so you'll merge into single bio, but I'd > >> rather build 2MB bios than merge them. > > > > Why don't we store a bio pointer inside the plug? You're opencoding that, > > iomap is opencoding that, and I bet there's a dozen other places where > > we pass a bio around. Then blk_finish_plug can submit the bio. > > Plugs aren't necessarily a bio, they can be callbacks too. I'm thinking something as simple as this: @@ -1711,6 +1711,7 @@ void blk_start_plug(struct blk_plug *plug) INIT_LIST_HEAD(&plug->mq_list); INIT_LIST_HEAD(&plug->cb_list); + plug->bio = NULL; plug->rq_count = 0; plug->multiple_queues = false; @@ -1786,6 +1787,8 @@ void blk_finish_plug(struct blk_plug *plug) { if (plug != current->plug) return; + if (plug->bio) + submit_bio(plug->bio); blk_flush_plug_list(plug, false); current->plug = NULL; @@ -1160,6 +1160,7 @@ extern void blk_set_queue_dying(struct request_queue *); struct blk_plug { struct list_head mq_list; /* blk-mq requests */ struct list_head cb_list; /* md requires an unplug callback */ + struct bio *bio; unsigned short rq_count; bool multiple_queues; }; with accessors to 'get_current_bio()' and 'set_current_bio()'.