On 1/13/20 3:10 PM, Matthew Wilcox wrote: > 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()'. It's a little odd imho, the plugging generally collect requests. Sounds what you're looking for is some plug owner private data, which just happens to be a bio in this case? Is this over repeated calls to some IO generating helper? Would it be more efficient if that helper could generate the full bio in one go, instead of piecemeal? -- Jens Axboe