File Index
Files and directories
Sign in
FILE

test_xsk.h

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/prog_tests/test_xsk.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2#ifndef TEST_XSK_H_
  3#define TEST_XSK_H_
  4
  5#include <linux/ethtool.h>
  6#include <linux/if_xdp.h>
  7
  8#include "../kselftest.h"
  9#include "xsk.h"
 10
 11#ifndef SO_PREFER_BUSY_POLL
 12#define SO_PREFER_BUSY_POLL 69
 13#endif
 14
 15#ifndef SO_BUSY_POLL_BUDGET
 16#define SO_BUSY_POLL_BUDGET 70
 17#endif
 18
 19#define TEST_PASS 0
 20#define TEST_FAILURE -1
 21#define TEST_CONTINUE 1
 22#define TEST_SKIP 2
 23
 24#define DEFAULT_PKT_CNT			(4 * 1024)
 25#define DEFAULT_UMEM_BUFFERS		(DEFAULT_PKT_CNT / 4)
 26#define HUGEPAGE_SIZE			(2 * 1024 * 1024)
 27#define MIN_PKT_SIZE			64
 28#define MAX_ETH_PKT_SIZE		1518
 29#define MAX_INTERFACE_NAME_CHARS	16
 30#define MAX_TEST_NAME_SIZE		48
 31#define SOCK_RECONF_CTR			10
 32#define USLEEP_MAX			10000
 33
 34extern bool opt_verbose;
 35#define print_verbose(x...) do { if (opt_verbose) ksft_print_msg(x); } while (0)
 36
 37
 38static inline u32 ceil_u32(u32 a, u32 b)
 39{
 40	return (a + b - 1) / b;
 41}
 42
 43static inline u64 ceil_u64(u64 a, u64 b)
 44{
 45	return (a + b - 1) / b;
 46}
 47
 48/* Simple test */
 49enum test_mode {
 50	TEST_MODE_SKB,
 51	TEST_MODE_DRV,
 52	TEST_MODE_ZC,
 53	TEST_MODE_ALL
 54};
 55
 56struct ifobject;
 57struct test_spec;
 58typedef int (*validation_func_t)(struct ifobject *ifobj);
 59typedef void *(*thread_func_t)(void *arg);
 60typedef int (*test_func_t)(struct test_spec *test);
 61
 62struct xsk_socket_info {
 63	struct xsk_ring_cons rx;
 64	struct xsk_ring_prod tx;
 65	struct xsk_umem_info *umem;
 66	struct xsk_socket *xsk;
 67	struct pkt_stream *pkt_stream;
 68	u32 outstanding_tx;
 69	u32 rxqsize;
 70	u32 batch_size;
 71	u8 dst_mac[ETH_ALEN];
 72	u8 src_mac[ETH_ALEN];
 73	bool check_consumer;
 74};
 75
 76int kick_rx(struct xsk_socket_info *xsk);
 77int kick_tx(struct xsk_socket_info *xsk);
 78
 79struct xsk_umem_info {
 80	struct xsk_ring_prod fq;
 81	struct xsk_ring_cons cq;
 82	struct xsk_umem *umem;
 83	u64 next_buffer;
 84	u32 num_frames;
 85	u32 frame_headroom;
 86	void *buffer;
 87	u32 frame_size;
 88	u32 base_addr;
 89	u32 fill_size;
 90	u32 comp_size;
 91	bool unaligned_mode;
 92};
 93
 94struct set_hw_ring {
 95	u32 default_tx;
 96	u32 default_rx;
 97};
 98
 99int hw_ring_size_reset(struct ifobject *ifobj);
100
101struct ifobject {
102	char ifname[MAX_INTERFACE_NAME_CHARS];
103	struct xsk_socket_info *xsk;
104	struct xsk_socket_info *xsk_arr;
105	struct xsk_umem_info *umem;
106	thread_func_t func_ptr;
107	validation_func_t validation_func;
108	struct xsk_xdp_progs *xdp_progs;
109	struct bpf_map *xskmap;
110	struct bpf_program *xdp_prog;
111	struct ethtool_ringparam ring;
112	struct set_hw_ring set_ring;
113	enum test_mode mode;
114	int ifindex;
115	int mtu;
116	u32 bind_flags;
117	u32 xdp_zc_max_segs;
118	bool tx_on;
119	bool rx_on;
120	bool use_poll;
121	bool busy_poll;
122	bool use_fill_ring;
123	bool release_rx;
124	bool shared_umem;
125	bool use_metadata;
126	bool unaligned_supp;
127	bool multi_buff_supp;
128	bool multi_buff_zc_supp;
129	bool hw_ring_size_supp;
130};
131struct ifobject *ifobject_create(void);
132void ifobject_delete(struct ifobject *ifobj);
133int init_iface(struct ifobject *ifobj, thread_func_t func_ptr);
134
135int xsk_configure_umem(struct ifobject *ifobj, struct xsk_umem_info *umem, void *buffer, u64 size);
136int xsk_configure_socket(struct xsk_socket_info *xsk, struct xsk_umem_info *umem,
137			 struct ifobject *ifobject, bool shared);
138
139
140struct pkt {
141	int offset;
142	u32 len;
143	u32 pkt_nb;
144	bool valid;
145	u16 options;
146};
147
148struct pkt_stream {
149	u32 nb_pkts;
150	u32 current_pkt_nb;
151	struct pkt *pkts;
152	u32 max_pkt_len;
153	u32 nb_rx_pkts;
154	u32 nb_valid_entries;
155	bool verbatim;
156};
157
158static inline bool pkt_continues(u32 options)
159{
160	return options & XDP_PKT_CONTD;
161}
162
163struct pkt_stream *pkt_stream_generate(u32 nb_pkts, u32 pkt_len);
164void pkt_stream_delete(struct pkt_stream *pkt_stream);
165void pkt_stream_reset(struct pkt_stream *pkt_stream);
166void pkt_stream_restore_default(struct test_spec *test);
167
168struct test_spec {
169	struct ifobject *ifobj_tx;
170	struct ifobject *ifobj_rx;
171	struct pkt_stream *tx_pkt_stream_default;
172	struct pkt_stream *rx_pkt_stream_default;
173	struct bpf_program *xdp_prog_rx;
174	struct bpf_program *xdp_prog_tx;
175	struct bpf_map *xskmap_rx;
176	struct bpf_map *xskmap_tx;
177	test_func_t test_func;
178	int mtu;
179	u16 total_steps;
180	u16 current_step;
181	u16 nb_sockets;
182	bool fail;
183	bool set_ring;
184	bool adjust_tail;
185	bool adjust_tail_support;
186	enum test_mode mode;
187	char name[MAX_TEST_NAME_SIZE];
188};
189
190#define busy_poll_string(test) (test)->ifobj_tx->busy_poll ? "BUSY-POLL " : ""
191static inline char *mode_string(struct test_spec *test)
192{
193	switch (test->mode) {
194	case TEST_MODE_SKB:
195		return "SKB";
196	case TEST_MODE_DRV:
197		return "DRV";
198	case TEST_MODE_ZC:
199		return "ZC";
200	default:
201		return "BOGUS";
202	}
203}
204
205void test_init(struct test_spec *test, struct ifobject *ifobj_tx,
206	       struct ifobject *ifobj_rx, enum test_mode mode,
207	       const struct test_spec *test_to_run);
208
209int testapp_adjust_tail_grow(struct test_spec *test);
210int testapp_adjust_tail_grow_mb(struct test_spec *test);
211int testapp_adjust_tail_shrink(struct test_spec *test);
212int testapp_adjust_tail_shrink_mb(struct test_spec *test);
213int testapp_aligned_inv_desc(struct test_spec *test);
214int testapp_aligned_inv_desc_2k_frame(struct test_spec *test);
215int testapp_aligned_inv_desc_mb(struct test_spec *test);
216int testapp_bidirectional(struct test_spec *test);
217int testapp_headroom(struct test_spec *test);
218int testapp_hw_sw_max_ring_size(struct test_spec *test);
219int testapp_hw_sw_min_ring_size(struct test_spec *test);
220int testapp_poll_rx(struct test_spec *test);
221int testapp_poll_rxq_tmout(struct test_spec *test);
222int testapp_poll_tx(struct test_spec *test);
223int testapp_poll_txq_tmout(struct test_spec *test);
224int testapp_send_receive(struct test_spec *test);
225int testapp_send_receive_2k_frame(struct test_spec *test);
226int testapp_send_receive_mb(struct test_spec *test);
227int testapp_send_receive_unaligned(struct test_spec *test);
228int testapp_send_receive_unaligned_mb(struct test_spec *test);
229int testapp_single_pkt(struct test_spec *test);
230int testapp_stats_fill_empty(struct test_spec *test);
231int testapp_stats_rx_dropped(struct test_spec *test);
232int testapp_stats_tx_invalid_descs(struct test_spec *test);
233int testapp_stats_rx_full(struct test_spec *test);
234int testapp_teardown(struct test_spec *test);
235int testapp_too_many_frags(struct test_spec *test);
236int testapp_tx_queue_consumer(struct test_spec *test);
237int testapp_unaligned_inv_desc(struct test_spec *test);
238int testapp_unaligned_inv_desc_4001_frame(struct test_spec *test);
239int testapp_unaligned_inv_desc_mb(struct test_spec *test);
240int testapp_xdp_drop(struct test_spec *test);
241int testapp_xdp_metadata(struct test_spec *test);
242int testapp_xdp_metadata_mb(struct test_spec *test);
243int testapp_xdp_prog_cleanup(struct test_spec *test);
244int testapp_xdp_shared_umem(struct test_spec *test);
245
246void *worker_testapp_validate_rx(void *arg);
247void *worker_testapp_validate_tx(void *arg);
248
249static const struct test_spec tests[] = {
250	{.name = "SEND_RECEIVE", .test_func = testapp_send_receive},
251	{.name = "SEND_RECEIVE_2K_FRAME", .test_func = testapp_send_receive_2k_frame},
252	{.name = "SEND_RECEIVE_SINGLE_PKT", .test_func = testapp_single_pkt},
253	{.name = "POLL_RX", .test_func = testapp_poll_rx},
254	{.name = "POLL_TX", .test_func = testapp_poll_tx},
255	{.name = "POLL_RXQ_FULL", .test_func = testapp_poll_rxq_tmout},
256	{.name = "POLL_TXQ_FULL", .test_func = testapp_poll_txq_tmout},
257	{.name = "ALIGNED_INV_DESC", .test_func = testapp_aligned_inv_desc},
258	{.name = "ALIGNED_INV_DESC_2K_FRAME_SIZE", .test_func = testapp_aligned_inv_desc_2k_frame},
259	{.name = "UMEM_HEADROOM", .test_func = testapp_headroom},
260	{.name = "BIDIRECTIONAL", .test_func = testapp_bidirectional},
261	{.name = "STAT_RX_DROPPED", .test_func = testapp_stats_rx_dropped},
262	{.name = "STAT_TX_INVALID", .test_func = testapp_stats_tx_invalid_descs},
263	{.name = "STAT_RX_FULL", .test_func = testapp_stats_rx_full},
264	{.name = "STAT_FILL_EMPTY", .test_func = testapp_stats_fill_empty},
265	{.name = "XDP_PROG_CLEANUP", .test_func = testapp_xdp_prog_cleanup},
266	{.name = "XDP_DROP_HALF", .test_func = testapp_xdp_drop},
267	{.name = "XDP_SHARED_UMEM", .test_func = testapp_xdp_shared_umem},
268	{.name = "XDP_METADATA_COPY", .test_func = testapp_xdp_metadata},
269	{.name = "XDP_METADATA_COPY_MULTI_BUFF", .test_func = testapp_xdp_metadata_mb},
270	{.name = "ALIGNED_INV_DESC_MULTI_BUFF", .test_func = testapp_aligned_inv_desc_mb},
271	{.name = "TOO_MANY_FRAGS", .test_func = testapp_too_many_frags},
272	{.name = "XDP_ADJUST_TAIL_SHRINK", .test_func = testapp_adjust_tail_shrink},
273	{.name = "TX_QUEUE_CONSUMER", .test_func = testapp_tx_queue_consumer},
274	};
275
276static const struct test_spec ci_skip_tests[] = {
277	/* Flaky tests */
278	{.name = "XDP_ADJUST_TAIL_SHRINK_MULTI_BUFF", .test_func = testapp_adjust_tail_shrink_mb},
279	{.name = "XDP_ADJUST_TAIL_GROW", .test_func = testapp_adjust_tail_grow},
280	{.name = "XDP_ADJUST_TAIL_GROW_MULTI_BUFF", .test_func = testapp_adjust_tail_grow_mb},
281	{.name = "SEND_RECEIVE_9K_PACKETS", .test_func = testapp_send_receive_mb},
282	/* Tests with huge page dependency */
283	{.name = "SEND_RECEIVE_UNALIGNED", .test_func = testapp_send_receive_unaligned},
284	{.name = "UNALIGNED_INV_DESC", .test_func = testapp_unaligned_inv_desc},
285	{.name = "UNALIGNED_INV_DESC_4001_FRAME_SIZE",
286	 .test_func = testapp_unaligned_inv_desc_4001_frame},
287	{.name = "SEND_RECEIVE_UNALIGNED_9K_PACKETS",
288	 .test_func = testapp_send_receive_unaligned_mb},
289	{.name = "UNALIGNED_INV_DESC_MULTI_BUFF", .test_func = testapp_unaligned_inv_desc_mb},
290	/* Test with HW ring size dependency */
291	{.name = "HW_SW_MIN_RING_SIZE", .test_func = testapp_hw_sw_min_ring_size},
292	{.name = "HW_SW_MAX_RING_SIZE", .test_func = testapp_hw_sw_max_ring_size},
293	/* Too long test */
294	{.name = "TEARDOWN", .test_func = testapp_teardown},
295};
296
297
298#endif				/* TEST_XSK_H_ */
~/ Read-only file preview.