Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

io_uring/rsrc: don't use blk_rq_nr_phys_segments() as number of bvecs

io_buffer_register_bvec() currently uses blk_rq_nr_phys_segments() as
the number of bvecs in the request. However, bvecs may be split into
multiple segments depending on the queue limits. Thus, the number of
segments may overestimate the number of bvecs. For ublk devices, the
only current users of io_buffer_register_bvec(), virt_boundary_mask,
seg_boundary_mask, max_segments, and max_segment_size can all be set
arbitrarily by the ublk server process.
Set imu->nr_bvecs based on the number of bvecs the rq_for_each_bvec()
loop actually yields. However, continue using blk_rq_nr_phys_segments()
as an upper bound on the number of bvecs when allocating imu to avoid
needing to iterate the bvecs a second time.

Link: https://lore.kernel.org/io-uring/20251111191530.1268875-1-csander@purestorage.com/
Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
Fixes: 27cb27b6d5ea ("io_uring: add support for kernel registered bvecs")
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Caleb Sander Mateos and committed by
Jens Axboe
2d0e88f3 6a77267d

+9 -7
+9 -7
io_uring/rsrc.c
··· 943 943 struct req_iterator rq_iter; 944 944 struct io_mapped_ubuf *imu; 945 945 struct io_rsrc_node *node; 946 - struct bio_vec bv, *bvec; 947 - u16 nr_bvecs; 946 + struct bio_vec bv; 947 + unsigned int nr_bvecs = 0; 948 948 int ret = 0; 949 949 950 950 io_ring_submit_lock(ctx, issue_flags); ··· 965 965 goto unlock; 966 966 } 967 967 968 - nr_bvecs = blk_rq_nr_phys_segments(rq); 969 - imu = io_alloc_imu(ctx, nr_bvecs); 968 + /* 969 + * blk_rq_nr_phys_segments() may overestimate the number of bvecs 970 + * but avoids needing to iterate over the bvecs 971 + */ 972 + imu = io_alloc_imu(ctx, blk_rq_nr_phys_segments(rq)); 970 973 if (!imu) { 971 974 kfree(node); 972 975 ret = -ENOMEM; ··· 980 977 imu->len = blk_rq_bytes(rq); 981 978 imu->acct_pages = 0; 982 979 imu->folio_shift = PAGE_SHIFT; 983 - imu->nr_bvecs = nr_bvecs; 984 980 refcount_set(&imu->refs, 1); 985 981 imu->release = release; 986 982 imu->priv = rq; 987 983 imu->is_kbuf = true; 988 984 imu->dir = 1 << rq_data_dir(rq); 989 985 990 - bvec = imu->bvec; 991 986 rq_for_each_bvec(bv, rq, rq_iter) 992 - *bvec++ = bv; 987 + imu->bvec[nr_bvecs++] = bv; 988 + imu->nr_bvecs = nr_bvecs; 993 989 994 990 node->buf = imu; 995 991 data->nodes[index] = node;