266 lines
8.0 KiB
Diff
266 lines
8.0 KiB
Diff
|
|
From 44b5e00692dbce7b2a5eab5d56c237c967b8f03f Mon Sep 17 00:00:00 2001
|
||
|
|
From: Muyang Tian <tianmuyang@huawei.com>
|
||
|
|
Date: Tue, 22 Oct 2024 19:18:45 +0800
|
||
|
|
Subject: [PATCH] libxdp: Add tx_metadata_len/xsk_umem__create_opts() to
|
||
|
|
support AF_XDP Tx metadata
|
||
|
|
|
||
|
|
Add tx_metadata_len to support AF_XDP Tx metadata.
|
||
|
|
Also, add xsk_umem__create_opts() to provide a new way to create umem, like xdp_program__create().
|
||
|
|
Another 2 functions to create umem(xsk_umem__create() and xsk_umem__create_with_fd()) calls
|
||
|
|
xsk_umem__create_opts() internally, while outside callers do not know this change.
|
||
|
|
|
||
|
|
Signed-off-by: Muyang Tian <tianmuyang@huawei.com>
|
||
|
|
---
|
||
|
|
headers/linux/if_xdp.h | 1 +
|
||
|
|
headers/xdp/xsk.h | 32 ++++++++++++
|
||
|
|
lib/libxdp/libxdp.map | 4 ++
|
||
|
|
lib/libxdp/xsk.c | 113 ++++++++++++++++++++++++++++-------------
|
||
|
|
4 files changed, 115 insertions(+), 35 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/headers/linux/if_xdp.h b/headers/linux/if_xdp.h
|
||
|
|
index a78a809..c6569e9 100644
|
||
|
|
--- a/headers/linux/if_xdp.h
|
||
|
|
+++ b/headers/linux/if_xdp.h
|
||
|
|
@@ -70,6 +70,7 @@ struct xdp_umem_reg {
|
||
|
|
__u32 chunk_size;
|
||
|
|
__u32 headroom;
|
||
|
|
__u32 flags;
|
||
|
|
+ __u32 tx_metadata_len;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct xdp_statistics {
|
||
|
|
diff --git a/headers/xdp/xsk.h b/headers/xdp/xsk.h
|
||
|
|
index 0b4fdca..55aab26 100644
|
||
|
|
--- a/headers/xdp/xsk.h
|
||
|
|
+++ b/headers/xdp/xsk.h
|
||
|
|
@@ -194,6 +194,7 @@ int xsk_socket__fd(const struct xsk_socket *xsk);
|
||
|
|
#define XSK_UMEM__DEFAULT_FRAME_SIZE (1 << XSK_UMEM__DEFAULT_FRAME_SHIFT)
|
||
|
|
#define XSK_UMEM__DEFAULT_FRAME_HEADROOM 0
|
||
|
|
#define XSK_UMEM__DEFAULT_FLAGS 0
|
||
|
|
+#define XSK_UMEM__DEFAULT_TX_METADATA_LEN 0
|
||
|
|
|
||
|
|
struct xsk_umem_config {
|
||
|
|
__u32 fill_size;
|
||
|
|
@@ -203,6 +204,31 @@ struct xsk_umem_config {
|
||
|
|
__u32 flags;
|
||
|
|
};
|
||
|
|
|
||
|
|
+/* The following fields are optional:
|
||
|
|
+ *
|
||
|
|
+ * @fd, @size, @fill_size, @comp_size, @frame_size, @frame_headroom,
|
||
|
|
+ * @flags, @tx_metadata_len
|
||
|
|
+ * If @fd is unset, a new sockfd will be created.
|
||
|
|
+ * If @size is unset, @umem_area must be page-aligned.
|
||
|
|
+ * If the remaining fields are unset, they will be set to
|
||
|
|
+ * default value (see `xsk_set_umem_config()`).
|
||
|
|
+ *
|
||
|
|
+ * Except for the fields mentioned above, none field can be set.
|
||
|
|
+ */
|
||
|
|
+struct xsk_umem_opts {
|
||
|
|
+ size_t sz;
|
||
|
|
+ int fd;
|
||
|
|
+ __u64 size;
|
||
|
|
+ __u32 fill_size;
|
||
|
|
+ __u32 comp_size;
|
||
|
|
+ __u32 frame_size;
|
||
|
|
+ __u32 frame_headroom;
|
||
|
|
+ __u32 flags;
|
||
|
|
+ __u32 tx_metadata_len;
|
||
|
|
+ size_t :0;
|
||
|
|
+};
|
||
|
|
+#define xsk_umem_opts__last_field tx_metadata_len
|
||
|
|
+
|
||
|
|
int xsk_setup_xdp_prog(int ifindex, int *xsks_map_fd);
|
||
|
|
int xsk_socket__update_xskmap(struct xsk_socket *xsk, int xsks_map_fd);
|
||
|
|
|
||
|
|
@@ -234,6 +260,12 @@ int xsk_umem__create_with_fd(struct xsk_umem **umem,
|
||
|
|
struct xsk_ring_prod *fill,
|
||
|
|
struct xsk_ring_cons *comp,
|
||
|
|
const struct xsk_umem_config *config);
|
||
|
|
+/* Newer version to create umem by opts, recommended to use. */
|
||
|
|
+struct xsk_umem *xsk_umem__create_opts(void *umem_area,
|
||
|
|
+ struct xsk_ring_prod *fill,
|
||
|
|
+ struct xsk_ring_cons *comp,
|
||
|
|
+ struct xsk_umem_opts *opts);
|
||
|
|
+
|
||
|
|
int xsk_socket__create(struct xsk_socket **xsk,
|
||
|
|
const char *ifname, __u32 queue_id,
|
||
|
|
struct xsk_umem *umem,
|
||
|
|
diff --git a/lib/libxdp/libxdp.map b/lib/libxdp/libxdp.map
|
||
|
|
index 51f78b4..61f686e 100644
|
||
|
|
--- a/lib/libxdp/libxdp.map
|
||
|
|
+++ b/lib/libxdp/libxdp.map
|
||
|
|
@@ -80,3 +80,7 @@ LIBXDP_1.3.0 {
|
||
|
|
LIBXDP_1.4.0 {
|
||
|
|
xsk_umem__create_with_fd;
|
||
|
|
} LIBXDP_1.3.0;
|
||
|
|
+
|
||
|
|
+LIBXDP_1.5.0 {
|
||
|
|
+ xsk_umem__create_opts;
|
||
|
|
+} LIBXDP_1.4.0;
|
||
|
|
diff --git a/lib/libxdp/xsk.c b/lib/libxdp/xsk.c
|
||
|
|
index b3527fb..958a2b0 100644
|
||
|
|
--- a/lib/libxdp/xsk.c
|
||
|
|
+++ b/lib/libxdp/xsk.c
|
||
|
|
@@ -152,22 +152,13 @@ static bool xsk_page_aligned(void *buffer)
|
||
|
|
}
|
||
|
|
|
||
|
|
static void xsk_set_umem_config(struct xsk_umem_config *cfg,
|
||
|
|
- const struct xsk_umem_config *usr_cfg)
|
||
|
|
+ const struct xsk_umem_opts *opts)
|
||
|
|
{
|
||
|
|
- if (!usr_cfg) {
|
||
|
|
- cfg->fill_size = XSK_RING_PROD__DEFAULT_NUM_DESCS;
|
||
|
|
- cfg->comp_size = XSK_RING_CONS__DEFAULT_NUM_DESCS;
|
||
|
|
- cfg->frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
|
||
|
|
- cfg->frame_headroom = XSK_UMEM__DEFAULT_FRAME_HEADROOM;
|
||
|
|
- cfg->flags = XSK_UMEM__DEFAULT_FLAGS;
|
||
|
|
- return;
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- cfg->fill_size = usr_cfg->fill_size;
|
||
|
|
- cfg->comp_size = usr_cfg->comp_size;
|
||
|
|
- cfg->frame_size = usr_cfg->frame_size;
|
||
|
|
- cfg->frame_headroom = usr_cfg->frame_headroom;
|
||
|
|
- cfg->flags = usr_cfg->flags;
|
||
|
|
+ cfg->fill_size = OPTS_GET(opts, fill_size, XSK_RING_PROD__DEFAULT_NUM_DESCS);
|
||
|
|
+ cfg->comp_size = OPTS_GET(opts, comp_size, XSK_RING_CONS__DEFAULT_NUM_DESCS);
|
||
|
|
+ cfg->frame_size = OPTS_GET(opts, frame_size, XSK_UMEM__DEFAULT_FRAME_SIZE);
|
||
|
|
+ cfg->frame_headroom = OPTS_GET(opts, frame_headroom, XSK_UMEM__DEFAULT_FRAME_HEADROOM);
|
||
|
|
+ cfg->flags = OPTS_GET(opts, flags, XSK_UMEM__DEFAULT_FLAGS);
|
||
|
|
}
|
||
|
|
|
||
|
|
static int xsk_set_xdp_socket_config(struct xsk_socket_config *cfg,
|
||
|
|
@@ -306,24 +297,38 @@ out_mmap:
|
||
|
|
return err;
|
||
|
|
}
|
||
|
|
|
||
|
|
-int xsk_umem__create_with_fd(struct xsk_umem **umem_ptr, int fd,
|
||
|
|
- void *umem_area, __u64 size,
|
||
|
|
- struct xsk_ring_prod *fill,
|
||
|
|
- struct xsk_ring_cons *comp,
|
||
|
|
- const struct xsk_umem_config *usr_config)
|
||
|
|
-{
|
||
|
|
+struct xsk_umem *xsk_umem__create_opts(void *umem_area,
|
||
|
|
+ struct xsk_ring_prod *fill,
|
||
|
|
+ struct xsk_ring_cons *comp,
|
||
|
|
+ struct xsk_umem_opts *opts) {
|
||
|
|
struct xdp_umem_reg mr;
|
||
|
|
struct xsk_umem *umem;
|
||
|
|
- int err;
|
||
|
|
+ size_t mr_size;
|
||
|
|
+ int err, fd;
|
||
|
|
+ __u64 size;
|
||
|
|
+
|
||
|
|
+ if (!umem_area || !fill || !comp) {
|
||
|
|
+ err = -EFAULT;
|
||
|
|
+ goto err;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
- if (!umem_area || !umem_ptr || !fill || !comp)
|
||
|
|
- return -EFAULT;
|
||
|
|
- if (!size && !xsk_page_aligned(umem_area))
|
||
|
|
- return -EINVAL;
|
||
|
|
+ if (!OPTS_VALID(opts, xsk_umem_opts)) {
|
||
|
|
+ err = -EINVAL;
|
||
|
|
+ goto err;
|
||
|
|
+ }
|
||
|
|
+ fd = OPTS_GET(opts, fd, -1);
|
||
|
|
+ size = OPTS_GET(opts, size, 0);
|
||
|
|
+
|
||
|
|
+ if (!size && !xsk_page_aligned(umem_area)) {
|
||
|
|
+ err = -EINVAL;
|
||
|
|
+ goto err;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
umem = calloc(1, sizeof(*umem));
|
||
|
|
- if (!umem)
|
||
|
|
- return -ENOMEM;
|
||
|
|
+ if (!umem) {
|
||
|
|
+ err = -ENOMEM;
|
||
|
|
+ goto err;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
umem->fd = fd < 0 ? socket(AF_XDP, SOCK_RAW, 0) : fd;
|
||
|
|
if (umem->fd < 0) {
|
||
|
|
@@ -333,7 +338,7 @@ int xsk_umem__create_with_fd(struct xsk_umem **umem_ptr, int fd,
|
||
|
|
|
||
|
|
umem->umem_area = umem_area;
|
||
|
|
INIT_LIST_HEAD(&umem->ctx_list);
|
||
|
|
- xsk_set_umem_config(&umem->config, usr_config);
|
||
|
|
+ xsk_set_umem_config(&umem->config, opts);
|
||
|
|
|
||
|
|
memset(&mr, 0, sizeof(mr));
|
||
|
|
mr.addr = (uintptr_t)umem_area;
|
||
|
|
@@ -341,8 +346,13 @@ int xsk_umem__create_with_fd(struct xsk_umem **umem_ptr, int fd,
|
||
|
|
mr.chunk_size = umem->config.frame_size;
|
||
|
|
mr.headroom = umem->config.frame_headroom;
|
||
|
|
mr.flags = umem->config.flags;
|
||
|
|
-
|
||
|
|
- err = setsockopt(umem->fd, SOL_XDP, XDP_UMEM_REG, &mr, sizeof(mr));
|
||
|
|
+ mr.tx_metadata_len = OPTS_GET(opts, tx_metadata_len, XSK_UMEM__DEFAULT_TX_METADATA_LEN);
|
||
|
|
+
|
||
|
|
+ mr_size = sizeof(mr);
|
||
|
|
+ /* Older kernels don't support tx_metadata_len, skip if we are not setting a value */
|
||
|
|
+ if(!mr.tx_metadata_len)
|
||
|
|
+ mr_size = offsetof(struct xdp_umem_reg, tx_metadata_len);
|
||
|
|
+ err = setsockopt(umem->fd, SOL_XDP, XDP_UMEM_REG, &mr, mr_size);
|
||
|
|
if (err) {
|
||
|
|
err = -errno;
|
||
|
|
goto out_socket;
|
||
|
|
@@ -354,14 +364,47 @@ int xsk_umem__create_with_fd(struct xsk_umem **umem_ptr, int fd,
|
||
|
|
|
||
|
|
umem->fill_save = fill;
|
||
|
|
umem->comp_save = comp;
|
||
|
|
- *umem_ptr = umem;
|
||
|
|
- return 0;
|
||
|
|
-
|
||
|
|
+ return umem;
|
||
|
|
out_socket:
|
||
|
|
close(umem->fd);
|
||
|
|
out_umem_alloc:
|
||
|
|
free(umem);
|
||
|
|
- return err;
|
||
|
|
+err:
|
||
|
|
+ return libxdp_err_ptr(err, true);
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+int xsk_umem__create_with_fd(struct xsk_umem **umem_ptr, int fd,
|
||
|
|
+ void *umem_area, __u64 size,
|
||
|
|
+ struct xsk_ring_prod *fill,
|
||
|
|
+ struct xsk_ring_cons *comp,
|
||
|
|
+ const struct xsk_umem_config *usr_config)
|
||
|
|
+{
|
||
|
|
+ struct xsk_umem *umem;
|
||
|
|
+
|
||
|
|
+ if(!umem_ptr)
|
||
|
|
+ return -EFAULT;
|
||
|
|
+
|
||
|
|
+ DECLARE_LIBXDP_OPTS(xsk_umem_opts, opts,
|
||
|
|
+ .fd = fd,
|
||
|
|
+ .size = size,
|
||
|
|
+ .fill_size = usr_config ? usr_config->fill_size
|
||
|
|
+ : XSK_RING_PROD__DEFAULT_NUM_DESCS,
|
||
|
|
+ .comp_size = usr_config ? usr_config->comp_size
|
||
|
|
+ : XSK_RING_CONS__DEFAULT_NUM_DESCS,
|
||
|
|
+ .frame_size = usr_config ? usr_config->frame_size
|
||
|
|
+ : XSK_UMEM__DEFAULT_FRAME_SIZE,
|
||
|
|
+ .frame_headroom = usr_config ? usr_config->frame_headroom
|
||
|
|
+ : XSK_UMEM__DEFAULT_FRAME_HEADROOM,
|
||
|
|
+ .flags = usr_config ? usr_config->flags
|
||
|
|
+ : XSK_UMEM__DEFAULT_FLAGS,
|
||
|
|
+ );
|
||
|
|
+
|
||
|
|
+ umem = xsk_umem__create_opts(umem_area, fill, comp, &opts);
|
||
|
|
+ if(!umem)
|
||
|
|
+ return errno;
|
||
|
|
+
|
||
|
|
+ *umem_ptr = umem;
|
||
|
|
+ return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int xsk_umem__create(struct xsk_umem **umem_ptr, void *umem_area,
|
||
|
|
--
|
||
|
|
2.41.0
|
||
|
|
|