Skip to content

Commit 0e7192b

Browse files
committed
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 <[email protected]>
1 parent cc7a112 commit 0e7192b

File tree

4 files changed

+115
-35
lines changed

4 files changed

+115
-35
lines changed

headers/linux/if_xdp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ struct xdp_umem_reg {
7070
__u32 chunk_size;
7171
__u32 headroom;
7272
__u32 flags;
73+
__u32 tx_metadata_len;
7374
};
7475

7576
struct xdp_statistics {

headers/xdp/xsk.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ int xsk_socket__fd(const struct xsk_socket *xsk);
194194
#define XSK_UMEM__DEFAULT_FRAME_SIZE (1 << XSK_UMEM__DEFAULT_FRAME_SHIFT)
195195
#define XSK_UMEM__DEFAULT_FRAME_HEADROOM 0
196196
#define XSK_UMEM__DEFAULT_FLAGS 0
197+
#define XSK_UMEM__DEFAULT_TX_METADATA_LEN 0
197198

198199
struct xsk_umem_config {
199200
__u32 fill_size;
@@ -203,6 +204,31 @@ struct xsk_umem_config {
203204
__u32 flags;
204205
};
205206

207+
/* The following fields are optional:
208+
*
209+
* @fd, @size, @fill_size, @comp_size, @frame_size, @frame_headroom,
210+
* @flags, @tx_metadata_len
211+
* If @fd is unset, a new sockfd will be created.
212+
* If @size is unset, @umem_area must be page-aligned.
213+
* If the remaining fields are unset, they will be set to
214+
* default value (see `xsk_set_umem_config()`).
215+
*
216+
* Except for the fields mentioned above, none field can be set.
217+
*/
218+
struct xsk_umem_opts {
219+
size_t sz;
220+
int fd;
221+
__u64 size;
222+
__u32 fill_size;
223+
__u32 comp_size;
224+
__u32 frame_size;
225+
__u32 frame_headroom;
226+
__u32 flags;
227+
__u32 tx_metadata_len;
228+
size_t :0;
229+
};
230+
#define xsk_umem_opts__last_field tx_metadata_len
231+
206232
int xsk_setup_xdp_prog(int ifindex, int *xsks_map_fd);
207233
int xsk_socket__update_xskmap(struct xsk_socket *xsk, int xsks_map_fd);
208234

@@ -234,6 +260,12 @@ int xsk_umem__create_with_fd(struct xsk_umem **umem,
234260
struct xsk_ring_prod *fill,
235261
struct xsk_ring_cons *comp,
236262
const struct xsk_umem_config *config);
263+
/* Newer version to create umem by opts, recommended to use. */
264+
struct xsk_umem *xsk_umem__create_opts(void *umem_area,
265+
struct xsk_ring_prod *fill,
266+
struct xsk_ring_cons *comp,
267+
struct xsk_umem_opts *opts);
268+
237269
int xsk_socket__create(struct xsk_socket **xsk,
238270
const char *ifname, __u32 queue_id,
239271
struct xsk_umem *umem,

lib/libxdp/libxdp.map

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,7 @@ LIBXDP_1.3.0 {
8080
LIBXDP_1.4.0 {
8181
xsk_umem__create_with_fd;
8282
} LIBXDP_1.3.0;
83+
84+
LIBXDP_1.5.0 {
85+
xsk_umem__create_opts;
86+
} LIBXDP_1.4.0;

lib/libxdp/xsk.c

Lines changed: 78 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -152,22 +152,13 @@ static bool xsk_page_aligned(void *buffer)
152152
}
153153

154154
static void xsk_set_umem_config(struct xsk_umem_config *cfg,
155-
const struct xsk_umem_config *usr_cfg)
155+
const struct xsk_umem_opts *opts)
156156
{
157-
if (!usr_cfg) {
158-
cfg->fill_size = XSK_RING_PROD__DEFAULT_NUM_DESCS;
159-
cfg->comp_size = XSK_RING_CONS__DEFAULT_NUM_DESCS;
160-
cfg->frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
161-
cfg->frame_headroom = XSK_UMEM__DEFAULT_FRAME_HEADROOM;
162-
cfg->flags = XSK_UMEM__DEFAULT_FLAGS;
163-
return;
164-
}
165-
166-
cfg->fill_size = usr_cfg->fill_size;
167-
cfg->comp_size = usr_cfg->comp_size;
168-
cfg->frame_size = usr_cfg->frame_size;
169-
cfg->frame_headroom = usr_cfg->frame_headroom;
170-
cfg->flags = usr_cfg->flags;
157+
cfg->fill_size = OPTS_GET(opts, fill_size, XSK_RING_PROD__DEFAULT_NUM_DESCS);
158+
cfg->comp_size = OPTS_GET(opts, comp_size, XSK_RING_CONS__DEFAULT_NUM_DESCS);
159+
cfg->frame_size = OPTS_GET(opts, frame_size, XSK_UMEM__DEFAULT_FRAME_SIZE);
160+
cfg->frame_headroom = OPTS_GET(opts, frame_headroom, XSK_UMEM__DEFAULT_FRAME_HEADROOM);
161+
cfg->flags = OPTS_GET(opts, flags, XSK_UMEM__DEFAULT_FLAGS);
171162
}
172163

173164
static int xsk_set_xdp_socket_config(struct xsk_socket_config *cfg,
@@ -306,24 +297,38 @@ static int xsk_create_umem_rings(struct xsk_umem *umem, int fd,
306297
return err;
307298
}
308299

309-
int xsk_umem__create_with_fd(struct xsk_umem **umem_ptr, int fd,
310-
void *umem_area, __u64 size,
311-
struct xsk_ring_prod *fill,
312-
struct xsk_ring_cons *comp,
313-
const struct xsk_umem_config *usr_config)
314-
{
300+
struct xsk_umem *xsk_umem__create_opts(void *umem_area,
301+
struct xsk_ring_prod *fill,
302+
struct xsk_ring_cons *comp,
303+
struct xsk_umem_opts *opts) {
315304
struct xdp_umem_reg mr;
316305
struct xsk_umem *umem;
317-
int err;
306+
size_t mr_size;
307+
int err, fd;
308+
__u64 size;
309+
310+
if (!umem_area || !fill || !comp) {
311+
err = -EFAULT;
312+
goto err;
313+
}
318314

319-
if (!umem_area || !umem_ptr || !fill || !comp)
320-
return -EFAULT;
321-
if (!size && !xsk_page_aligned(umem_area))
322-
return -EINVAL;
315+
if (!OPTS_VALID(opts, xsk_umem_opts)) {
316+
err = -EINVAL;
317+
goto err;
318+
}
319+
fd = OPTS_GET(opts, fd, -1);
320+
size = OPTS_GET(opts, size, 0);
321+
322+
if (!size && !xsk_page_aligned(umem_area)) {
323+
err = -EINVAL;
324+
goto err;
325+
}
323326

324327
umem = calloc(1, sizeof(*umem));
325-
if (!umem)
326-
return -ENOMEM;
328+
if (!umem) {
329+
err = -ENOMEM;
330+
goto err;
331+
}
327332

328333
umem->fd = fd < 0 ? socket(AF_XDP, SOCK_RAW, 0) : fd;
329334
if (umem->fd < 0) {
@@ -333,16 +338,21 @@ int xsk_umem__create_with_fd(struct xsk_umem **umem_ptr, int fd,
333338

334339
umem->umem_area = umem_area;
335340
INIT_LIST_HEAD(&umem->ctx_list);
336-
xsk_set_umem_config(&umem->config, usr_config);
341+
xsk_set_umem_config(&umem->config, opts);
337342

338343
memset(&mr, 0, sizeof(mr));
339344
mr.addr = (uintptr_t)umem_area;
340345
mr.len = size;
341346
mr.chunk_size = umem->config.frame_size;
342347
mr.headroom = umem->config.frame_headroom;
343348
mr.flags = umem->config.flags;
344-
345-
err = setsockopt(umem->fd, SOL_XDP, XDP_UMEM_REG, &mr, sizeof(mr));
349+
mr.tx_metadata_len = OPTS_GET(opts, tx_metadata_len, XSK_UMEM__DEFAULT_TX_METADATA_LEN);
350+
351+
mr_size = sizeof(mr);
352+
/* Older kernels don't support tx_metadata_len, skip if we are not setting a value */
353+
if(!mr.tx_metadata_len)
354+
mr_size = offsetof(struct xdp_umem_reg, tx_metadata_len);
355+
err = setsockopt(umem->fd, SOL_XDP, XDP_UMEM_REG, &mr, mr_size);
346356
if (err) {
347357
err = -errno;
348358
goto out_socket;
@@ -354,14 +364,47 @@ int xsk_umem__create_with_fd(struct xsk_umem **umem_ptr, int fd,
354364

355365
umem->fill_save = fill;
356366
umem->comp_save = comp;
357-
*umem_ptr = umem;
358-
return 0;
359-
367+
return umem;
360368
out_socket:
361369
close(umem->fd);
362370
out_umem_alloc:
363371
free(umem);
364-
return err;
372+
err:
373+
return libxdp_err_ptr(err, true);
374+
}
375+
376+
int xsk_umem__create_with_fd(struct xsk_umem **umem_ptr, int fd,
377+
void *umem_area, __u64 size,
378+
struct xsk_ring_prod *fill,
379+
struct xsk_ring_cons *comp,
380+
const struct xsk_umem_config *usr_config)
381+
{
382+
struct xsk_umem *umem;
383+
384+
if(!umem_ptr)
385+
return -EFAULT;
386+
387+
DECLARE_LIBXDP_OPTS(xsk_umem_opts, opts,
388+
.fd = fd,
389+
.size = size,
390+
.fill_size = usr_config ? usr_config->fill_size
391+
: XSK_RING_PROD__DEFAULT_NUM_DESCS,
392+
.comp_size = usr_config ? usr_config->comp_size
393+
: XSK_RING_CONS__DEFAULT_NUM_DESCS,
394+
.frame_size = usr_config ? usr_config->frame_size
395+
: XSK_UMEM__DEFAULT_FRAME_SIZE,
396+
.frame_headroom = usr_config ? usr_config->frame_headroom
397+
: XSK_UMEM__DEFAULT_FRAME_HEADROOM,
398+
.flags = usr_config ? usr_config->flags
399+
: XSK_UMEM__DEFAULT_FLAGS,
400+
);
401+
402+
umem = xsk_umem__create_opts(umem_area, fill, comp, &opts);
403+
if(!umem)
404+
return errno;
405+
406+
*umem_ptr = umem;
407+
return 0;
365408
}
366409

367410
int xsk_umem__create(struct xsk_umem **umem_ptr, void *umem_area,

0 commit comments

Comments
 (0)