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.

selftests/ublk: add UBLK_F_SHMEM_ZC support for loop target

Add loop_queue_shmem_zc_io() which handles I/O requests marked with
UBLK_IO_F_SHMEM_ZC. When the kernel sets this flag, the request data
lives in a registered shared memory buffer — decode index + offset
from iod->addr and use the server's mmap as the I/O buffer.

The dispatch check in loop_queue_tgt_rw_io() routes SHMEM_ZC requests
to this new function, bypassing the normal buffer registration path.

Signed-off-by: Ming Lei <ming.lei@redhat.com>
Link: https://patch.msgid.link/20260331153207.3635125-7-ming.lei@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Ming Lei and committed by
Jens Axboe
ec20aa44 166b476b

+38
+38
tools/testing/selftests/ublk/file_backed.c
··· 27 27 return 1; 28 28 } 29 29 30 + /* 31 + * Shared memory zero-copy I/O: when UBLK_IO_F_SHMEM_ZC is set, the 32 + * request's data lives in a registered shared memory buffer. Decode 33 + * index + offset from iod->addr and use the server's mmap of that 34 + * buffer as the I/O buffer for the backing file. 35 + */ 36 + static int loop_queue_shmem_zc_io(struct ublk_thread *t, struct ublk_queue *q, 37 + const struct ublksrv_io_desc *iod, int tag) 38 + { 39 + unsigned ublk_op = ublksrv_get_op(iod); 40 + enum io_uring_op op = ublk_to_uring_op(iod, 0); 41 + __u64 file_offset = iod->start_sector << 9; 42 + __u32 len = iod->nr_sectors << 9; 43 + __u32 shmem_idx = ublk_shmem_zc_index(iod->addr); 44 + __u32 shmem_off = ublk_shmem_zc_offset(iod->addr); 45 + struct io_uring_sqe *sqe[1]; 46 + void *addr; 47 + 48 + if (shmem_idx >= UBLK_BUF_MAX || !shmem_table[shmem_idx].mmap_base) 49 + return -EINVAL; 50 + 51 + addr = shmem_table[shmem_idx].mmap_base + shmem_off; 52 + 53 + ublk_io_alloc_sqes(t, sqe, 1); 54 + if (!sqe[0]) 55 + return -ENOMEM; 56 + 57 + io_uring_prep_rw(op, sqe[0], ublk_get_registered_fd(q, 1), 58 + addr, len, file_offset); 59 + io_uring_sqe_set_flags(sqe[0], IOSQE_FIXED_FILE); 60 + sqe[0]->user_data = build_user_data(tag, ublk_op, 0, q->q_id, 1); 61 + return 1; 62 + } 63 + 30 64 static int loop_queue_tgt_rw_io(struct ublk_thread *t, struct ublk_queue *q, 31 65 const struct ublksrv_io_desc *iod, int tag) 32 66 { ··· 74 40 struct io_uring_sqe *sqe[3]; 75 41 void *addr = io->buf_addr; 76 42 unsigned short buf_index = ublk_io_buf_idx(t, q, tag); 43 + 44 + /* shared memory zero-copy path */ 45 + if (iod->op_flags & UBLK_IO_F_SHMEM_ZC) 46 + return loop_queue_shmem_zc_io(t, q, iod, tag); 77 47 78 48 if (iod->op_flags & UBLK_IO_F_INTEGRITY) { 79 49 ublk_io_alloc_sqes(t, sqe, 1);