{
  "slug": "io-uring-provided-buffers",
  "term": "io_uring provided buffers",
  "aliases": [
    "io_uring buffer selection",
    "io_uring provided-buffer ring"
  ],
  "definition": "io_uring provided buffers are application-supplied buffers grouped for kernel selection by supported I/O requests.",
  "note": "Selection: IOSQE_BUFFER_SELECT and buf_group choose a supplied group. Supported read or receive requests select a destination; supported sends can instead select outgoing data. If IORING_CQE_F_BUFFER is set, the upper 16 CQE flag bits give the application buffer ID, not a fixed-buffer index. [buffers-provide] [buffers-send] [buffers-opcodes]\n\nRing publication: io_uring_buf_ring_add writes a descriptor; io_uring_buf_ring_advance publishes previously added descriptors for kernel consumption. The insertion offset is relative to the ring tail, not the application buffer ID. Keep the ID-to-address mapping correct for each provisioning cycle. [buffers-add] [buffers-advance]\n\nReplenishment: io_uring_cqe_seen releases a completion slot, not a payload buffer back to its pool. For ordinary non-incremental buffers, finish processing a returned payload before adding and publishing that buffer again. The combined io_uring_buf_ring_cq_advance helper publishes previously added buffers while advancing the CQ; it does not populate their descriptors. [buffers-seen] [buffers-cq-advance]\n\nContinuation: in the Linux v6.16 ABI, IORING_CQE_F_MORE concerns additional completions from the request. IORING_CQE_F_BUF_MORE instead means an incrementally consumed buffer remains in use by the kernel. Do not recycle that entire buffer merely because one completion arrived; ordinary non-incremental buffer return is a different case. [buffers-uapi]",
  "status": "shipping",
  "supersedes": [],
  "supersededBy": [],
  "firstSeen": null,
  "lastSeen": null,
  "updated": "2026-11-08",
  "provenance": [
    "Primary documentation and pinned Linux v6.16 ABI review; no native kernel execution, performance benchmark or durability experiment."
  ],
  "advantages": [
    {
      "text": "Lets supported operations select from a supplied group instead of requiring a separate preselected payload buffer for each request.",
      "citationIds": [
        "buffers-provide"
      ]
    }
  ],
  "limitations": [
    {
      "text": "Publishing a buffer transfers it to the ring; do not republish memory while the application or kernel still needs its contents.",
      "citationIds": [
        "buffers-advance",
        "buffers-uapi"
      ]
    },
    {
      "text": "For multishot receive, check IORING_CQE_F_MORE on every completion, including nonnegative results; replenishing buffers does not restart a terminated request.",
      "citationIds": [
        "buffers-recv-multishot"
      ]
    },
    {
      "text": "Multishot read requires a pollable file type; ordinary regular files fail with -EBADFD in the reviewed API.",
      "citationIds": [
        "buffers-read-multishot"
      ]
    },
    {
      "text": "IORING_FEAT_RECVSEND_BUNDLE in the features returned at ring setup reports the reviewed send-buffer capability; it is not an SQE flag. Supported requests still use IOSQE_BUFFER_SELECT with buf_group.",
      "citationIds": [
        "buffers-setup",
        "buffers-send-uapi"
      ]
    }
  ],
  "related": [
    "io-uring",
    "io-uring-registered-buffers",
    "io-uring-cqe"
  ],
  "citations": [
    {
      "id": "buffers-provide",
      "title": "liburing 2.8: buffer groups and selected IDs",
      "url": "https://github.com/axboe/liburing/blob/liburing-2.8/man/io_uring_prep_provide_buffers.3",
      "accessed": "2026-11-08"
    },
    {
      "id": "buffers-add",
      "title": "liburing 2.8: ring offsets and application buffer IDs",
      "url": "https://github.com/axboe/liburing/blob/liburing-2.8/man/io_uring_buf_ring_add.3",
      "accessed": "2026-11-08"
    },
    {
      "id": "buffers-advance",
      "title": "liburing 2.8: publishing buffers and ownership",
      "url": "https://github.com/axboe/liburing/blob/liburing-2.8/man/io_uring_buf_ring_advance.3",
      "accessed": "2026-11-08"
    },
    {
      "id": "buffers-seen",
      "title": "liburing 2.8: completion-slot consumption",
      "url": "https://github.com/axboe/liburing/blob/liburing-2.8/man/io_uring_cqe_seen.3",
      "accessed": "2026-11-08"
    },
    {
      "id": "buffers-cq-advance",
      "title": "liburing 2.8: combined CQ and buffer publication",
      "url": "https://github.com/axboe/liburing/blob/liburing-2.8/man/io_uring_buf_ring_cq_advance.3",
      "accessed": "2026-11-08"
    },
    {
      "id": "buffers-uapi",
      "title": "Linux v6.16: CQE buffer-selection and continuation flags",
      "url": "https://github.com/torvalds/linux/blob/v6.16/include/uapi/linux/io_uring.h",
      "accessed": "2026-11-08"
    },
    {
      "id": "hesela-buffers",
      "title": "Hesela: fixed buffers and provided-buffer ownership",
      "url": "https://hesela.com/analyses/io-uring-completion-ordering-durability/#buffer-selection",
      "accessed": "2026-11-08"
    },
    {
      "id": "buffers-recv-multishot",
      "title": "liburing 2.8: receive termination and resubmission",
      "url": "https://github.com/axboe/liburing/blob/liburing-2.8/man/io_uring_prep_recv.3",
      "accessed": "2026-11-08"
    },
    {
      "id": "buffers-read-multishot",
      "title": "liburing 2.8: pollable-file requirement for multishot read",
      "url": "https://github.com/axboe/liburing/blob/liburing-2.8/man/io_uring_prep_read_multishot.3",
      "accessed": "2026-11-08"
    },
    {
      "id": "buffers-send",
      "title": "liburing 2.8: provided buffers for supported send operations",
      "url": "https://github.com/axboe/liburing/blob/liburing-2.8/man/io_uring_prep_send.3",
      "accessed": "2026-11-08"
    },
    {
      "id": "buffers-opcodes",
      "title": "Linux v6.16: SEND opcode supports buffer selection",
      "url": "https://github.com/torvalds/linux/blob/v6.16/io_uring/opdef.c",
      "accessed": "2026-11-08"
    },
    {
      "id": "buffers-setup",
      "title": "liburing 2.8: reported send-buffer capability at ring setup",
      "url": "https://github.com/axboe/liburing/blob/liburing-2.8/man/io_uring_setup.2",
      "accessed": "2026-11-08"
    },
    {
      "id": "buffers-send-uapi",
      "title": "Linux v6.10: separate setup feature bits and SQE selection flags",
      "url": "https://github.com/torvalds/linux/blob/v6.10/include/uapi/linux/io_uring.h",
      "accessed": "2026-11-08"
    }
  ]
}
