---
name: "io_uring_register_buf_ring"
section: "3"
platform: "linux"
package: "liburing"
version: "2.15-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/io_uring_register_buf_ring"
---

# io\_uring\_register\_buf\_ring(3)

register buffer ring for provided buffers

## NAME

io\_uring\_register\_buf\_ring - register buffer ring for provided buffers

## SYNOPSIS

```
#include <liburing.h>
```

**int io\_uring\_register\_buf\_ring(struct io\_uring \****ring***,**                                **struct io\_uring\_buf\_reg \****reg***,**                                **unsigned int** *flags***);**

## DESCRIPTION

The [**io\_uring\_register\_buf\_ring**(3)](/io_uring_register_buf_ring/3.md) function registers a shared buffer ring to be used with provided buffers. For the request types that support it, provided buffers are given to the ring and one is selected by a request if it has **IOSQE\_BUFFER\_SELECT** set in the SQE *flags*, when the request is ready to receive data. This allows both clear ownership of the buffer lifetime, and a way to have more read/receive type of operations in flight than buffers available.

The *reg* argument must be filled in with the appropriate information. It looks as follows:

```
struct io_uring_buf_reg {
    __u64 ring_addr;
    __u32 ring_entries;
    __u16 bgid;
    __u16 flags;
    __u32 min_left;
    __u32 resv[5];
};
```

The *ring\_addr* field must contain the address to the memory allocated to fit this ring. The memory must be page aligned and hence allocated appropriately using eg [**posix\_memalign**(3)](/posix_memalign/3.md) or similar. The size of the ring is the product of *ring\_entries* and the size of *struct io\_uring\_buf*. *ring\_entries* is the desired size of the ring, and must be a power-of-2 in size. The maximum size allowed is 2^15 (32768). *bgid* is the buffer group ID associated with this ring. SQEs that select a buffer have a buffer group associated with them in their *buf\_group* field, and the associated CQEs will have **IORING\_CQE\_F\_BUFFER** set in their *flags* member, which will also contain the specific ID of the buffer selected. *min\_left* is the minimum value that should be left in an incrementally consumed buffer ring for the buffer to be considered valid. If not set, defaults to a single byte. Only valid with **IOU\_PBUF\_RING\_INC** set in *flags .* The rest of the fields are reserved and must be cleared to zero.

The *flags* argument can be set to one of the following values:

- **IOU\_PBUF\_RING\_INC**

  The buffers in this ring can be incrementally consumed. With partial consumption, each completion of a given buffer ID will continue where the previous one left off, or from the start if no completions have been seen yet. When more completions should be expected for a given buffer ID, the CQE will have **IORING\_CQE\_F\_BUF\_MORE** set in the *flags* member. Available since 6.12.

A shared buffer ring looks as follows:

```
struct io_uring_buf_ring {
    union {
        struct {
            __u64 resv1;
            __u32 resv2;
            __u16 resv3;
            __u16 tail;
        };
        struct io_uring_buf bufs[0];
    };
};
```

where *tail* is the index at which the application can insert new buffers for consumption by requests, and *struct io\_uring\_buf* is buffer definition:

```
struct io_uring_buf {
    __u64 addr;
    __u32 len;
    __u16 bid;
    __u16 resv;
};
```

where *addr* is the address for the buffer, *len* is the length of the buffer in bytes, and *bid* is the buffer ID that will be returned in the CQE once consumed.

Reserved fields must not be touched. Applications must use [**io\_uring\_buf\_ring\_init**(3)](/io_uring_buf_ring_init/3.md) to initialise the buffer ring before use. Applications may use [**io\_uring\_buf\_ring\_add**(3)](/io_uring_buf_ring_add/3.md) and [**io\_uring\_buf\_ring\_advance**(3)](/io_uring_buf_ring_advance/3.md) or [**io\_uring\_buf\_ring\_cq\_advance**(3)](/io_uring_buf_ring_cq_advance/3.md) to provide buffers, which will set these fields and update the tail.

Available since 5.19.

## RETURN VALUE

On success [**io\_uring\_register\_buf\_ring**(3)](/io_uring_register_buf_ring/3.md) returns 0. On failure it returns **-errno**.

## NOTES

Unless manual setup is needed, it's recommended to use [**io\_uring\_setup\_buf\_ring**(3)](/io_uring_setup_buf_ring/3.md) as it provides a simpler way to setup a provided buffer ring.

## SEE ALSO

[**io\_uring\_buf\_ring\_init**(3)](/io_uring_buf_ring_init/3.md), [**io\_uring\_buf\_ring\_add**(3)](/io_uring_buf_ring_add/3.md), [**io\_uring\_setup\_buf\_ring**(3)](/io_uring_setup_buf_ring/3.md), [**io\_uring\_buf\_ring\_advance**(3)](/io_uring_buf_ring_advance/3.md), [**io\_uring\_buf\_ring\_cq\_advance**(3)](/io_uring_buf_ring_cq_advance/3.md)
