Skip to content

Commit 1ac5712

Browse files
isilenceaxboe
authored andcommitted
io_uring/rsrc: don't skip offset calculation
Don't optimise for requests with offset=0. Large registered buffers are the preference and hence the user is likely to pass an offset, and the adjustments are not expensive and will be made even cheaper in following patches. Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Link: https://lore.kernel.org/r/1c2beb20470ee3c886a363d4d8340d3790db19f3.1744882081.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 70e4f9b commit 1ac5712

File tree

1 file changed

+37
-38
lines changed

1 file changed

+37
-38
lines changed

io_uring/rsrc.c

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,7 @@ static int io_import_fixed(int ddir, struct iov_iter *iter,
10361036
struct io_mapped_ubuf *imu,
10371037
u64 buf_addr, size_t len)
10381038
{
1039+
const struct bio_vec *bvec;
10391040
size_t offset;
10401041
int ret;
10411042

@@ -1054,47 +1055,45 @@ static int io_import_fixed(int ddir, struct iov_iter *iter,
10541055
offset = buf_addr - imu->ubuf;
10551056
iov_iter_bvec(iter, ddir, imu->bvec, imu->nr_bvecs, offset + len);
10561057

1057-
if (offset) {
1058-
/*
1059-
* Don't use iov_iter_advance() here, as it's really slow for
1060-
* using the latter parts of a big fixed buffer - it iterates
1061-
* over each segment manually. We can cheat a bit here for user
1062-
* registered nodes, because we know that:
1063-
*
1064-
* 1) it's a BVEC iter, we set it up
1065-
* 2) all bvecs are the same in size, except potentially the
1066-
* first and last bvec
1067-
*
1068-
* So just find our index, and adjust the iterator afterwards.
1069-
* If the offset is within the first bvec (or the whole first
1070-
* bvec, just use iov_iter_advance(). This makes it easier
1071-
* since we can just skip the first segment, which may not
1072-
* be folio_size aligned.
1073-
*/
1074-
const struct bio_vec *bvec = imu->bvec;
1058+
/*
1059+
* Don't use iov_iter_advance() here, as it's really slow for
1060+
* using the latter parts of a big fixed buffer - it iterates
1061+
* over each segment manually. We can cheat a bit here for user
1062+
* registered nodes, because we know that:
1063+
*
1064+
* 1) it's a BVEC iter, we set it up
1065+
* 2) all bvecs are the same in size, except potentially the
1066+
* first and last bvec
1067+
*
1068+
* So just find our index, and adjust the iterator afterwards.
1069+
* If the offset is within the first bvec (or the whole first
1070+
* bvec, just use iov_iter_advance(). This makes it easier
1071+
* since we can just skip the first segment, which may not
1072+
* be folio_size aligned.
1073+
*/
1074+
bvec = imu->bvec;
10751075

1076-
/*
1077-
* Kernel buffer bvecs, on the other hand, don't necessarily
1078-
* have the size property of user registered ones, so we have
1079-
* to use the slow iter advance.
1080-
*/
1081-
if (offset < bvec->bv_len) {
1082-
iter->count -= offset;
1083-
iter->iov_offset = offset;
1084-
} else if (imu->is_kbuf) {
1085-
iov_iter_advance(iter, offset);
1086-
} else {
1087-
unsigned long seg_skip;
1076+
/*
1077+
* Kernel buffer bvecs, on the other hand, don't necessarily
1078+
* have the size property of user registered ones, so we have
1079+
* to use the slow iter advance.
1080+
*/
1081+
if (offset < bvec->bv_len) {
1082+
iter->count -= offset;
1083+
iter->iov_offset = offset;
1084+
} else if (imu->is_kbuf) {
1085+
iov_iter_advance(iter, offset);
1086+
} else {
1087+
unsigned long seg_skip;
10881088

1089-
/* skip first vec */
1090-
offset -= bvec->bv_len;
1091-
seg_skip = 1 + (offset >> imu->folio_shift);
1089+
/* skip first vec */
1090+
offset -= bvec->bv_len;
1091+
seg_skip = 1 + (offset >> imu->folio_shift);
10921092

1093-
iter->bvec += seg_skip;
1094-
iter->nr_segs -= seg_skip;
1095-
iter->count -= bvec->bv_len + offset;
1096-
iter->iov_offset = offset & ((1UL << imu->folio_shift) - 1);
1097-
}
1093+
iter->bvec += seg_skip;
1094+
iter->nr_segs -= seg_skip;
1095+
iter->count -= bvec->bv_len + offset;
1096+
iter->iov_offset = offset & ((1UL << imu->folio_shift) - 1);
10981097
}
10991098

11001099
return 0;

0 commit comments

Comments
 (0)