2025-02-14 16:09:36 -08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
|
#ifndef IOU_ZC_RX_H
|
|
|
|
|
#define IOU_ZC_RX_H
|
|
|
|
|
|
|
|
|
|
#include <linux/io_uring_types.h>
|
2025-05-01 13:17:18 +01:00
|
|
|
#include <linux/dma-buf.h>
|
2025-02-14 16:09:41 -08:00
|
|
|
#include <linux/socket.h>
|
2025-02-14 16:09:37 -08:00
|
|
|
#include <net/page_pool/types.h>
|
2025-02-14 16:09:38 -08:00
|
|
|
#include <net/net_trackers.h>
|
2025-02-14 16:09:37 -08:00
|
|
|
|
2026-03-23 12:43:54 +00:00
|
|
|
#define ZCRX_SUPPORTED_REG_FLAGS (ZCRX_REG_IMPORT | ZCRX_REG_NODEV)
|
2026-02-15 23:29:39 +00:00
|
|
|
#define ZCRX_FEATURES (ZCRX_FEATURE_RX_PAGE_SIZE)
|
|
|
|
|
|
2025-05-01 13:17:16 +01:00
|
|
|
struct io_zcrx_mem {
|
|
|
|
|
unsigned long size;
|
2025-05-01 13:17:18 +01:00
|
|
|
bool is_dmabuf;
|
2025-05-01 13:17:16 +01:00
|
|
|
|
|
|
|
|
struct page **pages;
|
|
|
|
|
unsigned long nr_folios;
|
2025-07-02 15:29:07 +01:00
|
|
|
struct sg_table page_sg_table;
|
2025-07-16 22:04:09 +01:00
|
|
|
unsigned long account_pages;
|
2025-09-16 15:27:54 +01:00
|
|
|
struct sg_table *sgt;
|
2025-05-01 13:17:18 +01:00
|
|
|
|
|
|
|
|
struct dma_buf_attachment *attach;
|
|
|
|
|
struct dma_buf *dmabuf;
|
2025-05-01 13:17:16 +01:00
|
|
|
};
|
|
|
|
|
|
2025-02-14 16:09:37 -08:00
|
|
|
struct io_zcrx_area {
|
|
|
|
|
struct net_iov_area nia;
|
|
|
|
|
struct io_zcrx_ifq *ifq;
|
2025-02-14 16:09:39 -08:00
|
|
|
atomic_t *user_refs;
|
2025-02-14 16:09:37 -08:00
|
|
|
|
2025-02-14 16:09:40 -08:00
|
|
|
bool is_mapped;
|
2025-02-14 16:09:37 -08:00
|
|
|
u16 area_id;
|
|
|
|
|
|
|
|
|
|
/* freelist */
|
|
|
|
|
spinlock_t freelist_lock ____cacheline_aligned_in_smp;
|
|
|
|
|
u32 free_count;
|
|
|
|
|
u32 *freelist;
|
2025-05-01 13:17:16 +01:00
|
|
|
|
|
|
|
|
struct io_zcrx_mem mem;
|
2025-02-14 16:09:37 -08:00
|
|
|
};
|
2025-02-14 16:09:36 -08:00
|
|
|
|
2026-03-23 12:43:56 +00:00
|
|
|
struct zcrx_rq {
|
|
|
|
|
spinlock_t lock;
|
|
|
|
|
struct io_uring *ring;
|
|
|
|
|
struct io_uring_zcrx_rqe *rqes;
|
|
|
|
|
u32 cached_head;
|
|
|
|
|
u32 nr_entries;
|
|
|
|
|
};
|
|
|
|
|
|
2025-02-14 16:09:36 -08:00
|
|
|
struct io_zcrx_ifq {
|
2025-02-14 16:09:37 -08:00
|
|
|
struct io_zcrx_area *area;
|
2025-09-16 15:27:55 +01:00
|
|
|
unsigned niov_shift;
|
2025-11-04 14:44:56 -08:00
|
|
|
struct user_struct *user;
|
|
|
|
|
struct mm_struct *mm_account;
|
2026-03-23 12:44:03 +00:00
|
|
|
bool kern_readable;
|
2025-02-14 16:09:37 -08:00
|
|
|
|
2026-03-23 12:43:56 +00:00
|
|
|
struct zcrx_rq rq ____cacheline_aligned_in_smp;
|
2025-02-14 16:09:36 -08:00
|
|
|
|
|
|
|
|
u32 if_rxq;
|
2025-02-14 16:09:38 -08:00
|
|
|
struct device *dev;
|
|
|
|
|
struct net_device *netdev;
|
|
|
|
|
netdevice_tracker netdev_tracker;
|
2025-11-04 14:44:58 -08:00
|
|
|
refcount_t refs;
|
2025-11-13 10:46:14 +00:00
|
|
|
/* counts userspace facing users like io_uring */
|
|
|
|
|
refcount_t user_refs;
|
2025-09-16 15:27:56 +01:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Page pool and net configuration lock, can be taken deeper in the
|
|
|
|
|
* net stack.
|
|
|
|
|
*/
|
|
|
|
|
struct mutex pp_lock;
|
2026-03-23 12:43:55 +00:00
|
|
|
struct io_mapped_region rq_region;
|
2025-02-14 16:09:36 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_IO_URING_ZCRX)
|
2025-11-13 10:46:12 +00:00
|
|
|
int io_zcrx_ctrl(struct io_ring_ctx *ctx, void __user *arg, unsigned nr_arg);
|
2026-03-23 12:44:05 +00:00
|
|
|
int io_register_zcrx(struct io_ring_ctx *ctx,
|
2025-02-14 16:09:36 -08:00
|
|
|
struct io_uring_zcrx_ifq_reg __user *arg);
|
2026-03-23 12:44:05 +00:00
|
|
|
void io_unregister_zcrx(struct io_ring_ctx *ctx);
|
2026-03-23 12:43:50 +00:00
|
|
|
void io_terminate_zcrx(struct io_ring_ctx *ctx);
|
2025-02-14 16:09:41 -08:00
|
|
|
int io_zcrx_recv(struct io_kiocb *req, struct io_zcrx_ifq *ifq,
|
|
|
|
|
struct socket *sock, unsigned int flags,
|
2025-02-23 20:13:18 -08:00
|
|
|
unsigned issue_flags, unsigned int *len);
|
2025-04-20 10:31:18 +01:00
|
|
|
struct io_mapped_region *io_zcrx_get_region(struct io_ring_ctx *ctx,
|
|
|
|
|
unsigned int id);
|
2025-02-14 16:09:36 -08:00
|
|
|
#else
|
2026-03-23 12:44:05 +00:00
|
|
|
static inline int io_register_zcrx(struct io_ring_ctx *ctx,
|
|
|
|
|
struct io_uring_zcrx_ifq_reg __user *arg)
|
2025-02-14 16:09:36 -08:00
|
|
|
{
|
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
}
|
2026-03-23 12:44:05 +00:00
|
|
|
static inline void io_unregister_zcrx(struct io_ring_ctx *ctx)
|
2025-02-14 16:09:36 -08:00
|
|
|
{
|
|
|
|
|
}
|
2026-03-23 12:43:50 +00:00
|
|
|
static inline void io_terminate_zcrx(struct io_ring_ctx *ctx)
|
|
|
|
|
{
|
|
|
|
|
}
|
2025-02-14 16:09:41 -08:00
|
|
|
static inline int io_zcrx_recv(struct io_kiocb *req, struct io_zcrx_ifq *ifq,
|
|
|
|
|
struct socket *sock, unsigned int flags,
|
2025-02-23 20:13:18 -08:00
|
|
|
unsigned issue_flags, unsigned int *len)
|
2025-02-14 16:09:41 -08:00
|
|
|
{
|
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
}
|
2025-04-20 10:31:18 +01:00
|
|
|
static inline struct io_mapped_region *io_zcrx_get_region(struct io_ring_ctx *ctx,
|
|
|
|
|
unsigned int id)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2025-11-13 10:46:12 +00:00
|
|
|
static inline int io_zcrx_ctrl(struct io_ring_ctx *ctx,
|
|
|
|
|
void __user *arg, unsigned nr_arg)
|
|
|
|
|
{
|
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
}
|
2025-02-14 16:09:36 -08:00
|
|
|
#endif
|
|
|
|
|
|
2025-02-14 16:09:41 -08:00
|
|
|
int io_recvzc(struct io_kiocb *req, unsigned int issue_flags);
|
|
|
|
|
int io_recvzc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
|
|
|
|
|
|
2025-02-14 16:09:36 -08:00
|
|
|
#endif
|