Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2017 Intel Corporation
3 : : */
4 : :
5 : : #include <rte_common.h>
6 : : #include <rte_hexdump.h>
7 : : #include <rte_mbuf.h>
8 : : #include <rte_malloc.h>
9 : : #include <rte_memcpy.h>
10 : : #include <rte_cycles.h>
11 : :
12 : : #include <rte_service.h>
13 : : #include <rte_service_component.h>
14 : :
15 : : #include "test.h"
16 : :
17 : : /* used as the service core ID */
18 : : static uint32_t slcore_id;
19 : : /* used as timestamp to detect if a service core is running */
20 : : static uint64_t service_tick;
21 : : /* used as a flag to check if a function was run */
22 : : static uint32_t service_remote_launch_flag;
23 : :
24 : : #define SERVICE_DELAY 1
25 : : #define TIMEOUT_MS 1000
26 : :
27 : : #define DUMMY_SERVICE_NAME "dummy_service"
28 : : #define MT_SAFE_SERVICE_NAME "mt_safe_service"
29 : :
30 : : static int
31 : 1 : testsuite_setup(void)
32 : : {
33 : 1 : slcore_id = rte_get_next_lcore(/* start core */ -1,
34 : : /* skip main */ 1,
35 : : /* wrap */ 0);
36 : :
37 : 1 : return TEST_SUCCESS;
38 : : }
39 : :
40 : : static void
41 : 1 : testsuite_teardown(void)
42 : : {
43 : : /* release service cores? */
44 : 1 : }
45 : :
46 : 100 : static int32_t dummy_cb(void *args)
47 : : {
48 : : RTE_SET_USED(args);
49 : 100 : service_tick++;
50 : : rte_delay_ms(SERVICE_DELAY);
51 : 100 : return 0;
52 : : }
53 : :
54 : 0 : static int32_t dummy_mt_unsafe_cb(void *args)
55 : : {
56 : : /* before running test, the initialization has set pass_test to 1.
57 : : * If the CAS in service-cores is working correctly, the code here
58 : : * should never fail to take the lock. If the lock *is* taken, fail the
59 : : * test, because two threads are concurrently in a non-MT safe callback.
60 : : */
61 : : uint32_t *test_params = args;
62 : : uint32_t *lock = &test_params[0];
63 : : uint32_t *pass_test = &test_params[1];
64 : : uint32_t exp = 0;
65 : 0 : int lock_taken = __atomic_compare_exchange_n(lock, &exp, 1, 0,
66 : : __ATOMIC_RELAXED, __ATOMIC_RELAXED);
67 [ # # ]: 0 : if (lock_taken) {
68 : : /* delay with the lock held */
69 : : rte_delay_ms(250);
70 : 0 : __atomic_store_n(lock, 0, __ATOMIC_RELAXED);
71 : : } else {
72 : : /* 2nd thread will fail to take lock, so clear pass flag */
73 : 0 : *pass_test = 0;
74 : : }
75 : :
76 : 0 : return 0;
77 : : }
78 : :
79 : :
80 : 0 : static int32_t dummy_mt_safe_cb(void *args)
81 : : {
82 : : /* Atomic checks to ensure MT safe services allow > 1 thread to
83 : : * concurrently run the callback. The concept is as follows;
84 : : * 1) if lock is available, take the lock then delay
85 : : * 2) if first lock is taken, and a thread arrives in the CB, we know
86 : : * that 2 threads are running the callback at the same time: MT safe
87 : : */
88 : : uint32_t *test_params = args;
89 : : uint32_t *lock = &test_params[0];
90 : : uint32_t *pass_test = &test_params[1];
91 : : uint32_t exp = 0;
92 : 0 : int lock_taken = __atomic_compare_exchange_n(lock, &exp, 1, 0,
93 : : __ATOMIC_RELAXED, __ATOMIC_RELAXED);
94 [ # # ]: 0 : if (lock_taken) {
95 : : /* delay with the lock held */
96 : : rte_delay_ms(250);
97 : 0 : __atomic_store_n(lock, 0, __ATOMIC_RELAXED);
98 : : } else {
99 : : /* 2nd thread will fail to take lock, so set pass flag */
100 : 0 : *pass_test = 1;
101 : : }
102 : :
103 : 0 : return 0;
104 : : }
105 : :
106 : : /* unregister all services */
107 : : static int
108 : 23 : unregister_all(void)
109 : : {
110 : : uint32_t i;
111 : :
112 [ - + ]: 23 : TEST_ASSERT_EQUAL(-EINVAL, rte_service_component_unregister(1000),
113 : : "Unregistered invalid service id");
114 : :
115 : 23 : uint32_t c = rte_service_get_count();
116 [ + + ]: 37 : for (i = 0; i < c; i++) {
117 [ - + ]: 14 : TEST_ASSERT_EQUAL(0, rte_service_component_unregister(i),
118 : : "Error unregistering a valid service");
119 : : }
120 : :
121 : 23 : rte_service_lcore_reset_all();
122 : 23 : rte_eal_mp_wait_lcore();
123 : :
124 : 23 : return TEST_SUCCESS;
125 : : }
126 : :
127 : : /* Wait until service lcore not active, or for TIMEOUT_MS */
128 : : static void
129 : 0 : wait_slcore_inactive(uint32_t slcore_id)
130 : : {
131 : : int i;
132 : :
133 [ # # # # ]: 0 : for (i = 0; rte_service_lcore_may_be_active(slcore_id) == 1 &&
134 : 0 : i < TIMEOUT_MS; i++)
135 : : rte_delay_ms(1);
136 : 0 : }
137 : :
138 : : /* register a single dummy service */
139 : : static int
140 : 12 : dummy_register(void)
141 : : {
142 : : /* make sure there are no remains from previous tests */
143 : 12 : unregister_all();
144 : :
145 : : struct rte_service_spec service;
146 : : memset(&service, 0, sizeof(struct rte_service_spec));
147 : :
148 [ - + ]: 12 : TEST_ASSERT_EQUAL(-EINVAL,
149 : : rte_service_component_register(&service, NULL),
150 : : "Invalid callback");
151 : 12 : service.callback = dummy_cb;
152 : :
153 [ - + ]: 12 : TEST_ASSERT_EQUAL(-EINVAL,
154 : : rte_service_component_register(&service, NULL),
155 : : "Invalid name");
156 : : snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME);
157 : :
158 : : uint32_t id;
159 [ - + ]: 12 : TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id),
160 : : "Failed to register valid service");
161 : :
162 : 12 : rte_service_component_runstate_set(id, 1);
163 : :
164 : 12 : return TEST_SUCCESS;
165 : : }
166 : :
167 : : /* verify get_by_name() service lookup */
168 : : static int
169 : 1 : service_get_by_name(void)
170 : : {
171 : 1 : unregister_all();
172 : :
173 : : uint32_t sid;
174 [ - + ]: 1 : TEST_ASSERT_EQUAL(-ENODEV,
175 : : rte_service_get_by_name(DUMMY_SERVICE_NAME, &sid),
176 : : "get by name with invalid name should return -ENODEV");
177 [ - + ]: 1 : TEST_ASSERT_EQUAL(-EINVAL,
178 : : rte_service_get_by_name(DUMMY_SERVICE_NAME, 0x0),
179 : : "get by name with NULL ptr should return -ENODEV");
180 : :
181 : : /* register service */
182 : : struct rte_service_spec service;
183 : : memset(&service, 0, sizeof(struct rte_service_spec));
184 [ - + ]: 1 : TEST_ASSERT_EQUAL(-EINVAL,
185 : : rte_service_component_register(&service, NULL),
186 : : "Invalid callback");
187 : 1 : service.callback = dummy_cb;
188 [ - + ]: 1 : TEST_ASSERT_EQUAL(-EINVAL,
189 : : rte_service_component_register(&service, NULL),
190 : : "Invalid name");
191 : : snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME);
192 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, NULL),
193 : : "Failed to register valid service");
194 : :
195 : : /* we unregistered all service, now registering 1, should be id 0 */
196 : : uint32_t service_id_as_expected = 0;
197 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_get_by_name(DUMMY_SERVICE_NAME, &sid),
198 : : "Service get_by_name should return 0 on valid inputs");
199 [ - + ]: 1 : TEST_ASSERT_EQUAL(service_id_as_expected, sid,
200 : : "Service get_by_name should equal expected id");
201 : :
202 : 1 : unregister_all();
203 : :
204 : : /* ensure after unregister, get_by_name returns NULL */
205 [ - + ]: 1 : TEST_ASSERT_EQUAL(-ENODEV,
206 : : rte_service_get_by_name(DUMMY_SERVICE_NAME, &sid),
207 : : "get by name should return -ENODEV after unregister");
208 : :
209 : : return TEST_SUCCESS;
210 : : }
211 : :
212 : : /* verify probe of capabilities */
213 : : static int
214 : 1 : service_probe_capability(void)
215 : : {
216 : 1 : unregister_all();
217 : :
218 : : struct rte_service_spec service;
219 : : memset(&service, 0, sizeof(struct rte_service_spec));
220 : 1 : service.callback = dummy_cb;
221 : : snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME);
222 : 1 : service.capabilities |= RTE_SERVICE_CAP_MT_SAFE;
223 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, NULL),
224 : : "Register of MT SAFE service failed");
225 : :
226 : : /* verify flag is enabled */
227 : : const uint32_t sid = 0;
228 : 1 : int32_t mt = rte_service_probe_capability(sid, RTE_SERVICE_CAP_MT_SAFE);
229 [ - + ]: 1 : TEST_ASSERT_EQUAL(1, mt, "MT SAFE capability flag not set.");
230 : :
231 : :
232 : 1 : unregister_all();
233 : :
234 : : memset(&service, 0, sizeof(struct rte_service_spec));
235 : 1 : service.callback = dummy_cb;
236 : : snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME);
237 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, NULL),
238 : : "Register of non-MT safe service failed");
239 : :
240 : : /* verify flag is enabled */
241 : 1 : mt = rte_service_probe_capability(sid, RTE_SERVICE_CAP_MT_SAFE);
242 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, mt, "MT SAFE cap flag set on non MT SAFE service");
243 : :
244 : 1 : return unregister_all();
245 : : }
246 : :
247 : : /* verify the service name */
248 : : static int
249 : 1 : service_name(void)
250 : : {
251 : 1 : const char *name = rte_service_get_name(0);
252 : 1 : int equal = strcmp(name, DUMMY_SERVICE_NAME);
253 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, equal, "Error: Service name not correct");
254 : :
255 : 1 : return unregister_all();
256 : : }
257 : :
258 : : /* verify service attr get */
259 : : static int
260 : 0 : service_attr_get(void)
261 : : {
262 : : /* ensure all services unregistered so cycle counts are zero */
263 : 0 : unregister_all();
264 : :
265 : : struct rte_service_spec service;
266 : : memset(&service, 0, sizeof(struct rte_service_spec));
267 : 0 : service.callback = dummy_cb;
268 : : snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME);
269 : 0 : service.capabilities |= RTE_SERVICE_CAP_MT_SAFE;
270 : : uint32_t id;
271 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id),
272 : : "Register of service failed");
273 : 0 : rte_service_component_runstate_set(id, 1);
274 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_runstate_set(id, 1),
275 : : "Error: Service start returned non-zero");
276 : 0 : rte_service_set_stats_enable(id, 1);
277 : :
278 : : uint32_t attr_id = UINT32_MAX;
279 : 0 : uint64_t attr_value = 0xdead;
280 : : /* check error return values */
281 [ # # ]: 0 : TEST_ASSERT_EQUAL(-EINVAL, rte_service_attr_get(id, attr_id,
282 : : &attr_value),
283 : : "Invalid attr_id didn't return -EINVAL");
284 : :
285 : : attr_id = RTE_SERVICE_ATTR_CYCLES;
286 [ # # ]: 0 : TEST_ASSERT_EQUAL(-EINVAL, rte_service_attr_get(UINT32_MAX, attr_id,
287 : : &attr_value),
288 : : "Invalid service id didn't return -EINVAL");
289 : :
290 [ # # ]: 0 : TEST_ASSERT_EQUAL(-EINVAL, rte_service_attr_get(id, attr_id, NULL),
291 : : "Invalid attr_value pointer id didn't return -EINVAL");
292 : :
293 : : /* check correct (zero) return value and correct value (zero) */
294 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_id, &attr_value),
295 : : "Valid attr_get() call didn't return success");
296 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, attr_value,
297 : : "attr_get() call didn't set correct cycles (zero)");
298 : : /* check correct call count */
299 : : const int attr_calls = RTE_SERVICE_ATTR_CALL_COUNT;
300 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_calls, &attr_value),
301 : : "Valid attr_get() call didn't return success");
302 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, attr_value,
303 : : "attr_get() call didn't get call count (zero)");
304 : :
305 : : /* Call service to increment cycle count */
306 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id),
307 : : "Service core add did not return zero");
308 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(id, slcore_id, 1),
309 : : "Enabling valid service and core failed");
310 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_start(slcore_id),
311 : : "Starting service core failed");
312 : :
313 : : /* wait for the service lcore to run */
314 : : rte_delay_ms(200);
315 : :
316 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_id, &attr_value),
317 : : "Valid attr_get() call didn't return success");
318 : 0 : int cycles_gt_zero = attr_value > 0;
319 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, cycles_gt_zero,
320 : : "attr_get() failed to get cycles (expected > zero)");
321 : :
322 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(id, slcore_id, 0),
323 : : "Disabling valid service and core failed");
324 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_stop(slcore_id),
325 : : "Failed to stop service lcore");
326 : :
327 : 0 : wait_slcore_inactive(slcore_id);
328 : :
329 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_may_be_active(slcore_id),
330 : : "Service lcore not stopped after waiting.");
331 : :
332 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_calls, &attr_value),
333 : : "Valid attr_get() call didn't return success");
334 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, (attr_value > 0),
335 : : "attr_get() call didn't get call count (zero)");
336 : :
337 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_attr_reset_all(id),
338 : : "Valid attr_reset_all() return success");
339 : :
340 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_id, &attr_value),
341 : : "Valid attr_get() call didn't return success");
342 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, attr_value,
343 : : "attr_get() call didn't set correct cycles (zero)");
344 : : /* ensure call count > zero */
345 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_attr_get(id, attr_calls, &attr_value),
346 : : "Valid attr_get() call didn't return success");
347 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, (attr_value > 0),
348 : : "attr_get() call didn't get call count (zero)");
349 : :
350 : 0 : return unregister_all();
351 : : }
352 : :
353 : : /* verify service lcore attr get */
354 : : static int
355 : 0 : service_lcore_attr_get(void)
356 : : {
357 : : /* ensure all services unregistered so cycle counts are zero */
358 : 0 : unregister_all();
359 : :
360 : : struct rte_service_spec service;
361 : : memset(&service, 0, sizeof(struct rte_service_spec));
362 : 0 : service.callback = dummy_cb;
363 : : snprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME);
364 : 0 : service.capabilities |= RTE_SERVICE_CAP_MT_SAFE;
365 : : uint32_t id;
366 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id),
367 : : "Register of service failed");
368 : 0 : rte_service_component_runstate_set(id, 1);
369 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_runstate_set(id, 1),
370 : : "Error: Service start returned non-zero");
371 : 0 : rte_service_set_stats_enable(id, 1);
372 : :
373 : 0 : uint64_t lcore_attr_value = 0xdead;
374 : : uint32_t lcore_attr_id = UINT32_MAX;
375 : :
376 : : /* check error return values */
377 [ # # ]: 0 : TEST_ASSERT_EQUAL(-EINVAL, rte_service_lcore_attr_get(UINT32_MAX,
378 : : lcore_attr_id, &lcore_attr_value),
379 : : "Invalid lcore_id didn't return -EINVAL");
380 [ # # ]: 0 : TEST_ASSERT_EQUAL(-ENOTSUP, rte_service_lcore_attr_get(rte_lcore_id(),
381 : : lcore_attr_id, &lcore_attr_value),
382 : : "Non-service core didn't return -ENOTSUP");
383 : :
384 : : /* Start service core to increment loop count */
385 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id),
386 : : "Service core add did not return zero");
387 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(id, slcore_id, 1),
388 : : "Enabling valid service and core failed");
389 : : /* Ensure service is not active before starting */
390 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_may_be_active(slcore_id),
391 : : "Not-active service core reported as active");
392 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_start(slcore_id),
393 : : "Starting service core failed");
394 : :
395 : : /* wait for the service lcore to run */
396 : : rte_delay_ms(200);
397 : :
398 : : lcore_attr_id = RTE_SERVICE_LCORE_ATTR_LOOPS;
399 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_attr_get(slcore_id,
400 : : lcore_attr_id, &lcore_attr_value),
401 : : "Valid lcore_attr_get() call didn't return success");
402 : 0 : int loops_gt_zero = lcore_attr_value > 0;
403 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, loops_gt_zero,
404 : : "lcore_attr_get() failed to get loops "
405 : : "(expected > zero)");
406 : :
407 : : lcore_attr_id = 42; /* invalid lcore attr id */
408 [ # # ]: 0 : TEST_ASSERT_EQUAL(-EINVAL, rte_service_lcore_attr_get(slcore_id,
409 : : lcore_attr_id, &lcore_attr_value),
410 : : "Invalid lcore attr didn't return -EINVAL");
411 : :
412 : : /* Ensure service is active */
413 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, rte_service_lcore_may_be_active(slcore_id),
414 : : "Active service core reported as not-active");
415 : :
416 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(id, slcore_id, 0),
417 : : "Disabling valid service and core failed");
418 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_stop(slcore_id),
419 : : "Failed to stop service lcore");
420 : :
421 : 0 : wait_slcore_inactive(slcore_id);
422 : :
423 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_may_be_active(slcore_id),
424 : : "Service lcore not stopped after waiting.");
425 : :
426 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_attr_reset_all(slcore_id),
427 : : "Valid lcore_attr_reset_all() didn't return success");
428 : :
429 : : lcore_attr_id = RTE_SERVICE_LCORE_ATTR_LOOPS;
430 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_attr_get(slcore_id,
431 : : lcore_attr_id, &lcore_attr_value),
432 : : "Valid lcore_attr_get() call didn't return success");
433 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, lcore_attr_value,
434 : : "lcore_attr_get() didn't get correct loop count "
435 : : "(zero)");
436 : :
437 : 0 : return unregister_all();
438 : : }
439 : :
440 : : /* verify service dump */
441 : : static int
442 : 1 : service_dump(void)
443 : : {
444 : : const uint32_t sid = 0;
445 : 1 : rte_service_set_stats_enable(sid, 1);
446 : 1 : rte_service_dump(stdout, 0);
447 : 1 : rte_service_set_stats_enable(sid, 0);
448 : 1 : rte_service_dump(stdout, 0);
449 : 1 : return unregister_all();
450 : : }
451 : :
452 : : /* start and stop a service */
453 : : static int
454 : 1 : service_start_stop(void)
455 : : {
456 : : const uint32_t sid = 0;
457 : :
458 : : /* runstate_get() returns if service is running and slcore is mapped */
459 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id),
460 : : "Service core add did not return zero");
461 : 1 : int ret = rte_service_map_lcore_set(sid, slcore_id, 1);
462 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, ret,
463 : : "Enabling service core, expected 0 got %d", ret);
464 : :
465 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_runstate_get(sid),
466 : : "Error: Service should be stopped");
467 : :
468 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0),
469 : : "Error: Service stopped returned non-zero");
470 : :
471 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_runstate_get(sid),
472 : : "Error: Service is running - should be stopped");
473 : :
474 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 1),
475 : : "Error: Service start returned non-zero");
476 : :
477 [ - + ]: 1 : TEST_ASSERT_EQUAL(1, rte_service_runstate_get(sid),
478 : : "Error: Service is not running");
479 : :
480 : 1 : return unregister_all();
481 : : }
482 : :
483 : :
484 : : static int
485 : 1 : service_remote_launch_func(void *arg)
486 : : {
487 : : RTE_SET_USED(arg);
488 : 1 : service_remote_launch_flag = 1;
489 : 1 : return 0;
490 : : }
491 : :
492 : : /* enable and disable a lcore for a service */
493 : : static int
494 : 1 : service_lcore_en_dis_able(void)
495 : : {
496 : : const uint32_t sid = 0;
497 : :
498 : : /* expected failure cases */
499 [ - + ]: 1 : TEST_ASSERT_EQUAL(-EINVAL, rte_service_map_lcore_set(sid, 100000, 1),
500 : : "Enable on invalid core did not fail");
501 [ - + ]: 1 : TEST_ASSERT_EQUAL(-EINVAL, rte_service_map_lcore_set(sid, 100000, 0),
502 : : "Disable on invalid core did not fail");
503 : :
504 : : /* add service core to allow enabling */
505 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id),
506 : : "Add service core failed when not in use before");
507 : :
508 : : /* valid enable */
509 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_id, 1),
510 : : "Enabling valid service and core failed");
511 [ - + ]: 1 : TEST_ASSERT_EQUAL(1, rte_service_map_lcore_get(sid, slcore_id),
512 : : "Enabled core returned not-enabled");
513 : :
514 : : /* valid disable */
515 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_id, 0),
516 : : "Disabling valid service and lcore failed");
517 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_map_lcore_get(sid, slcore_id),
518 : : "Disabled core returned enabled");
519 : :
520 : : /* call remote_launch to verify that app can launch ex-service lcore */
521 : 1 : service_remote_launch_flag = 0;
522 : 1 : rte_eal_wait_lcore(slcore_id);
523 : 1 : int ret = rte_eal_remote_launch(service_remote_launch_func, NULL,
524 : : slcore_id);
525 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, ret, "Ex-service core remote launch failed.");
526 : 1 : rte_eal_wait_lcore(slcore_id);
527 [ - + ]: 1 : TEST_ASSERT_EQUAL(1, service_remote_launch_flag,
528 : : "Ex-service core function call had no effect.");
529 : :
530 : 1 : return unregister_all();
531 : : }
532 : :
533 : : static int
534 : : service_lcore_running_check(void)
535 : : {
536 : 1 : uint64_t tick = service_tick;
537 : : rte_delay_ms(SERVICE_DELAY * 100);
538 : : /* if (tick != service_tick) we know the lcore as polled the service */
539 : 1 : return tick != service_tick;
540 : : }
541 : :
542 : : static int
543 : 1 : service_lcore_add_del(void)
544 : 1 : {
545 [ + - + - : 2 : if (!rte_lcore_is_enabled(0) || !rte_lcore_is_enabled(1) ||
- + ]
546 [ - - ]: 1 : !rte_lcore_is_enabled(2) || !rte_lcore_is_enabled(3))
547 : 1 : return TEST_SKIPPED;
548 : :
549 : : /* check initial count */
550 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_count(),
551 : : "Service lcore count has value before adding a lcore");
552 : :
553 : : /* check service lcore add */
554 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id),
555 : : "Add service core failed when not in use before");
556 [ # # ]: 0 : TEST_ASSERT_EQUAL(-EALREADY, rte_service_lcore_add(slcore_id),
557 : : "Add service core failed to refuse in-use lcore");
558 : :
559 : : /* check count */
560 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, rte_service_lcore_count(),
561 : : "Service core count not equal to one");
562 : :
563 : : /* retrieve core list, checking lcore ids */
564 : : const uint32_t size = 4;
565 : : uint32_t service_core_ids[size];
566 : 0 : int32_t n = rte_service_lcore_list(service_core_ids, size);
567 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, n, "Service core list return should equal 1");
568 [ # # ]: 0 : TEST_ASSERT_EQUAL(slcore_id, service_core_ids[0],
569 : : "Service core list lcore must equal slcore_id");
570 : :
571 : : /* recheck count, add more cores, and check count */
572 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, rte_service_lcore_count(),
573 : : "Service core count not equal to one");
574 : 0 : uint32_t slcore_1 = rte_get_next_lcore(/* start core */ -1,
575 : : /* skip main */ 1,
576 : : /* wrap */ 0);
577 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_1),
578 : : "Service core add did not return zero");
579 : 0 : uint32_t slcore_2 = rte_get_next_lcore(/* start core */ slcore_1,
580 : : /* skip main */ 1,
581 : : /* wrap */ 0);
582 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_2),
583 : : "Service core add did not return zero");
584 : :
585 : 0 : uint32_t count = rte_service_lcore_count();
586 : : const uint32_t cores_at_this_point = 3;
587 [ # # ]: 0 : TEST_ASSERT_EQUAL(cores_at_this_point, count,
588 : : "Service core count %d, expected %d", count,
589 : : cores_at_this_point);
590 : :
591 : : /* check longer service core list */
592 : 0 : n = rte_service_lcore_list(service_core_ids, size);
593 [ # # ]: 0 : TEST_ASSERT_EQUAL(3, n, "Service core list return should equal 3");
594 [ # # ]: 0 : TEST_ASSERT_EQUAL(slcore_id, service_core_ids[0],
595 : : "Service core list[0] lcore must equal 1");
596 [ # # ]: 0 : TEST_ASSERT_EQUAL(slcore_1, service_core_ids[1],
597 : : "Service core list[1] lcore must equal 2");
598 [ # # ]: 0 : TEST_ASSERT_EQUAL(slcore_2, service_core_ids[2],
599 : : "Service core list[2] lcore must equal 3");
600 : :
601 : : /* recheck count, remove lcores, check remaining lcore_id is correct */
602 [ # # ]: 0 : TEST_ASSERT_EQUAL(3, rte_service_lcore_count(),
603 : : "Service core count not equal to three");
604 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_del(slcore_1),
605 : : "Service core add did not return zero");
606 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_del(slcore_2),
607 : : "Service core add did not return zero");
608 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, rte_service_lcore_count(),
609 : : "Service core count not equal to one");
610 : 0 : n = rte_service_lcore_list(service_core_ids, size);
611 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, n, "Service core list return should equal one");
612 [ # # ]: 0 : TEST_ASSERT_EQUAL(slcore_id, service_core_ids[0],
613 : : "Service core list[0] lcore must equal %d",
614 : : slcore_id);
615 : :
616 : 0 : return unregister_all();
617 : : }
618 : :
619 : : static int
620 : 0 : service_threaded_test(int mt_safe)
621 : : {
622 : 0 : unregister_all();
623 : :
624 : : /* add next 2 cores */
625 : 0 : uint32_t slcore_1 = rte_get_next_lcore(/* start core */ -1,
626 : : /* skip main */ 1,
627 : : /* wrap */ 0);
628 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_1),
629 : : "mt safe lcore add fail");
630 : 0 : uint32_t slcore_2 = rte_get_next_lcore(/* start core */ slcore_1,
631 : : /* skip main */ 1,
632 : : /* wrap */ 0);
633 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_2),
634 : : "mt safe lcore add fail");
635 : :
636 : : /* Use locks to verify that two threads are in the same function
637 : : * at the same time. These are passed to the unit tests through
638 : : * the callback userdata parameter.
639 : : */
640 : : uint32_t test_params[2];
641 : : memset(test_params, 0, sizeof(uint32_t) * 2);
642 : :
643 : : /* register MT safe service. */
644 : : struct rte_service_spec service;
645 : : memset(&service, 0, sizeof(struct rte_service_spec));
646 [ # # ]: 0 : service.callback_userdata = test_params;
647 : : snprintf(service.name, sizeof(service.name), MT_SAFE_SERVICE_NAME);
648 : :
649 [ # # ]: 0 : if (mt_safe) {
650 : 0 : service.callback = dummy_mt_safe_cb;
651 : 0 : service.capabilities |= RTE_SERVICE_CAP_MT_SAFE;
652 : : } else
653 : 0 : service.callback = dummy_mt_unsafe_cb;
654 : :
655 : : uint32_t id;
656 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id),
657 : : "Register of MT SAFE service failed");
658 : :
659 : : const uint32_t sid = 0;
660 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 1),
661 : : "Starting valid service failed");
662 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_1, 1),
663 : : "Failed to enable lcore 1 on mt safe service");
664 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_2, 1),
665 : : "Failed to enable lcore 2 on mt safe service");
666 : 0 : rte_service_lcore_start(slcore_1);
667 : 0 : rte_service_lcore_start(slcore_2);
668 : :
669 : : /* wait for the worker threads to run */
670 : : rte_delay_ms(500);
671 : 0 : rte_service_lcore_stop(slcore_1);
672 : 0 : rte_service_lcore_stop(slcore_2);
673 : :
674 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, test_params[1],
675 : : "Service run with component runstate = 0");
676 : :
677 : : /* enable backend runstate: the service should run after this */
678 : 0 : rte_service_component_runstate_set(id, 1);
679 : :
680 : : /* initialize to pass, see callback comment for details */
681 [ # # ]: 0 : if (!mt_safe)
682 : 0 : test_params[1] = 1;
683 : :
684 : : /* wait for lcores before start() */
685 : 0 : rte_eal_wait_lcore(slcore_1);
686 : 0 : rte_eal_wait_lcore(slcore_2);
687 : :
688 : 0 : rte_service_lcore_start(slcore_1);
689 : 0 : rte_service_lcore_start(slcore_2);
690 : :
691 : : /* wait for the worker threads to run */
692 : : rte_delay_ms(500);
693 : 0 : rte_service_lcore_stop(slcore_1);
694 : 0 : rte_service_lcore_stop(slcore_2);
695 : :
696 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, test_params[1],
697 : : "MT Safe service not run by two cores concurrently");
698 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0),
699 : : "Failed to stop MT Safe service");
700 : :
701 : 0 : rte_eal_wait_lcore(slcore_1);
702 : 0 : rte_eal_wait_lcore(slcore_2);
703 : 0 : unregister_all();
704 : :
705 : : /* return the value of the callback pass_test variable to caller */
706 : 0 : return test_params[1];
707 : : }
708 : :
709 : : /* tests an MT SAFE service with two cores. The callback function ensures that
710 : : * two threads access the callback concurrently.
711 : : */
712 : : static int
713 : 1 : service_mt_safe_poll(void)
714 : : {
715 : : int mt_safe = 1;
716 : :
717 [ + - + - : 2 : if (!rte_lcore_is_enabled(0) || !rte_lcore_is_enabled(1) ||
+ - ]
718 : 1 : !rte_lcore_is_enabled(2))
719 : 1 : return TEST_SKIPPED;
720 : :
721 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, service_threaded_test(mt_safe),
722 : : "Error: MT Safe service not run by two cores concurrently");
723 : : return TEST_SUCCESS;
724 : : }
725 : :
726 : : /* tests a NON mt safe service with two cores, the callback is serialized
727 : : * using the CAS.
728 : : */
729 : : static int
730 : 1 : service_mt_unsafe_poll(void)
731 : : {
732 : : int mt_safe = 0;
733 : :
734 [ + - + - : 2 : if (!rte_lcore_is_enabled(0) || !rte_lcore_is_enabled(1) ||
+ - ]
735 : 1 : !rte_lcore_is_enabled(2))
736 : 1 : return TEST_SKIPPED;
737 : :
738 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, service_threaded_test(mt_safe),
739 : : "Error: NON MT Safe service run by two cores concurrently");
740 : : return TEST_SUCCESS;
741 : : }
742 : :
743 : : static int32_t
744 : 0 : delay_as_a_mt_safe_service(void *args)
745 : : {
746 : : RTE_SET_USED(args);
747 : : uint32_t *params = args;
748 : :
749 : : /* retrieve done flag and lock to add/sub */
750 : : uint32_t *done = ¶ms[0];
751 : 0 : uint32_t *lock = ¶ms[1];
752 : :
753 [ # # ]: 0 : while (!*done) {
754 : 0 : __atomic_fetch_add(lock, 1, __ATOMIC_RELAXED);
755 : 0 : rte_delay_us(500);
756 [ # # ]: 0 : if (__atomic_load_n(lock, __ATOMIC_RELAXED) > 1)
757 : : /* pass: second core has simultaneously incremented */
758 : 0 : *done = 1;
759 : 0 : __atomic_fetch_sub(lock, 1, __ATOMIC_RELAXED);
760 : : }
761 : :
762 : 0 : return 0;
763 : : }
764 : :
765 : : static int32_t
766 : 0 : delay_as_a_service(void *args)
767 : : {
768 : : uint32_t *done = (uint32_t *)args;
769 [ # # ]: 0 : while (!*done)
770 : : rte_delay_ms(5);
771 : 0 : return 0;
772 : : }
773 : :
774 : : static int
775 : 0 : service_run_on_app_core_func(void *arg)
776 : : {
777 : : uint32_t *delay_service_id = (uint32_t *)arg;
778 : 0 : return rte_service_run_iter_on_app_lcore(*delay_service_id, 1);
779 : : }
780 : :
781 : : static float
782 : 0 : service_app_lcore_perf_measure(uint32_t id)
783 : : {
784 : : /* Performance test: call in a loop, and measure tsc() */
785 : : const uint32_t perf_iters = (1 << 12);
786 : : uint64_t start = rte_rdtsc();
787 : : uint32_t i;
788 [ # # ]: 0 : for (i = 0; i < perf_iters; i++) {
789 : : int err = service_run_on_app_core_func(&id);
790 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, err, "perf test: returned run failure");
791 : : }
792 : : uint64_t end = rte_rdtsc();
793 : :
794 : 0 : return (end - start)/(float)perf_iters;
795 : : }
796 : :
797 : : static int
798 : 0 : service_app_lcore_poll_impl(const int mt_safe)
799 : : {
800 [ # # ]: 0 : uint32_t params[2] = {0};
801 : :
802 : : struct rte_service_spec service;
803 : : memset(&service, 0, sizeof(struct rte_service_spec));
804 : : snprintf(service.name, sizeof(service.name), MT_SAFE_SERVICE_NAME);
805 [ # # ]: 0 : if (mt_safe) {
806 : 0 : service.callback = delay_as_a_mt_safe_service;
807 : 0 : service.callback_userdata = params;
808 : 0 : service.capabilities |= RTE_SERVICE_CAP_MT_SAFE;
809 : : } else {
810 : 0 : service.callback = delay_as_a_service;
811 : 0 : service.callback_userdata = ¶ms;
812 : : }
813 : :
814 : : uint32_t id;
815 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id),
816 : : "Register of app lcore delay service failed");
817 : :
818 : 0 : rte_service_component_runstate_set(id, 1);
819 : 0 : rte_service_runstate_set(id, 1);
820 : :
821 : 0 : uint32_t app_core2 = rte_get_next_lcore(slcore_id, 1, 1);
822 : 0 : rte_eal_wait_lcore(app_core2);
823 : 0 : int app_core2_ret = rte_eal_remote_launch(service_run_on_app_core_func,
824 : : &id, app_core2);
825 : :
826 : : rte_delay_ms(100);
827 : :
828 : : int app_core1_ret = service_run_on_app_core_func(&id);
829 : :
830 : : /* flag done, then wait for the spawned 2nd core to return */
831 : 0 : params[0] = 1;
832 : 0 : rte_eal_mp_wait_lcore();
833 : :
834 : : /* core two gets launched first - and should hold the service lock */
835 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, app_core2_ret,
836 : : "App core2 : run service didn't return zero");
837 : :
838 [ # # ]: 0 : if (mt_safe) {
839 : : /* mt safe should have both cores return 0 for success */
840 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, app_core1_ret,
841 : : "MT Safe: App core1 didn't return 0");
842 : : } else {
843 : : /* core one attempts to run later - should be blocked */
844 [ # # ]: 0 : TEST_ASSERT_EQUAL(-EBUSY, app_core1_ret,
845 : : "MT Unsafe: App core1 didn't return -EBUSY");
846 : : }
847 : :
848 : : /* Measure performance of no-stats and with-stats. */
849 : 0 : float cyc_no_stats = service_app_lcore_perf_measure(id);
850 : :
851 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_set_stats_enable(id, 1),
852 : : "failed to enable stats for service.");
853 : 0 : float cyc_with_stats = service_app_lcore_perf_measure(id);
854 : :
855 [ # # ]: 0 : printf("perf test for %s, no stats: %0.1f, with stats %0.1f cycles/call\n",
856 : : mt_safe ? "MT Safe" : "MT Unsafe", cyc_no_stats, cyc_with_stats);
857 : :
858 : 0 : unregister_all();
859 : 0 : return TEST_SUCCESS;
860 : : }
861 : :
862 : : static int
863 : 0 : service_app_lcore_mt_safe(void)
864 : : {
865 : : const int mt_safe = 1;
866 : 0 : return service_app_lcore_poll_impl(mt_safe);
867 : : }
868 : :
869 : : static int
870 : 0 : service_app_lcore_mt_unsafe(void)
871 : : {
872 : : const int mt_safe = 0;
873 : 0 : return service_app_lcore_poll_impl(mt_safe);
874 : : }
875 : :
876 : : /* start and stop a service core - ensuring it goes back to sleep */
877 : : static int
878 : 0 : service_lcore_start_stop(void)
879 : : {
880 : : /* start service core and service, create mapping so tick() runs */
881 : : const uint32_t sid = 0;
882 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 1),
883 : : "Starting valid service failed");
884 [ # # ]: 0 : TEST_ASSERT_EQUAL(-EINVAL, rte_service_map_lcore_set(sid, slcore_id, 1),
885 : : "Enabling valid service on non-service core must fail");
886 : :
887 : : /* core start */
888 [ # # ]: 0 : TEST_ASSERT_EQUAL(-EINVAL, rte_service_lcore_start(slcore_id),
889 : : "Service core start without add should return EINVAL");
890 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id),
891 : : "Service core add did not return zero");
892 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_id, 1),
893 : : "Enabling valid service on valid core failed");
894 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_start(slcore_id),
895 : : "Service core start after add failed");
896 [ # # ]: 0 : TEST_ASSERT_EQUAL(-EALREADY, rte_service_lcore_start(slcore_id),
897 : : "Service core expected as running but was stopped");
898 : :
899 : : /* ensures core really is running the service function */
900 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, service_lcore_running_check(),
901 : : "Service core expected to poll service but it didn't");
902 : :
903 : : /* core stop */
904 [ # # ]: 0 : TEST_ASSERT_EQUAL(-EBUSY, rte_service_lcore_stop(slcore_id),
905 : : "Service core running a service should return -EBUSY");
906 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0),
907 : : "Stopping valid service failed");
908 [ # # ]: 0 : TEST_ASSERT_EQUAL(-EINVAL, rte_service_lcore_stop(100000),
909 : : "Invalid Service core stop should return -EINVAL");
910 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_stop(slcore_id),
911 : : "Service core stop expected to return 0");
912 [ # # ]: 0 : TEST_ASSERT_EQUAL(-EALREADY, rte_service_lcore_stop(slcore_id),
913 : : "Already stopped service core should return -EALREADY");
914 : :
915 : : /* ensure service is not longer running */
916 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, service_lcore_running_check(),
917 : : "Service core expected to poll service but it didn't");
918 : :
919 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_del(slcore_id),
920 : : "Service core del did not return zero");
921 : :
922 : 0 : return unregister_all();
923 : : }
924 : :
925 : : static int
926 : 1 : service_ensure_stopped_with_timeout(uint32_t sid)
927 : : {
928 : : /* give the service time to stop running */
929 : : int i;
930 [ + - ]: 2 : for (i = 0; i < TIMEOUT_MS; i++) {
931 [ + + ]: 2 : if (!rte_service_may_be_active(sid))
932 : : break;
933 : : rte_delay_ms(1);
934 : : }
935 : :
936 : 1 : return rte_service_may_be_active(sid);
937 : : }
938 : :
939 : : /* stop a service and wait for it to become inactive */
940 : : static int
941 : 1 : service_may_be_active(void)
942 : : {
943 : : const uint32_t sid = 0;
944 : :
945 : : /* expected failure cases */
946 [ - + ]: 1 : TEST_ASSERT_EQUAL(-EINVAL, rte_service_may_be_active(10000),
947 : : "Invalid service may be active check did not fail");
948 : :
949 : : /* start the service */
950 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 1),
951 : : "Starting valid service failed");
952 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore_id),
953 : : "Add service core failed when not in use before");
954 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore_id, 1),
955 : : "Enabling valid service on valid core failed");
956 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_lcore_start(slcore_id),
957 : : "Service core start after add failed");
958 : :
959 : : /* ensures core really is running the service function */
960 [ - + ]: 1 : TEST_ASSERT_EQUAL(1, service_lcore_running_check(),
961 : : "Service core expected to poll service but it didn't");
962 : :
963 : : /* stop the service, and wait for not-active with timeout */
964 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0),
965 : : "Error: Service stop returned non-zero");
966 [ - + ]: 1 : TEST_ASSERT_EQUAL(0, service_ensure_stopped_with_timeout(sid),
967 : : "Error: Service not stopped after timeout period.");
968 : :
969 : 1 : return unregister_all();
970 : : }
971 : :
972 : : /* check service may be active when service is running on a second lcore */
973 : : static int
974 : 1 : service_active_two_cores(void)
975 : : {
976 [ + - + - : 2 : if (!rte_lcore_is_enabled(0) || !rte_lcore_is_enabled(1) ||
+ - ]
977 : 1 : !rte_lcore_is_enabled(2))
978 : 1 : return TEST_SKIPPED;
979 : :
980 : : const uint32_t sid = 0;
981 : :
982 : 0 : uint32_t lcore = rte_get_next_lcore(/* start core */ -1,
983 : : /* skip main */ 1,
984 : : /* wrap */ 0);
985 : 0 : uint32_t slcore = rte_get_next_lcore(/* start core */ lcore,
986 : : /* skip main */ 1,
987 : : /* wrap */ 0);
988 : :
989 : : /* start the service on the second available lcore */
990 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 1),
991 : : "Starting valid service failed");
992 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_add(slcore),
993 : : "Add service core failed when not in use before");
994 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_map_lcore_set(sid, slcore, 1),
995 : : "Enabling valid service on valid core failed");
996 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_lcore_start(slcore),
997 : : "Service core start after add failed");
998 : :
999 : : /* ensures core really is running the service function */
1000 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, service_lcore_running_check(),
1001 : : "Service core expected to poll service but it didn't");
1002 : :
1003 : : /* ensures that service may be active reports running state */
1004 [ # # ]: 0 : TEST_ASSERT_EQUAL(1, rte_service_may_be_active(sid),
1005 : : "Service may be active did not report running state");
1006 : :
1007 : : /* stop the service */
1008 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0),
1009 : : "Error: Service stop returned non-zero");
1010 [ # # ]: 0 : TEST_ASSERT_EQUAL(0, service_ensure_stopped_with_timeout(sid),
1011 : : "Error: Service not stopped after timeout period.");
1012 : :
1013 : 0 : return unregister_all();
1014 : : }
1015 : :
1016 : : static struct unit_test_suite service_tests = {
1017 : : .suite_name = "service core test suite",
1018 : : .setup = testsuite_setup,
1019 : : .teardown = testsuite_teardown,
1020 : : .unit_test_cases = {
1021 : : TEST_CASE_ST(dummy_register, NULL, unregister_all),
1022 : : TEST_CASE_ST(dummy_register, NULL, service_name),
1023 : : TEST_CASE_ST(dummy_register, NULL, service_get_by_name),
1024 : : TEST_CASE_ST(dummy_register, NULL, service_dump),
1025 : : TEST_CASE_ST(dummy_register, NULL, service_probe_capability),
1026 : : TEST_CASE_ST(dummy_register, NULL, service_start_stop),
1027 : : TEST_CASE_ST(dummy_register, NULL, service_lcore_add_del),
1028 : : TEST_CASE_ST(dummy_register, NULL, service_lcore_en_dis_able),
1029 : : TEST_CASE_ST(dummy_register, NULL, service_mt_unsafe_poll),
1030 : : TEST_CASE_ST(dummy_register, NULL, service_mt_safe_poll),
1031 : : TEST_CASE_ST(dummy_register, NULL, service_may_be_active),
1032 : : TEST_CASE_ST(dummy_register, NULL, service_active_two_cores),
1033 : : TEST_CASES_END() /**< NULL terminate unit test array */
1034 : : }
1035 : : };
1036 : :
1037 : : static int
1038 : 1 : test_service_common(void)
1039 : : {
1040 : 1 : return unit_test_suite_runner(&service_tests);
1041 : : }
1042 : :
1043 : 235 : REGISTER_FAST_TEST(service_autotest, true, true, test_service_common);
1044 : :
1045 : : static struct unit_test_suite service_perf_tests = {
1046 : : .suite_name = "service core performance test suite",
1047 : : .setup = testsuite_setup,
1048 : : .teardown = testsuite_teardown,
1049 : : .unit_test_cases = {
1050 : : TEST_CASE_ST(dummy_register, NULL, service_attr_get),
1051 : : TEST_CASE_ST(dummy_register, NULL, service_lcore_attr_get),
1052 : : TEST_CASE_ST(dummy_register, NULL, service_lcore_start_stop),
1053 : : TEST_CASE_ST(dummy_register, NULL, service_app_lcore_mt_safe),
1054 : : TEST_CASE_ST(dummy_register, NULL, service_app_lcore_mt_unsafe),
1055 : : TEST_CASES_END() /**< NULL terminate unit test array */
1056 : : }
1057 : : };
1058 : :
1059 : : static int
1060 : 0 : test_service_perf(void)
1061 : : {
1062 : 0 : return unit_test_suite_runner(&service_perf_tests);
1063 : : }
1064 : :
1065 : 235 : REGISTER_PERF_TEST(service_perf_autotest, test_service_perf);
|