CNDP  22.08.0
xskdev.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2019-2022 Intel Corporation
3  */
4 
5 #ifndef _XSKDEV_H_
6 #define _XSKDEV_H_
7 
16 #include <poll.h> // for pollfd
17 #include <pthread.h> // for pthread_mutex_t, pthread_mutex_init, pthre...
18 #include <stdint.h> // for uint16_t, uint32_t
19 #include <stdio.h> // for FILE, NULL, size_t
20 #if USE_LIBXDP
21 #include <xdp/xsk.h>
22 #else
23 #include <bpf/xsk.h>
24 #endif
25 #include <net/if.h> // for IF_NAMESIZE
26 
27 #include <cne_common.h> // for CNDP_API, CNE_STD_C11
28 #include <cne_lport.h> // for lport_stats_t, buf_alloc_t, buf_free_t
29 #include <pktmbuf.h> // for pktmbuf_t
30 #include <uds.h>
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 #ifndef SOL_XDP
37 #define SOL_XDP 283
38 #endif
39 
40 #ifndef AF_XDP
41 #define AF_XDP 44
42 #endif
43 
44 #ifndef PF_XDP
45 #define PF_XDP AF_XDP
46 #endif
47 
48 #ifndef XDP_USE_NEED_WAKEUP
49 /* If this option is set, the driver might go sleep and in that case
50  * the XDP_RING_NEED_WAKEUP flag in the fill and/or Tx rings will be
51  * set. If it is set, the application need to explicitly wake up the
52  * driver with a poll() (Rx and Tx) or sendto() (Tx only). If you are
53  * running the driver and the application on the same core, you should
54  * use this option so that the kernel will yield to the user space
55  * application.
56  */
57 #define XDP_USE_NEED_WAKEUP (1 << 3)
58 #endif
59 
60 #define XSKDEV_STATS_FLAG (1 << 0)
61 #define XSKDEV_RX_FQ_TX_CQ_FLAG (1 << 1)
63 #define AF_XDP_DFLT_BUSY_BUDGET 64
64 #define AF_XDP_DFLT_BUSY_TIMEOUT 20
65 
66 #ifndef SO_PREFER_BUSY_POLL
67 #define SO_PREFER_BUSY_POLL 69
68 #endif
69 #ifndef SO_BUSY_POLL_BUDGET
70 #define SO_BUSY_POLL_BUDGET 70
71 #endif
72 
73 typedef void *(*xskdev_pull_cq_addr_t)(uint64_t addr, uint64_t umem_addr, uint64_t mask,
74  uint64_t pool_header_sz);
75 typedef uint64_t (*xskdev_get_mbuf_addr_tx_t)(void *xi, void *mb, uint64_t umem_addr);
76 typedef uint16_t (*xskdev_get_mbuf_t)(void *xi, void *umem_addr, const struct xdp_desc *d,
77  void *buf);
78 typedef uint16_t (*xskdev_get_mbuf_rx_t)(void *xi, void *umem_addr, const struct xdp_desc *d,
79  void **buf);
80 
81 struct xskdev_umem {
82  struct xsk_ring_prod fq;
83  struct xsk_ring_cons cq;
84  struct xsk_umem *umem;
85  void *umem_addr;
86  size_t umem_size;
87  uint32_t obj_sz;
88  uint32_t fq_size;
89 };
90 
91 struct xskdev_queue {
93  union {
94  struct xsk_ring_cons rx;
95  struct xsk_ring_prod tx;
96  };
97  struct xskdev_umem *ux;
98  struct xsk_socket *xsk;
99  struct pollfd fds;
100 };
101 
102 /* Defines to map the xskdev_queue to be Rx/Tx like queues */
103 typedef struct xskdev_queue xskdev_rxq_t;
104 typedef struct xskdev_queue xskdev_txq_t;
105 
106 typedef struct xskdev_info {
107  TAILQ_ENTRY(xskdev_info) next;
108  char ifname[IF_NAMESIZE];
109  unsigned int if_index;
110  uint32_t prog_id;
111  pktmbuf_info_t *pi;
112  xskdev_rxq_t rxq;
113  xskdev_txq_t txq;
114  lport_stats_t stats;
115  pthread_mutex_t tx_lock;
116  int xdp_flags;
117  uint32_t busy_timeout;
118  uint32_t busy_budget;
119  uds_info_t *uds_info;
120  int xsk_map_fd;
122  /* byte flags to mirror the lport_cfg_t.flags bits */
123  bool unprivileged;
124  bool needs_wakeup;
125  bool skb_mode;
126  bool busy_polling;
127  bool shared_umem;
129  lport_buf_mgmt_t buf_mgmt;
130  xskdev_get_mbuf_addr_tx_t
131  __get_mbuf_addr_tx;
132  xskdev_get_mbuf_rx_t __get_mbuf_rx;
133  xskdev_pull_cq_addr_t __pull_cq_addr;
134  struct xdp_statistics orig_stats;
135 } xskdev_info_t;
136 
145 CNDP_API xskdev_info_t *xskdev_socket_create(struct lport_cfg *c);
146 
153 CNDP_API void xskdev_socket_destroy(xskdev_info_t *xi);
154 
167 CNDP_API __cne_always_inline uint16_t
168 xskdev_rx_burst(xskdev_info_t *xi, void **bufs, uint16_t nb_pkts)
169 {
170  return xi->buf_mgmt.buf_rx_burst(xi, bufs, nb_pkts);
171 }
172 
185 CNDP_API __cne_always_inline uint16_t
186 xskdev_tx_burst(xskdev_info_t *xi, void **bufs, uint16_t nb_pkts)
187 {
188  return xi->buf_mgmt.buf_tx_burst(xi, bufs, nb_pkts);
189 }
190 
201 CNDP_API int xskdev_stats_get(xskdev_info_t *xi, lport_stats_t *stats);
202 
211 CNDP_API int xskdev_stats_reset(xskdev_info_t *xi);
212 
221 CNDP_API void xskdev_dump(xskdev_info_t *xi, uint32_t flags);
222 
229 CNDP_API void xskdev_dump_all(uint32_t flags);
230 
243 CNDP_API int xskdev_print_stats(const char *name, lport_stats_t *s, bool dbg_stats);
244 
253 CNDP_API __cne_always_inline void *
254 xskdev_arg_get(xskdev_info_t *xi)
255 {
256  return xi->buf_mgmt.buf_arg;
257 }
258 
271 CNDP_API __cne_always_inline int
272 xskdev_buf_alloc(xskdev_info_t *xi, void **bufs, uint16_t nb_bufs)
273 {
274  return xi->buf_mgmt.buf_alloc(xskdev_arg_get(xi), bufs, nb_bufs);
275 }
276 
287 CNDP_API __cne_always_inline void
288 xskdev_buf_free(xskdev_info_t *xi, void **bufs, uint16_t nb_bufs)
289 {
290  xi->buf_mgmt.buf_free(xskdev_arg_get(xi), bufs, nb_bufs);
291 }
292 
304 CNDP_API __cne_always_inline void
305 xskdev_buf_set_len(xskdev_info_t *xi, void *buf, int len)
306 {
307  xi->buf_mgmt.buf_set_len(buf, len);
308 }
309 
321 CNDP_API __cne_always_inline void
322 xskdev_buf_set_data_len(xskdev_info_t *xi, void *buf, int len)
323 {
324  xi->buf_mgmt.buf_set_data_len(buf, len);
325 }
326 
337 CNDP_API __cne_always_inline void
338 xskdev_buf_set_data(xskdev_info_t *xi, void *buf, uint64_t off)
339 {
340  xi->buf_mgmt.buf_set_data(buf, off);
341 }
342 
353 CNDP_API __cne_always_inline uint16_t
354 xskdev_buf_get_data_len(xskdev_info_t *xi, void *buf)
355 {
356  return xi->buf_mgmt.buf_get_data_len(buf);
357 }
358 
369 CNDP_API __cne_always_inline uint64_t
370 xskdev_buf_get_data(xskdev_info_t *xi, void *buf)
371 {
372  return xi->buf_mgmt.buf_get_data(buf);
373 }
374 
385 CNDP_API __cne_always_inline uint64_t
386 xskdev_buf_get_addr(xskdev_info_t *xi, void *buf)
387 {
388  return xi->buf_mgmt.buf_get_addr(buf);
389 }
390 
399 CNDP_API __cne_always_inline void **
400 xskdev_buf_inc_ptr(xskdev_info_t *xi, void **buf)
401 {
402  return xi->buf_mgmt.buf_inc_ptr(buf);
403 }
404 
419 CNDP_API __cne_always_inline void
420 xskdev_buf_reset(xskdev_info_t *xi, void *buf, uint32_t buf_len, size_t headroom)
421 {
422  xi->buf_mgmt.buf_reset(buf, buf_len, headroom);
423 }
424 
425 #ifdef __cplusplus
426 }
427 #endif
428 
429 #endif /* _XSKDEV_H_ */
#define CNE_STD_C11
Definition: cne_common.h:91
#define __cne_always_inline
Definition: cne_common.h:218
CNDP_API __cne_always_inline void xskdev_buf_set_data(xskdev_info_t *xi, void *buf, uint64_t off)
Definition: xskdev.h:338
CNDP_API __cne_always_inline uint64_t xskdev_buf_get_addr(xskdev_info_t *xi, void *buf)
Definition: xskdev.h:386
CNDP_API __cne_always_inline uint16_t xskdev_rx_burst(xskdev_info_t *xi, void **bufs, uint16_t nb_pkts)
Definition: xskdev.h:168
CNDP_API xskdev_info_t * xskdev_socket_create(struct lport_cfg *c)
CNDP_API __cne_always_inline void xskdev_buf_reset(xskdev_info_t *xi, void *buf, uint32_t buf_len, size_t headroom)
Definition: xskdev.h:420
CNDP_API void xskdev_socket_destroy(xskdev_info_t *xi)
CNDP_API void xskdev_dump_all(uint32_t flags)
CNDP_API __cne_always_inline void * xskdev_arg_get(xskdev_info_t *xi)
Definition: xskdev.h:254
CNDP_API void xskdev_dump(xskdev_info_t *xi, uint32_t flags)
CNDP_API int xskdev_stats_get(xskdev_info_t *xi, lport_stats_t *stats)
CNDP_API __cne_always_inline void ** xskdev_buf_inc_ptr(xskdev_info_t *xi, void **buf)
Definition: xskdev.h:400
CNDP_API __cne_always_inline void xskdev_buf_free(xskdev_info_t *xi, void **bufs, uint16_t nb_bufs)
Definition: xskdev.h:288
CNDP_API __cne_always_inline uint16_t xskdev_tx_burst(xskdev_info_t *xi, void **bufs, uint16_t nb_pkts)
Definition: xskdev.h:186
CNDP_API __cne_always_inline void xskdev_buf_set_data_len(xskdev_info_t *xi, void *buf, int len)
Definition: xskdev.h:322
CNDP_API __cne_always_inline int xskdev_buf_alloc(xskdev_info_t *xi, void **bufs, uint16_t nb_bufs)
Definition: xskdev.h:272
CNDP_API __cne_always_inline uint64_t xskdev_buf_get_data(xskdev_info_t *xi, void *buf)
Definition: xskdev.h:370
CNDP_API int xskdev_stats_reset(xskdev_info_t *xi)
CNDP_API __cne_always_inline void xskdev_buf_set_len(xskdev_info_t *xi, void *buf, int len)
Definition: xskdev.h:305
CNDP_API __cne_always_inline uint16_t xskdev_buf_get_data_len(xskdev_info_t *xi, void *buf)
Definition: xskdev.h:354
CNDP_API int xskdev_print_stats(const char *name, lport_stats_t *s, bool dbg_stats)