The io_uring_register syscall supports various registration ops to allow a user to register different resources that io_uring can use.
Specifically, with IORING_REGISTER_PBUF_RING combined with the IOU_PBUF_RING_MMAP flag, the kernel allocates pages for an io_buffer_list and attaches it to the io_ring_ctx under a given bgid.
int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg)
{
struct io_uring_buf_reg reg;
struct io_buffer_list *bl, *free_bl = NULL;
int ret;
if (copy_from_user(®, arg, sizeof(reg)))
return -EFAULT;
/*...*/
if (!(reg.flags & IOU_PBUF_RING_MMAP))
ret = io_pin_pbuf_ring(®, bl);
else
ret = io_alloc_pbuf_ring(®, bl); // <-- IOU_PBUF_RING_MMAP
if (!ret) {
bl->nr_entries = reg.ring_entries;
bl->mask = reg.ring_entries - 1;
io_buffer_add_list(ctx, bl, reg.bgid); // <-- add buffer_list to ctx with bgid
return 0;
}
kfree(free_bl);
return ret;
} In the io_alloc_pbuf_ring() function below, the kernel uses __get_free_pages() to allocate pages for the buffer ring:
static int io_alloc_pbuf_ring(struct io_uring_buf_reg *reg,
struct io_buffer_list *bl)
{
gfp_t gfp = GFP_KERNEL_ACCOUNT | __GFP_ZERO | __GFP_NOWARN | __GFP_COMP;
size_t ring_size;
void *ptr;
ring_size = reg->ring_entries * sizeof(struct io_uring_buf_ring);
ptr = (void *) __get_free_pages(gfp, get_order(ring_size));
if (!ptr)
return -ENOMEM;
bl->buf_ring = ptr;
bl->is_mapped = 1;
bl->is_mmap = 1;
return 0;
} For more information click here.
General Working of a Web Application Firewall (WAF) A Web Application Firewall (WAF) acts as…
How to Send POST Requests Using curl in Linux If you work with APIs, servers,…
If you are a Linux user, you have probably seen commands like chmod 777 while…
Vim and Vi are among the most powerful text editors in the Linux world. They…
Working with compressed files is a common task for any Linux user. Whether you are…
In the digital era, an email address can reveal much more than just a contact…