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.
Showing the changes to include/uapi (1 of 2 files). Show all
Unified · Split
| @@ -410,6 +410,29 @@ struct ublk_param_dma_align { · 409 unmodified lines | |||
| 410 | __u8 pad[4]; | 410 | __u8 pad[4]; |
| 411 | }; | 411 | }; |
| 412 | 412 | ||
| 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 | |||
| 413 | struct ublk_params { | 436 | struct ublk_params { |
| 414 | /* | 437 | /* |
| 415 | * Total length of parameters, userspace has to set 'len' for both | 438 | * Total length of parameters, userspace has to set 'len' for both |
| @@ -423,6 +446,7 @@ struct ublk_params { · 7 unmodified lines | |||
| 423 | #define UBLK_PARAM_TYPE_DEVT (1 << 2) | 446 | #define UBLK_PARAM_TYPE_DEVT (1 << 2) |
| 424 | #define UBLK_PARAM_TYPE_ZONED (1 << 3) | 447 | #define UBLK_PARAM_TYPE_ZONED (1 << 3) |
| 425 | #define UBLK_PARAM_TYPE_DMA_ALIGN (1 << 4) | 448 | #define UBLK_PARAM_TYPE_DMA_ALIGN (1 << 4) |
| 449 | #define UBLK_PARAM_TYPE_SEGMENT (1 << 5) | ||
| 426 | __u32 types; /* types of parameter included */ | 450 | __u32 types; /* types of parameter included */ |
| 427 | 451 | ||
| 428 | struct ublk_param_basic basic; | 452 | struct ublk_param_basic basic; |
| @@ -430,6 +454,7 @@ struct ublk_params { · 1 unmodified line | |||
| 430 | struct ublk_param_devt devt; | 454 | struct ublk_param_devt devt; |
| 431 | struct ublk_param_zoned zoned; | 455 | struct ublk_param_zoned zoned; |
| 432 | struct ublk_param_dma_align dma; | 456 | struct ublk_param_dma_align dma; |
| 457 | struct ublk_param_segment seg; | ||
| 433 | }; | 458 | }; |
| 434 | 459 | ||
| 435 | #endif | 460 | #endif |