On Mon, Mar 11, 2019 at 03:35:54PM +0100, Christoph Hellwig wrote: > > struct bio_vec *prev = &bio->bi_io_vec[bio->bi_vcnt - 1]; > > > > + /* segment size is always >= PAGE_SIZE */ > > I don't think that actually is true. We have various drivers with 4k > segment size, for which this would not be true with a 64k page size > system. Please look at blk_queue_max_segment_size(): void blk_queue_max_segment_size(struct request_queue *q, unsigned int max_size) { if (max_size < PAGE_SIZE) { max_size = PAGE_SIZE; printk(KERN_INFO "%s: set to minimum %d\n", __func__, max_size); } q->limits.max_segment_size = max_size; } But your concern is correct wrt. 4k segment size vs. 64k page size, however, seems not see any such report. > > > if (page == prev->bv_page && > > offset == prev->bv_offset + prev->bv_len) { > > if (put_same_page) > > put_page(page); > > + bvec_merge: > > prev->bv_len += len; > > bio->bi_iter.bi_size += len; > > Please throw in a cleanup patch that removes prev and and always uses > bvec, then we can just move the done label up by two lines and handle > the increment of bv_len and bi_size in a common branch. Seems only one line of 'bio->bi_iter.bi_size += len;' can be shared. > > > done: > > + bio->bi_phys_segments = bio->bi_vcnt; > > + if (!bio_flagged(bio, BIO_SEG_VALID)) > > + bio_set_flag(bio, BIO_SEG_VALID); > > How would BIO_SEG_VALID get set previously? And even if it did bio_add_pc_page() is run over each page. > we wouldn't optimize much here, I'd just do it unconditionally. OK. > > Btw, there are various comments in this function that either already > were or have become out of data, like talking about REQ_PC or > file system I/O - I think they could use some love. OK. Thanks, Ming