Skip to content

Commit 041c16a

Browse files
committed
Merge tag 'for-7.0/io_uring-zcrx-large-buffers-20260206' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux
Pull io_uring large rx buffer support from Jens Axboe: "Now that the networking updates are upstream, here's the support for large buffers for zcrx. Using larger (bigger than 4K) rx buffers can increase the effiency of zcrx. For example, it's been shown that using 32K buffers can decrease CPU usage by ~30% compared to 4K buffers" * tag 'for-7.0/io_uring-zcrx-large-buffers-20260206' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux: io_uring/zcrx: implement large rx buffer support
2 parents e99785a + 795663b commit 041c16a

2 files changed

Lines changed: 34 additions & 6 deletions

File tree

include/uapi/linux/io_uring.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1104,7 +1104,7 @@ struct io_uring_zcrx_ifq_reg {
11041104

11051105
struct io_uring_zcrx_offsets offsets;
11061106
__u32 zcrx_id;
1107-
__u32 __resv2;
1107+
__u32 rx_buf_len;
11081108
__u64 __resv[3];
11091109
};
11101110

io_uring/zcrx.c

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ static inline struct page *io_zcrx_iov_page(const struct net_iov *niov)
5555
return area->mem.pages[net_iov_idx(niov) << niov_pages_shift];
5656
}
5757

58+
static int io_area_max_shift(struct io_zcrx_mem *mem)
59+
{
60+
struct sg_table *sgt = mem->sgt;
61+
struct scatterlist *sg;
62+
unsigned shift = -1U;
63+
unsigned i;
64+
65+
for_each_sgtable_dma_sg(sgt, sg, i)
66+
shift = min(shift, __ffs(sg->length));
67+
return shift;
68+
}
69+
5870
static int io_populate_area_dma(struct io_zcrx_ifq *ifq,
5971
struct io_zcrx_area *area)
6072
{
@@ -417,12 +429,21 @@ static int io_zcrx_append_area(struct io_zcrx_ifq *ifq,
417429
}
418430

419431
static int io_zcrx_create_area(struct io_zcrx_ifq *ifq,
420-
struct io_uring_zcrx_area_reg *area_reg)
432+
struct io_uring_zcrx_area_reg *area_reg,
433+
struct io_uring_zcrx_ifq_reg *reg)
421434
{
435+
int buf_size_shift = PAGE_SHIFT;
422436
struct io_zcrx_area *area;
423437
unsigned nr_iovs;
424438
int i, ret;
425439

440+
if (reg->rx_buf_len) {
441+
if (!is_power_of_2(reg->rx_buf_len) ||
442+
reg->rx_buf_len < PAGE_SIZE)
443+
return -EINVAL;
444+
buf_size_shift = ilog2(reg->rx_buf_len);
445+
}
446+
426447
ret = -ENOMEM;
427448
area = kzalloc(sizeof(*area), GFP_KERNEL);
428449
if (!area)
@@ -433,7 +454,12 @@ static int io_zcrx_create_area(struct io_zcrx_ifq *ifq,
433454
if (ret)
434455
goto err;
435456

436-
ifq->niov_shift = PAGE_SHIFT;
457+
if (buf_size_shift > io_area_max_shift(&area->mem)) {
458+
ret = -ERANGE;
459+
goto err;
460+
}
461+
462+
ifq->niov_shift = buf_size_shift;
437463
nr_iovs = area->mem.size >> ifq->niov_shift;
438464
area->nia.num_niovs = nr_iovs;
439465

@@ -743,8 +769,7 @@ int io_register_zcrx_ifq(struct io_ring_ctx *ctx,
743769
return -EINVAL;
744770
if (copy_from_user(&reg, arg, sizeof(reg)))
745771
return -EFAULT;
746-
if (!mem_is_zero(&reg.__resv, sizeof(reg.__resv)) ||
747-
reg.__resv2 || reg.zcrx_id)
772+
if (!mem_is_zero(&reg.__resv, sizeof(reg.__resv)) || reg.zcrx_id)
748773
return -EINVAL;
749774
if (reg.flags & ZCRX_REG_IMPORT)
750775
return import_zcrx(ctx, arg, &reg);
@@ -801,10 +826,11 @@ int io_register_zcrx_ifq(struct io_ring_ctx *ctx,
801826
}
802827
get_device(ifq->dev);
803828

804-
ret = io_zcrx_create_area(ifq, &area);
829+
ret = io_zcrx_create_area(ifq, &area, &reg);
805830
if (ret)
806831
goto netdev_put_unlock;
807832

833+
mp_param.rx_page_size = 1U << ifq->niov_shift;
808834
mp_param.mp_ops = &io_uring_pp_zc_ops;
809835
mp_param.mp_priv = ifq;
810836
ret = __net_mp_open_rxq(ifq->netdev, reg.if_rxq, &mp_param, NULL);
@@ -822,6 +848,8 @@ int io_register_zcrx_ifq(struct io_ring_ctx *ctx,
822848
goto err;
823849
}
824850

851+
reg.rx_buf_len = 1U << ifq->niov_shift;
852+
825853
if (copy_to_user(arg, &reg, sizeof(reg)) ||
826854
copy_to_user(u64_to_user_ptr(reg.region_ptr), &rd, sizeof(rd)) ||
827855
copy_to_user(u64_to_user_ptr(reg.area_ptr), &area, sizeof(area))) {

0 commit comments

Comments
 (0)