@@ -40,8 +40,26 @@ enum io_uring_cmd_flags {
IO_URING_F_COMPAT = (1 << 12),
};
+struct io_rsrc_node {
+ unsigned char type;
+ unsigned char flags;
+ int refs;
+
+ u64 tag;
+ union {
+ unsigned long file_ptr;
+ struct io_mapped_buf *buf;
+ };
+};
+
+typedef void (io_uring_kbuf_ack_t) (struct io_rsrc_node *);
+
struct io_mapped_buf {
- u64 addr;
+ /* 'addr' is always 0 for kernel buffer */
+ union {
+ u64 addr;
+ io_uring_kbuf_ack_t *kbuf_ack;
+ };
unsigned int len;
unsigned int nr_bvecs;
refcount_t refs;
@@ -441,6 +441,18 @@ int io_files_update(struct io_kiocb *req, unsigned int issue_flags)
return IOU_OK;
}
+static void __io_free_buf_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node)
+{
+ struct io_mapped_buf *buf = node->buf;
+
+ if (node->flags & IORING_RSRC_F_BUF_KERNEL) {
+ if (buf->kbuf_ack)
+ buf->kbuf_ack(node);
+ } else {
+ io_buffer_unmap(ctx, node);
+ }
+}
+
void io_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node)
{
bool need_free = node->flags & IORING_RSRC_F_NEED_FREE;
@@ -457,7 +469,7 @@ void io_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node)
break;
case IORING_RSRC_BUFFER:
if (node->buf)
- io_buffer_unmap(ctx, node);
+ __io_free_buf_node(ctx, node);
break;
default:
WARN_ON_ONCE(1);
@@ -14,18 +14,7 @@ enum {
__IORING_RSRC_LAST_TYPE,
IORING_RSRC_F_NEED_FREE = 1 << 0,
-};
-
-struct io_rsrc_node {
- unsigned char type;
- unsigned char flags;
- int refs;
-
- u64 tag;
- union {
- unsigned long file_ptr;
- struct io_mapped_buf *buf;
- };
+ IORING_RSRC_F_BUF_KERNEL = 1 << 1,
};
struct io_imu_folio_data {
Add one callback to 'io_mapped_buffer' for giving back kernel buffer after the buffer is used. Meantime move 'io_rsrc_node' into public header, and it will become part of kernel buffer API. Signed-off-by: Ming Lei <ming.lei@redhat.com> --- include/linux/io_uring_types.h | 20 +++++++++++++++++++- io_uring/rsrc.c | 14 +++++++++++++- io_uring/rsrc.h | 13 +------------ 3 files changed, 33 insertions(+), 14 deletions(-)