1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson * Copyright(c) 2010-2017 Intel Corporation
3a9de470cSBruce Richardson */
4a9de470cSBruce Richardson
53c60274cSJie Zhou #include "test.h"
63c60274cSJie Zhou
7a9de470cSBruce Richardson #include <string.h>
8a9de470cSBruce Richardson
93c60274cSJie Zhou #ifdef RTE_EXEC_ENV_WINDOWS
103c60274cSJie Zhou static int
test_event_ring(void)113c60274cSJie Zhou test_event_ring(void)
123c60274cSJie Zhou {
133c60274cSJie Zhou printf("event_ring not supported on Windows, skipping test\n");
143c60274cSJie Zhou return TEST_SKIPPED;
153c60274cSJie Zhou }
16a9de470cSBruce Richardson
173c60274cSJie Zhou #else
183c60274cSJie Zhou
193c60274cSJie Zhou #include <rte_event_ring.h>
20a9de470cSBruce Richardson
21a9de470cSBruce Richardson /*
22a9de470cSBruce Richardson * Event Ring
23a9de470cSBruce Richardson * ===========
24a9de470cSBruce Richardson *
25a9de470cSBruce Richardson * Test some basic ops for the event rings.
26a9de470cSBruce Richardson * Does not fully test everything, since most code is reused from rte_ring
27a9de470cSBruce Richardson * library and tested as part of the normal ring autotests.
28a9de470cSBruce Richardson */
29a9de470cSBruce Richardson
30a9de470cSBruce Richardson #define RING_SIZE 4096
31a9de470cSBruce Richardson #define MAX_BULK 32
32a9de470cSBruce Richardson
33a9de470cSBruce Richardson static struct rte_event_ring *r;
34a9de470cSBruce Richardson
35a9de470cSBruce Richardson /*
36a9de470cSBruce Richardson * ensure failure to create ring with a bad ring size
37a9de470cSBruce Richardson */
38a9de470cSBruce Richardson static int
test_event_ring_creation_with_wrong_size(void)39a9de470cSBruce Richardson test_event_ring_creation_with_wrong_size(void)
40a9de470cSBruce Richardson {
41a9de470cSBruce Richardson struct rte_event_ring *rp = NULL;
42a9de470cSBruce Richardson
43a9de470cSBruce Richardson /* Test if ring size is not power of 2 */
44a9de470cSBruce Richardson rp = rte_event_ring_create("test_bad_ring_size", RING_SIZE + 1,
45a9de470cSBruce Richardson SOCKET_ID_ANY, 0);
46a9de470cSBruce Richardson if (rp != NULL)
47a9de470cSBruce Richardson return -1;
48a9de470cSBruce Richardson
49a9de470cSBruce Richardson /* Test if ring size is exceeding the limit */
50a9de470cSBruce Richardson rp = rte_event_ring_create("test_bad_ring_size", (RTE_RING_SZ_MASK + 1),
51a9de470cSBruce Richardson SOCKET_ID_ANY, 0);
52a9de470cSBruce Richardson if (rp != NULL)
53a9de470cSBruce Richardson return -1;
54a9de470cSBruce Richardson return 0;
55a9de470cSBruce Richardson }
56a9de470cSBruce Richardson
57a9de470cSBruce Richardson /*
58a9de470cSBruce Richardson * Test to check if a non-power-of-2 count causes the create
59a9de470cSBruce Richardson * function to fail correctly
60a9de470cSBruce Richardson */
61a9de470cSBruce Richardson static int
test_create_count_odd(void)62a9de470cSBruce Richardson test_create_count_odd(void)
63a9de470cSBruce Richardson {
64a9de470cSBruce Richardson struct rte_event_ring *r = rte_event_ring_create("test_event_ring_count",
65a9de470cSBruce Richardson 4097, SOCKET_ID_ANY, 0);
66a9de470cSBruce Richardson if (r != NULL)
67a9de470cSBruce Richardson return -1;
68a9de470cSBruce Richardson return 0;
69a9de470cSBruce Richardson }
70a9de470cSBruce Richardson
71a9de470cSBruce Richardson static int
test_lookup_null(void)72a9de470cSBruce Richardson test_lookup_null(void)
73a9de470cSBruce Richardson {
74a9de470cSBruce Richardson struct rte_event_ring *rlp = rte_event_ring_lookup("ring_not_found");
75a9de470cSBruce Richardson if (rlp == NULL && rte_errno != ENOENT) {
76a9de470cSBruce Richardson printf("test failed to return error on null pointer\n");
77a9de470cSBruce Richardson return -1;
78a9de470cSBruce Richardson }
79a9de470cSBruce Richardson return 0;
80a9de470cSBruce Richardson }
81a9de470cSBruce Richardson
82a9de470cSBruce Richardson static int
test_basic_event_enqueue_dequeue(void)83a9de470cSBruce Richardson test_basic_event_enqueue_dequeue(void)
84a9de470cSBruce Richardson {
85a9de470cSBruce Richardson struct rte_event_ring *sr = NULL;
86a9de470cSBruce Richardson struct rte_event evs[16];
87a9de470cSBruce Richardson uint16_t ret, free_count, used_count;
88a9de470cSBruce Richardson
89a9de470cSBruce Richardson memset(evs, 0, sizeof(evs));
90a9de470cSBruce Richardson sr = rte_event_ring_create("spsc_ring", 32, rte_socket_id(),
91a9de470cSBruce Richardson RING_F_SP_ENQ | RING_F_SC_DEQ);
92a9de470cSBruce Richardson if (sr == NULL) {
93a9de470cSBruce Richardson printf("Failed to create sp/sc ring\n");
94a9de470cSBruce Richardson return -1;
95a9de470cSBruce Richardson }
96a9de470cSBruce Richardson if (rte_event_ring_get_capacity(sr) != 31) {
97a9de470cSBruce Richardson printf("Error, invalid capacity\n");
98a9de470cSBruce Richardson goto error;
99a9de470cSBruce Richardson }
100a9de470cSBruce Richardson
101a9de470cSBruce Richardson /* test sp/sc ring */
102a9de470cSBruce Richardson if (rte_event_ring_count(sr) != 0) {
103a9de470cSBruce Richardson printf("Error, ring not empty as expected\n");
104a9de470cSBruce Richardson goto error;
105a9de470cSBruce Richardson }
106a9de470cSBruce Richardson if (rte_event_ring_free_count(sr) != rte_event_ring_get_capacity(sr)) {
107a9de470cSBruce Richardson printf("Error, ring free count not as expected\n");
108a9de470cSBruce Richardson goto error;
109a9de470cSBruce Richardson }
110a9de470cSBruce Richardson
111a9de470cSBruce Richardson ret = rte_event_ring_enqueue_burst(sr, evs, RTE_DIM(evs), &free_count);
112a9de470cSBruce Richardson if (ret != RTE_DIM(evs) ||
113a9de470cSBruce Richardson free_count != rte_event_ring_get_capacity(sr) - ret) {
114a9de470cSBruce Richardson printf("Error, status after enqueue is unexpected\n");
115a9de470cSBruce Richardson goto error;
116a9de470cSBruce Richardson }
117a9de470cSBruce Richardson
118a9de470cSBruce Richardson ret = rte_event_ring_enqueue_burst(sr, evs, RTE_DIM(evs), &free_count);
119a9de470cSBruce Richardson if (ret != RTE_DIM(evs) - 1 ||
120a9de470cSBruce Richardson free_count != 0) {
121a9de470cSBruce Richardson printf("Error, status after enqueue is unexpected\n");
122a9de470cSBruce Richardson goto error;
123a9de470cSBruce Richardson }
124a9de470cSBruce Richardson
125a9de470cSBruce Richardson ret = rte_event_ring_dequeue_burst(sr, evs, RTE_DIM(evs), &used_count);
126a9de470cSBruce Richardson if (ret != RTE_DIM(evs) ||
127a9de470cSBruce Richardson used_count != rte_event_ring_get_capacity(sr) - ret) {
128a9de470cSBruce Richardson printf("Error, status after enqueue is unexpected\n");
129a9de470cSBruce Richardson goto error;
130a9de470cSBruce Richardson }
131a9de470cSBruce Richardson ret = rte_event_ring_dequeue_burst(sr, evs, RTE_DIM(evs), &used_count);
132a9de470cSBruce Richardson if (ret != RTE_DIM(evs) - 1 ||
133a9de470cSBruce Richardson used_count != 0) {
134a9de470cSBruce Richardson printf("Error, status after enqueue is unexpected\n");
135a9de470cSBruce Richardson goto error;
136a9de470cSBruce Richardson }
137a9de470cSBruce Richardson
138a9de470cSBruce Richardson rte_event_ring_free(sr);
139a9de470cSBruce Richardson return 0;
140a9de470cSBruce Richardson error:
141a9de470cSBruce Richardson rte_event_ring_free(sr);
142a9de470cSBruce Richardson return -1;
143a9de470cSBruce Richardson }
144a9de470cSBruce Richardson
145a9de470cSBruce Richardson static int
test_event_ring_with_exact_size(void)146a9de470cSBruce Richardson test_event_ring_with_exact_size(void)
147a9de470cSBruce Richardson {
148a9de470cSBruce Richardson struct rte_event_ring *std_ring, *exact_sz_ring;
149a9de470cSBruce Richardson struct rte_event ev = { .mbuf = NULL };
150a9de470cSBruce Richardson struct rte_event ev_array[16];
151a9de470cSBruce Richardson static const unsigned int ring_sz = RTE_DIM(ev_array);
152a9de470cSBruce Richardson unsigned int i;
153a9de470cSBruce Richardson
154a9de470cSBruce Richardson std_ring = rte_event_ring_create("std", ring_sz, rte_socket_id(),
155a9de470cSBruce Richardson RING_F_SP_ENQ | RING_F_SC_DEQ);
156a9de470cSBruce Richardson if (std_ring == NULL) {
157a9de470cSBruce Richardson printf("%s: error, can't create std ring\n", __func__);
158a9de470cSBruce Richardson return -1;
159a9de470cSBruce Richardson }
160a9de470cSBruce Richardson exact_sz_ring = rte_event_ring_create("exact sz",
161a9de470cSBruce Richardson ring_sz, rte_socket_id(),
162a9de470cSBruce Richardson RING_F_SP_ENQ | RING_F_SC_DEQ | RING_F_EXACT_SZ);
163a9de470cSBruce Richardson if (exact_sz_ring == NULL) {
164a9de470cSBruce Richardson printf("%s: error, can't create exact size ring\n", __func__);
165a9de470cSBruce Richardson return -1;
166a9de470cSBruce Richardson }
167a9de470cSBruce Richardson
168a9de470cSBruce Richardson /*
169a9de470cSBruce Richardson * Check that the exact size ring is bigger than the standard ring
170a9de470cSBruce Richardson */
171a9de470cSBruce Richardson if (rte_event_ring_get_size(std_ring) >=
172a9de470cSBruce Richardson rte_event_ring_get_size(exact_sz_ring)) {
173a9de470cSBruce Richardson printf("%s: error, std ring (size: %u) is not smaller than exact size one (size %u)\n",
174a9de470cSBruce Richardson __func__,
175a9de470cSBruce Richardson rte_event_ring_get_size(std_ring),
176a9de470cSBruce Richardson rte_event_ring_get_size(exact_sz_ring));
177a9de470cSBruce Richardson return -1;
178a9de470cSBruce Richardson }
179a9de470cSBruce Richardson /*
180a9de470cSBruce Richardson * check that the exact_sz_ring can hold one more element than the
181a9de470cSBruce Richardson * standard ring. (16 vs 15 elements)
182a9de470cSBruce Richardson */
183a9de470cSBruce Richardson for (i = 0; i < ring_sz - 1; i++) {
184a9de470cSBruce Richardson rte_event_ring_enqueue_burst(std_ring, &ev, 1, NULL);
185a9de470cSBruce Richardson rte_event_ring_enqueue_burst(exact_sz_ring, &ev, 1, NULL);
186a9de470cSBruce Richardson }
187a9de470cSBruce Richardson if (rte_event_ring_enqueue_burst(std_ring, &ev, 1, NULL) != 0) {
188a9de470cSBruce Richardson printf("%s: error, unexpected successful enqueue\n", __func__);
189a9de470cSBruce Richardson return -1;
190a9de470cSBruce Richardson }
191a9de470cSBruce Richardson if (rte_event_ring_enqueue_burst(exact_sz_ring, &ev, 1, NULL) != 1) {
192a9de470cSBruce Richardson printf("%s: error, enqueue failed\n", __func__);
193a9de470cSBruce Richardson return -1;
194a9de470cSBruce Richardson }
195a9de470cSBruce Richardson
196a9de470cSBruce Richardson /* check that dequeue returns the expected number of elements */
197a9de470cSBruce Richardson if (rte_event_ring_dequeue_burst(exact_sz_ring, ev_array,
198a9de470cSBruce Richardson RTE_DIM(ev_array), NULL) != ring_sz) {
199a9de470cSBruce Richardson printf("%s: error, failed to dequeue expected nb of elements\n",
200a9de470cSBruce Richardson __func__);
201a9de470cSBruce Richardson return -1;
202a9de470cSBruce Richardson }
203a9de470cSBruce Richardson
204a9de470cSBruce Richardson /* check that the capacity function returns expected value */
205a9de470cSBruce Richardson if (rte_event_ring_get_capacity(exact_sz_ring) != ring_sz) {
206a9de470cSBruce Richardson printf("%s: error, incorrect ring capacity reported\n",
207a9de470cSBruce Richardson __func__);
208a9de470cSBruce Richardson return -1;
209a9de470cSBruce Richardson }
210a9de470cSBruce Richardson
211a9de470cSBruce Richardson rte_event_ring_free(std_ring);
212a9de470cSBruce Richardson rte_event_ring_free(exact_sz_ring);
213a9de470cSBruce Richardson return 0;
214a9de470cSBruce Richardson }
215a9de470cSBruce Richardson
216a9de470cSBruce Richardson static int
test_event_ring(void)217a9de470cSBruce Richardson test_event_ring(void)
218a9de470cSBruce Richardson {
219a9de470cSBruce Richardson if (r == NULL)
220a9de470cSBruce Richardson r = rte_event_ring_create("ev_test", RING_SIZE,
221a9de470cSBruce Richardson SOCKET_ID_ANY, 0);
222a9de470cSBruce Richardson if (r == NULL)
223a9de470cSBruce Richardson return -1;
224a9de470cSBruce Richardson
225a9de470cSBruce Richardson /* retrieve the ring from its name */
226a9de470cSBruce Richardson if (rte_event_ring_lookup("ev_test") != r) {
227a9de470cSBruce Richardson printf("Cannot lookup ring from its name\n");
228a9de470cSBruce Richardson return -1;
229a9de470cSBruce Richardson }
230a9de470cSBruce Richardson
231a9de470cSBruce Richardson /* basic operations */
232a9de470cSBruce Richardson if (test_create_count_odd() < 0) {
233a9de470cSBruce Richardson printf("Test failed to detect odd count\n");
234a9de470cSBruce Richardson return -1;
235a9de470cSBruce Richardson }
236a9de470cSBruce Richardson printf("Test detected odd count\n");
237a9de470cSBruce Richardson
238a9de470cSBruce Richardson if (test_lookup_null() < 0) {
239a9de470cSBruce Richardson printf("Test failed to detect NULL ring lookup\n");
240a9de470cSBruce Richardson return -1;
241a9de470cSBruce Richardson }
242a9de470cSBruce Richardson printf("Test detected NULL ring lookup\n");
243a9de470cSBruce Richardson
244a9de470cSBruce Richardson /* test of creating ring with wrong size */
245a9de470cSBruce Richardson if (test_event_ring_creation_with_wrong_size() < 0)
246a9de470cSBruce Richardson return -1;
247a9de470cSBruce Richardson
248a9de470cSBruce Richardson if (test_basic_event_enqueue_dequeue() < 0)
249a9de470cSBruce Richardson return -1;
250a9de470cSBruce Richardson
251a9de470cSBruce Richardson if (test_event_ring_with_exact_size() < 0)
252a9de470cSBruce Richardson return -1;
253a9de470cSBruce Richardson
254a9de470cSBruce Richardson return 0;
255a9de470cSBruce Richardson }
256a9de470cSBruce Richardson
2573c60274cSJie Zhou #endif /* !RTE_EXEC_ENV_WINDOWS */
2583c60274cSJie Zhou
259*e0a8442cSBruce Richardson REGISTER_FAST_TEST(event_ring_autotest, true, true, test_event_ring);
260