doc: announce behaviour change to i40e RSS
[dpdk.git] / test / test / test_event_ring.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <string.h>
35
36 #include <rte_event_ring.h>
37
38 #include "test.h"
39
40 /*
41  * Event Ring
42  * ===========
43  *
44  * Test some basic ops for the event rings.
45  * Does not fully test everything, since most code is reused from rte_ring
46  * library and tested as part of the normal ring autotests.
47  */
48
49 #define RING_SIZE 4096
50 #define MAX_BULK 32
51
52 static struct rte_event_ring *r;
53
54 /*
55  * ensure failure to create ring with a bad ring size
56  */
57 static int
58 test_event_ring_creation_with_wrong_size(void)
59 {
60         struct rte_event_ring *rp = NULL;
61
62         /* Test if ring size is not power of 2 */
63         rp = rte_event_ring_create("test_bad_ring_size", RING_SIZE + 1,
64                         SOCKET_ID_ANY, 0);
65         if (rp != NULL)
66                 return -1;
67
68         /* Test if ring size is exceeding the limit */
69         rp = rte_event_ring_create("test_bad_ring_size", (RTE_RING_SZ_MASK + 1),
70                         SOCKET_ID_ANY, 0);
71         if (rp != NULL)
72                 return -1;
73         return 0;
74 }
75
76 /*
77  * Test to check if a non-power-of-2 count causes the create
78  * function to fail correctly
79  */
80 static int
81 test_create_count_odd(void)
82 {
83         struct rte_event_ring *r = rte_event_ring_create("test_event_ring_count",
84                         4097, SOCKET_ID_ANY, 0);
85         if (r != NULL)
86                 return -1;
87         return 0;
88 }
89
90 static int
91 test_lookup_null(void)
92 {
93         struct rte_event_ring *rlp = rte_event_ring_lookup("ring_not_found");
94         if (rlp == NULL && rte_errno != ENOENT) {
95                 printf("test failed to return error on null pointer\n");
96                 return -1;
97         }
98         return 0;
99 }
100
101 static int
102 test_basic_event_enqueue_dequeue(void)
103 {
104         struct rte_event_ring *sr = NULL;
105         struct rte_event evs[16];
106         uint16_t ret, free_count, used_count;
107
108         memset(evs, 0, sizeof(evs));
109         sr = rte_event_ring_create("spsc_ring", 32, rte_socket_id(),
110                         RING_F_SP_ENQ | RING_F_SC_DEQ);
111         if (sr == NULL) {
112                 printf("Failed to create sp/sc ring\n");
113                 return -1;
114         }
115         if (rte_event_ring_get_capacity(sr) != 31) {
116                 printf("Error, invalid capacity\n");
117                 goto error;
118         }
119
120         /* test sp/sc ring */
121         if (rte_event_ring_count(sr) != 0) {
122                 printf("Error, ring not empty as expected\n");
123                 goto error;
124         }
125         if (rte_event_ring_free_count(sr) != rte_event_ring_get_capacity(sr)) {
126                 printf("Error, ring free count not as expected\n");
127                 goto error;
128         }
129
130         ret = rte_event_ring_enqueue_burst(sr, evs, RTE_DIM(evs), &free_count);
131         if (ret != RTE_DIM(evs) ||
132                         free_count != rte_event_ring_get_capacity(sr) - ret) {
133                 printf("Error, status after enqueue is unexpected\n");
134                 goto error;
135         }
136
137         ret = rte_event_ring_enqueue_burst(sr, evs, RTE_DIM(evs), &free_count);
138         if (ret != RTE_DIM(evs) - 1 ||
139                         free_count != 0) {
140                 printf("Error, status after enqueue is unexpected\n");
141                 goto error;
142         }
143
144         ret = rte_event_ring_dequeue_burst(sr, evs, RTE_DIM(evs), &used_count);
145         if (ret != RTE_DIM(evs) ||
146                         used_count != rte_event_ring_get_capacity(sr) - ret) {
147                 printf("Error, status after enqueue is unexpected\n");
148                 goto error;
149         }
150         ret = rte_event_ring_dequeue_burst(sr, evs, RTE_DIM(evs), &used_count);
151         if (ret != RTE_DIM(evs) - 1 ||
152                         used_count != 0) {
153                 printf("Error, status after enqueue is unexpected\n");
154                 goto error;
155         }
156
157         rte_event_ring_free(sr);
158         return 0;
159 error:
160         rte_event_ring_free(sr);
161         return -1;
162 }
163
164 static int
165 test_event_ring_with_exact_size(void)
166 {
167         struct rte_event_ring *std_ring, *exact_sz_ring;
168         struct rte_event ev = { .mbuf = NULL };
169         struct rte_event ev_array[16];
170         static const unsigned int ring_sz = RTE_DIM(ev_array);
171         unsigned int i;
172
173         std_ring = rte_event_ring_create("std", ring_sz, rte_socket_id(),
174                         RING_F_SP_ENQ | RING_F_SC_DEQ);
175         if (std_ring == NULL) {
176                 printf("%s: error, can't create std ring\n", __func__);
177                 return -1;
178         }
179         exact_sz_ring = rte_event_ring_create("exact sz",
180                         ring_sz, rte_socket_id(),
181                         RING_F_SP_ENQ | RING_F_SC_DEQ | RING_F_EXACT_SZ);
182         if (exact_sz_ring == NULL) {
183                 printf("%s: error, can't create exact size ring\n", __func__);
184                 return -1;
185         }
186
187         /*
188          * Check that the exact size ring is bigger than the standard ring
189          */
190         if (rte_event_ring_get_size(std_ring) >=
191                         rte_event_ring_get_size(exact_sz_ring)) {
192                 printf("%s: error, std ring (size: %u) is not smaller than exact size one (size %u)\n",
193                                 __func__,
194                                 rte_event_ring_get_size(std_ring),
195                                 rte_event_ring_get_size(exact_sz_ring));
196                 return -1;
197         }
198         /*
199          * check that the exact_sz_ring can hold one more element than the
200          * standard ring. (16 vs 15 elements)
201          */
202         for (i = 0; i < ring_sz - 1; i++) {
203                 rte_event_ring_enqueue_burst(std_ring, &ev, 1, NULL);
204                 rte_event_ring_enqueue_burst(exact_sz_ring, &ev, 1, NULL);
205         }
206         if (rte_event_ring_enqueue_burst(std_ring, &ev, 1, NULL) != 0) {
207                 printf("%s: error, unexpected successful enqueue\n", __func__);
208                 return -1;
209         }
210         if (rte_event_ring_enqueue_burst(exact_sz_ring, &ev, 1, NULL) != 1) {
211                 printf("%s: error, enqueue failed\n", __func__);
212                 return -1;
213         }
214
215         /* check that dequeue returns the expected number of elements */
216         if (rte_event_ring_dequeue_burst(exact_sz_ring, ev_array,
217                         RTE_DIM(ev_array), NULL) != ring_sz) {
218                 printf("%s: error, failed to dequeue expected nb of elements\n",
219                                 __func__);
220                 return -1;
221         }
222
223         /* check that the capacity function returns expected value */
224         if (rte_event_ring_get_capacity(exact_sz_ring) != ring_sz) {
225                 printf("%s: error, incorrect ring capacity reported\n",
226                                 __func__);
227                 return -1;
228         }
229
230         rte_event_ring_free(std_ring);
231         rte_event_ring_free(exact_sz_ring);
232         return 0;
233 }
234
235 static int
236 test_event_ring(void)
237 {
238         if (r == NULL)
239                 r = rte_event_ring_create("ev_test", RING_SIZE,
240                                 SOCKET_ID_ANY, 0);
241         if (r == NULL)
242                 return -1;
243
244         /* retrieve the ring from its name */
245         if (rte_event_ring_lookup("ev_test") != r) {
246                 printf("Cannot lookup ring from its name\n");
247                 return -1;
248         }
249
250         /* basic operations */
251         if (test_create_count_odd() < 0) {
252                 printf("Test failed to detect odd count\n");
253                 return -1;
254         }
255         printf("Test detected odd count\n");
256
257         if (test_lookup_null() < 0) {
258                 printf("Test failed to detect NULL ring lookup\n");
259                 return -1;
260         }
261         printf("Test detected NULL ring lookup\n");
262
263         /* test of creating ring with wrong size */
264         if (test_event_ring_creation_with_wrong_size() < 0)
265                 return -1;
266
267         if (test_basic_event_enqueue_dequeue() < 0)
268                 return -1;
269
270         if (test_event_ring_with_exact_size() < 0)
271                 return -1;
272
273         return 0;
274 }
275
276 REGISTER_TEST_COMMAND(event_ring_autotest, test_event_ring);