On Tue, Jan 11, 2022 at 09:56:36AM +0800, Ming Lei wrote: > 2) block throttle is block layer internal stuff, and we shouldn't expose > blk_throtl_charge_bio_split() to driver. > > Maybe rename the new API as submit_split_bio_noacct(), but we can't > reuse submit_bio_noacct() simply, otherwise blk_throtl_charge_bio_split() > needs to be exported. submit_bio_noacct should only ever be used for resubmitting bios that came up from the upper layer, although they might not always be "split". blk_throtl_charge_bio_split > Another ides is to clearing BIO_THROTTLED before calling submit_bio_noacct(), > meantime blk-throttle code needs to change to avoid double accounting of bio > bytes, so the caller of submit_bio_noacct() still needs some change. > This way can get smooth IOPS throttle, but needs to call __blk_throtl_bio > for split bio one more time. > > Or other idea for this bio split vs. iops limit issue? Well, if you want a helper specificly for splits, add one that actally specifically handles splits and makes the callers life easier, something like: void bio_submit_splice(struct bio *split, struct bio *orig) { split->bi_opf |= REQ_NOMERGE; trace_block_split(split, orig->bi_iter.bi_sector); submit_bio_noacct(orig); blk_throtl_charge_bio_split(orig); } including a proper kerneldoc comment. But I still fail to grasp how a split is so different from just resubmitting a not split bio.