On 01/12/2020 13:32, Christoph Hellwig wrote: > On Tue, Dec 01, 2020 at 01:17:49PM +0000, Pavel Begunkov wrote: >> I was thinking about memcpy bvec instead of iterating as a first step, >> and then try to reuse passed in bvec. >> >> A thing that doesn't play nice with that is setting BIO_WORKINGSET in >> __bio_add_page(), which requires to iterate all pages anyway. I have no >> clue what it is, so rather to ask if we can optimise it out somehow? >> Apart from pre-computing for specific cases... >> >> E.g. can pages of a single bvec segment be both in and out of a working >> set? (i.e. PageWorkingset(page)). > > Adding Johannes for the PageWorkingset logic, which keeps confusing me > everytime I look at it. I think it is intended to deal with pages > being swapped out and in, and doesn't make much sense to look at in > any form for direct I/O, but as said I'm rather confused by this code. > > If PageWorkingset is a non-issue we should be able to just point the > bio at the biovec array. I think that be done by allocating the bio > with nr_iovecs == 0, and then just updating >bi_io_vec and ->bi_vcnt > using a little helper like this: Yeah, that's the idea, but also wanted to verify that callers don't free it while in use, or if that's not the case to make it conditional by adding a flag in iov_iter. Can anybody vow right off the bat that all callers behave well? > > static inline void bio_assign_bvec(struct bio *bio, struct bio_vec *bvecs, > unsigned short nr_bvecs) > { > WARN_ON_ONCE(BVEC_POOL_IDX(bio) != 0); > bio->bi_io_vec = bvecs; > bio->bi_vcnt = nr_bvecs; > } > -- Pavel Begunkov