Skip to content

Commit ebf695f

Browse files
Ming Leiaxboe
authored andcommitted
ublk: add segment parameter
IO split is usually bad in io_uring world, since -EAGAIN is caused and IO handling may have to fallback to io-wq, this way does hurt performance. ublk starts to support zero copy recently, for avoiding unnecessary IO split, ublk driver's segment limit should be aligned with backend device's segment limit. Another reason is that io_buffer_register_bvec() needs to allocate bvecs, which number is aligned with ublk request segment number, so that big memory allocation can be avoided by setting reasonable max_segments limit. So add segment parameter for providing ublk server chance to align segment limit with backend, and keep it reasonable from implementation viewpoint. Signed-off-by: Ming Lei <ming.lei@redhat.com> Link: https://lore.kernel.org/r/20250327095123.179113-7-ming.lei@redhat.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent b460f32 commit ebf695f

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

drivers/block/ublk_drv.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
#define UBLK_PARAM_TYPE_ALL \
7575
(UBLK_PARAM_TYPE_BASIC | UBLK_PARAM_TYPE_DISCARD | \
7676
UBLK_PARAM_TYPE_DEVT | UBLK_PARAM_TYPE_ZONED | \
77-
UBLK_PARAM_TYPE_DMA_ALIGN)
77+
UBLK_PARAM_TYPE_DMA_ALIGN | UBLK_PARAM_TYPE_SEGMENT)
7878

7979
struct ublk_rq_data {
8080
struct kref ref;
@@ -580,6 +580,18 @@ static int ublk_validate_params(const struct ublk_device *ub)
580580
return -EINVAL;
581581
}
582582

583+
if (ub->params.types & UBLK_PARAM_TYPE_SEGMENT) {
584+
const struct ublk_param_segment *p = &ub->params.seg;
585+
586+
if (!is_power_of_2(p->seg_boundary_mask + 1))
587+
return -EINVAL;
588+
589+
if (p->seg_boundary_mask + 1 < UBLK_MIN_SEGMENT_SIZE)
590+
return -EINVAL;
591+
if (p->max_segment_size < UBLK_MIN_SEGMENT_SIZE)
592+
return -EINVAL;
593+
}
594+
583595
return 0;
584596
}
585597

@@ -2370,6 +2382,12 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd)
23702382
if (ub->params.types & UBLK_PARAM_TYPE_DMA_ALIGN)
23712383
lim.dma_alignment = ub->params.dma.alignment;
23722384

2385+
if (ub->params.types & UBLK_PARAM_TYPE_SEGMENT) {
2386+
lim.seg_boundary_mask = ub->params.seg.seg_boundary_mask;
2387+
lim.max_segment_size = ub->params.seg.max_segment_size;
2388+
lim.max_segments = ub->params.seg.max_segments;
2389+
}
2390+
23732391
if (wait_for_completion_interruptible(&ub->completion) != 0)
23742392
return -EINTR;
23752393

include/uapi/linux/ublk_cmd.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,29 @@ struct ublk_param_dma_align {
410410
__u8 pad[4];
411411
};
412412

413+
#define UBLK_MIN_SEGMENT_SIZE 4096
414+
/*
415+
* If any one of the three segment parameter is set as 0, the behavior is
416+
* undefined.
417+
*/
418+
struct ublk_param_segment {
419+
/*
420+
* seg_boundary_mask + 1 needs to be power_of_2(), and the sum has
421+
* to be >= UBLK_MIN_SEGMENT_SIZE(4096)
422+
*/
423+
__u64 seg_boundary_mask;
424+
425+
/*
426+
* max_segment_size could be override by virt_boundary_mask, so be
427+
* careful when setting both.
428+
*
429+
* max_segment_size has to be >= UBLK_MIN_SEGMENT_SIZE(4096)
430+
*/
431+
__u32 max_segment_size;
432+
__u16 max_segments;
433+
__u8 pad[2];
434+
};
435+
413436
struct ublk_params {
414437
/*
415438
* Total length of parameters, userspace has to set 'len' for both
@@ -423,13 +446,15 @@ struct ublk_params {
423446
#define UBLK_PARAM_TYPE_DEVT (1 << 2)
424447
#define UBLK_PARAM_TYPE_ZONED (1 << 3)
425448
#define UBLK_PARAM_TYPE_DMA_ALIGN (1 << 4)
449+
#define UBLK_PARAM_TYPE_SEGMENT (1 << 5)
426450
__u32 types; /* types of parameter included */
427451

428452
struct ublk_param_basic basic;
429453
struct ublk_param_discard discard;
430454
struct ublk_param_devt devt;
431455
struct ublk_param_zoned zoned;
432456
struct ublk_param_dma_align dma;
457+
struct ublk_param_segment seg;
433458
};
434459

435460
#endif

0 commit comments

Comments
 (0)