1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2010-2014 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 /* 35 * Timer 36 * ===== 37 * 38 * #. Stress test 1. 39 * 40 * The objective of the timer stress tests is to check that there are no 41 * race conditions in list and status management. This test launches, 42 * resets and stops the timer very often on many cores at the same 43 * time. 44 * 45 * - Only one timer is used for this test. 46 * - On each core, the rte_timer_manage() function is called from the main 47 * loop every 3 microseconds. 48 * - In the main loop, the timer may be reset (randomly, with a 49 * probability of 0.5 %) 100 microseconds later on a random core, or 50 * stopped (with a probability of 0.5 % also). 51 * - In callback, the timer is can be reset (randomly, with a 52 * probability of 0.5 %) 100 microseconds later on the same core or 53 * on another core (same probability), or stopped (same 54 * probability). 55 * 56 * # Stress test 2. 57 * 58 * The objective of this test is similar to the first in that it attempts 59 * to find if there are any race conditions in the timer library. However, 60 * it is less complex in terms of operations performed and duration, as it 61 * is designed to have a predictable outcome that can be tested. 62 * 63 * - A set of timers is initialized for use by the test 64 * - All cores then simultaneously are set to schedule all the timers at 65 * the same time, so conflicts should occur. 66 * - Then there is a delay while we wait for the timers to expire 67 * - Then the master lcore calls timer_manage() and we check that all 68 * timers have had their callbacks called exactly once - no more no less. 69 * - Then we repeat the process, except after setting up the timers, we have 70 * all cores randomly reschedule them. 71 * - Again we check that the expected number of callbacks has occurred when 72 * we call timer-manage. 73 * 74 * #. Basic test. 75 * 76 * This test performs basic functional checks of the timers. The test 77 * uses four different timers that are loaded and stopped under 78 * specific conditions in specific contexts. 79 * 80 * - Four timers are used for this test. 81 * - On each core, the rte_timer_manage() function is called from main loop 82 * every 3 microseconds. 83 * 84 * The autotest python script checks that the behavior is correct: 85 * 86 * - timer0 87 * 88 * - At initialization, timer0 is loaded by the master core, on master core 89 * in "single" mode (time = 1 second). 90 * - In the first 19 callbacks, timer0 is reloaded on the same core, 91 * then, it is explicitly stopped at the 20th call. 92 * - At t=25s, timer0 is reloaded once by timer2. 93 * 94 * - timer1 95 * 96 * - At initialization, timer1 is loaded by the master core, on the 97 * master core in "single" mode (time = 2 seconds). 98 * - In the first 9 callbacks, timer1 is reloaded on another 99 * core. After the 10th callback, timer1 is not reloaded anymore. 100 * 101 * - timer2 102 * 103 * - At initialization, timer2 is loaded by the master core, on the 104 * master core in "periodical" mode (time = 1 second). 105 * - In the callback, when t=25s, it stops timer3 and reloads timer0 106 * on the current core. 107 * 108 * - timer3 109 * 110 * - At initialization, timer3 is loaded by the master core, on 111 * another core in "periodical" mode (time = 1 second). 112 * - It is stopped at t=25s by timer2. 113 */ 114 115 #include <stdio.h> 116 #include <stdarg.h> 117 #include <string.h> 118 #include <stdlib.h> 119 #include <stdint.h> 120 #include <inttypes.h> 121 #include <sys/queue.h> 122 #include <math.h> 123 124 #include <cmdline_parse.h> 125 126 #include <rte_common.h> 127 #include <rte_log.h> 128 #include <rte_memory.h> 129 #include <rte_memzone.h> 130 #include <rte_launch.h> 131 #include <rte_cycles.h> 132 #include <rte_tailq.h> 133 #include <rte_eal.h> 134 #include <rte_per_lcore.h> 135 #include <rte_lcore.h> 136 #include <rte_atomic.h> 137 #include <rte_timer.h> 138 #include <rte_random.h> 139 #include <rte_malloc.h> 140 141 #include "test.h" 142 143 #define TEST_DURATION_S 20 /* in seconds */ 144 #define NB_TIMER 4 145 146 #define RTE_LOGTYPE_TESTTIMER RTE_LOGTYPE_USER3 147 148 static volatile uint64_t end_time; 149 150 struct mytimerinfo { 151 struct rte_timer tim; 152 unsigned id; 153 unsigned count; 154 }; 155 156 static struct mytimerinfo mytiminfo[NB_TIMER]; 157 158 static void timer_basic_cb(struct rte_timer *tim, void *arg); 159 160 static void 161 mytimer_reset(struct mytimerinfo *timinfo, uint64_t ticks, 162 enum rte_timer_type type, unsigned tim_lcore, 163 rte_timer_cb_t fct) 164 { 165 rte_timer_reset_sync(&timinfo->tim, ticks, type, tim_lcore, 166 fct, timinfo); 167 } 168 169 /* timer callback for stress tests */ 170 static void 171 timer_stress_cb(__attribute__((unused)) struct rte_timer *tim, 172 __attribute__((unused)) void *arg) 173 { 174 long r; 175 unsigned lcore_id = rte_lcore_id(); 176 uint64_t hz = rte_get_timer_hz(); 177 178 if (rte_timer_pending(tim)) 179 return; 180 181 r = rte_rand(); 182 if ((r & 0xff) == 0) { 183 mytimer_reset(&mytiminfo[0], hz, SINGLE, lcore_id, 184 timer_stress_cb); 185 } 186 else if ((r & 0xff) == 1) { 187 mytimer_reset(&mytiminfo[0], hz, SINGLE, 188 rte_get_next_lcore(lcore_id, 0, 1), 189 timer_stress_cb); 190 } 191 else if ((r & 0xff) == 2) { 192 rte_timer_stop(&mytiminfo[0].tim); 193 } 194 } 195 196 static int 197 timer_stress_main_loop(__attribute__((unused)) void *arg) 198 { 199 uint64_t hz = rte_get_timer_hz(); 200 unsigned lcore_id = rte_lcore_id(); 201 uint64_t cur_time; 202 int64_t diff = 0; 203 long r; 204 205 while (diff >= 0) { 206 207 /* call the timer handler on each core */ 208 rte_timer_manage(); 209 210 /* simulate the processing of a packet 211 * (1 us = 2000 cycles at 2 Ghz) */ 212 rte_delay_us(1); 213 214 /* randomly stop or reset timer */ 215 r = rte_rand(); 216 lcore_id = rte_get_next_lcore(lcore_id, 0, 1); 217 if ((r & 0xff) == 0) { 218 /* 100 us */ 219 mytimer_reset(&mytiminfo[0], hz/10000, SINGLE, lcore_id, 220 timer_stress_cb); 221 } 222 else if ((r & 0xff) == 1) { 223 rte_timer_stop_sync(&mytiminfo[0].tim); 224 } 225 cur_time = rte_get_timer_cycles(); 226 diff = end_time - cur_time; 227 } 228 229 lcore_id = rte_lcore_id(); 230 RTE_LOG(INFO, TESTTIMER, "core %u finished\n", lcore_id); 231 232 return 0; 233 } 234 235 static volatile int cb_count = 0; 236 237 /* callback for second stress test. will only be called 238 * on master lcore */ 239 static void 240 timer_stress2_cb(struct rte_timer *tim __rte_unused, void *arg __rte_unused) 241 { 242 cb_count++; 243 } 244 245 #define NB_STRESS2_TIMERS 8192 246 247 static int 248 timer_stress2_main_loop(__attribute__((unused)) void *arg) 249 { 250 static struct rte_timer *timers; 251 int i; 252 static volatile int ready = 0; 253 uint64_t delay = rte_get_timer_hz() / 4; 254 unsigned lcore_id = rte_lcore_id(); 255 256 if (lcore_id == rte_get_master_lcore()) { 257 timers = rte_malloc(NULL, sizeof(*timers) * NB_STRESS2_TIMERS, 0); 258 if (timers == NULL) { 259 printf("Test Failed\n"); 260 printf("- Cannot allocate memory for timers\n" ); 261 return -1; 262 } 263 for (i = 0; i < NB_STRESS2_TIMERS; i++) 264 rte_timer_init(&timers[i]); 265 ready = 1; 266 } else { 267 while (!ready) 268 rte_pause(); 269 } 270 271 /* have all cores schedule all timers on master lcore */ 272 for (i = 0; i < NB_STRESS2_TIMERS; i++) 273 rte_timer_reset(&timers[i], delay, SINGLE, rte_get_master_lcore(), 274 timer_stress2_cb, NULL); 275 276 ready = 0; 277 rte_delay_ms(500); 278 279 /* now check that we get the right number of callbacks */ 280 if (lcore_id == rte_get_master_lcore()) { 281 rte_timer_manage(); 282 if (cb_count != NB_STRESS2_TIMERS) { 283 printf("Test Failed\n"); 284 printf("- Stress test 2, part 1 failed\n"); 285 printf("- Expected %d callbacks, got %d\n", NB_STRESS2_TIMERS, 286 cb_count); 287 return -1; 288 } 289 ready = 1; 290 } else { 291 while (!ready) 292 rte_pause(); 293 } 294 295 /* now test again, just stop and restart timers at random after init*/ 296 for (i = 0; i < NB_STRESS2_TIMERS; i++) 297 rte_timer_reset(&timers[i], delay, SINGLE, rte_get_master_lcore(), 298 timer_stress2_cb, NULL); 299 cb_count = 0; 300 301 /* pick random timer to reset, stopping them first half the time */ 302 for (i = 0; i < 100000; i++) { 303 int r = rand() % NB_STRESS2_TIMERS; 304 if (i % 2) 305 rte_timer_stop(&timers[r]); 306 rte_timer_reset(&timers[r], delay, SINGLE, rte_get_master_lcore(), 307 timer_stress2_cb, NULL); 308 } 309 310 rte_delay_ms(500); 311 312 /* now check that we get the right number of callbacks */ 313 if (lcore_id == rte_get_master_lcore()) { 314 rte_timer_manage(); 315 if (cb_count != NB_STRESS2_TIMERS) { 316 printf("Test Failed\n"); 317 printf("- Stress test 2, part 2 failed\n"); 318 printf("- Expected %d callbacks, got %d\n", NB_STRESS2_TIMERS, 319 cb_count); 320 return -1; 321 } 322 printf("Test OK\n"); 323 } 324 325 return 0; 326 } 327 328 /* timer callback for basic tests */ 329 static void 330 timer_basic_cb(struct rte_timer *tim, void *arg) 331 { 332 struct mytimerinfo *timinfo = arg; 333 uint64_t hz = rte_get_timer_hz(); 334 unsigned lcore_id = rte_lcore_id(); 335 uint64_t cur_time = rte_get_timer_cycles(); 336 337 if (rte_timer_pending(tim)) 338 return; 339 340 timinfo->count ++; 341 342 RTE_LOG(INFO, TESTTIMER, 343 "%"PRIu64": callback id=%u count=%u on core %u\n", 344 cur_time, timinfo->id, timinfo->count, lcore_id); 345 346 /* reload timer 0 on same core */ 347 if (timinfo->id == 0 && timinfo->count < 20) { 348 mytimer_reset(timinfo, hz, SINGLE, lcore_id, timer_basic_cb); 349 return; 350 } 351 352 /* reload timer 1 on next core */ 353 if (timinfo->id == 1 && timinfo->count < 10) { 354 mytimer_reset(timinfo, hz*2, SINGLE, 355 rte_get_next_lcore(lcore_id, 0, 1), 356 timer_basic_cb); 357 return; 358 } 359 360 /* Explicitelly stop timer 0. Once stop() called, we can even 361 * erase the content of the structure: it is not referenced 362 * anymore by any code (in case of dynamic structure, it can 363 * be freed) */ 364 if (timinfo->id == 0 && timinfo->count == 20) { 365 366 /* stop_sync() is not needed, because we know that the 367 * status of timer is only modified by this core */ 368 rte_timer_stop(tim); 369 memset(tim, 0xAA, sizeof(struct rte_timer)); 370 return; 371 } 372 373 /* stop timer3, and restart a new timer0 (it was removed 5 374 * seconds ago) for a single shot */ 375 if (timinfo->id == 2 && timinfo->count == 25) { 376 rte_timer_stop_sync(&mytiminfo[3].tim); 377 378 /* need to reinit because structure was erased with 0xAA */ 379 rte_timer_init(&mytiminfo[0].tim); 380 mytimer_reset(&mytiminfo[0], hz, SINGLE, lcore_id, 381 timer_basic_cb); 382 } 383 } 384 385 static int 386 timer_basic_main_loop(__attribute__((unused)) void *arg) 387 { 388 uint64_t hz = rte_get_timer_hz(); 389 unsigned lcore_id = rte_lcore_id(); 390 uint64_t cur_time; 391 int64_t diff = 0; 392 393 /* launch all timers on core 0 */ 394 if (lcore_id == rte_get_master_lcore()) { 395 mytimer_reset(&mytiminfo[0], hz, SINGLE, lcore_id, 396 timer_basic_cb); 397 mytimer_reset(&mytiminfo[1], hz*2, SINGLE, lcore_id, 398 timer_basic_cb); 399 mytimer_reset(&mytiminfo[2], hz, PERIODICAL, lcore_id, 400 timer_basic_cb); 401 mytimer_reset(&mytiminfo[3], hz, PERIODICAL, 402 rte_get_next_lcore(lcore_id, 0, 1), 403 timer_basic_cb); 404 } 405 406 while (diff >= 0) { 407 408 /* call the timer handler on each core */ 409 rte_timer_manage(); 410 411 /* simulate the processing of a packet 412 * (3 us = 6000 cycles at 2 Ghz) */ 413 rte_delay_us(3); 414 415 cur_time = rte_get_timer_cycles(); 416 diff = end_time - cur_time; 417 } 418 RTE_LOG(INFO, TESTTIMER, "core %u finished\n", lcore_id); 419 420 return 0; 421 } 422 423 static int 424 timer_sanity_check(void) 425 { 426 #ifdef RTE_LIBEAL_USE_HPET 427 if (eal_timer_source != EAL_TIMER_HPET) { 428 printf("Not using HPET, can't sanity check timer sources\n"); 429 return 0; 430 } 431 432 const uint64_t t_hz = rte_get_tsc_hz(); 433 const uint64_t h_hz = rte_get_hpet_hz(); 434 printf("Hertz values: TSC = %"PRIu64", HPET = %"PRIu64"\n", t_hz, h_hz); 435 436 const uint64_t tsc_start = rte_get_tsc_cycles(); 437 const uint64_t hpet_start = rte_get_hpet_cycles(); 438 rte_delay_ms(100); /* delay 1/10 second */ 439 const uint64_t tsc_end = rte_get_tsc_cycles(); 440 const uint64_t hpet_end = rte_get_hpet_cycles(); 441 printf("Measured cycles: TSC = %"PRIu64", HPET = %"PRIu64"\n", 442 tsc_end-tsc_start, hpet_end-hpet_start); 443 444 const double tsc_time = (double)(tsc_end - tsc_start)/t_hz; 445 const double hpet_time = (double)(hpet_end - hpet_start)/h_hz; 446 /* get the percentage that the times differ by */ 447 const double time_diff = fabs(tsc_time - hpet_time)*100/tsc_time; 448 printf("Measured time: TSC = %.4f, HPET = %.4f\n", tsc_time, hpet_time); 449 450 printf("Elapsed time measured by TSC and HPET differ by %f%%\n", 451 time_diff); 452 if (time_diff > 0.1) { 453 printf("Error times differ by >0.1%%"); 454 return -1; 455 } 456 #endif 457 return 0; 458 } 459 460 int 461 test_timer(void) 462 { 463 unsigned i; 464 uint64_t cur_time; 465 uint64_t hz; 466 467 /* sanity check our timer sources and timer config values */ 468 if (timer_sanity_check() < 0) { 469 printf("Timer sanity checks failed\n"); 470 return -1; 471 } 472 473 if (rte_lcore_count() < 2) { 474 printf("not enough lcores for this test\n"); 475 return -1; 476 } 477 478 /* init timer */ 479 for (i=0; i<NB_TIMER; i++) { 480 memset(&mytiminfo[i], 0, sizeof(struct mytimerinfo)); 481 mytiminfo[i].id = i; 482 rte_timer_init(&mytiminfo[i].tim); 483 } 484 485 /* calculate the "end of test" time */ 486 cur_time = rte_get_timer_cycles(); 487 hz = rte_get_timer_hz(); 488 end_time = cur_time + (hz * TEST_DURATION_S); 489 490 /* start other cores */ 491 printf("Start timer stress tests (%d seconds)\n", TEST_DURATION_S); 492 rte_eal_mp_remote_launch(timer_stress_main_loop, NULL, CALL_MASTER); 493 rte_eal_mp_wait_lcore(); 494 495 /* stop timer 0 used for stress test */ 496 rte_timer_stop_sync(&mytiminfo[0].tim); 497 498 /* run a second, slightly different set of stress tests */ 499 printf("Start timer stress tests 2\n"); 500 rte_eal_mp_remote_launch(timer_stress2_main_loop, NULL, CALL_MASTER); 501 rte_eal_mp_wait_lcore(); 502 503 /* calculate the "end of test" time */ 504 cur_time = rte_get_timer_cycles(); 505 hz = rte_get_timer_hz(); 506 end_time = cur_time + (hz * TEST_DURATION_S); 507 508 /* start other cores */ 509 printf("Start timer basic tests (%d seconds)\n", TEST_DURATION_S); 510 rte_eal_mp_remote_launch(timer_basic_main_loop, NULL, CALL_MASTER); 511 rte_eal_mp_wait_lcore(); 512 513 /* stop all timers */ 514 for (i=0; i<NB_TIMER; i++) { 515 rte_timer_stop_sync(&mytiminfo[i].tim); 516 } 517 518 rte_timer_dump_stats(); 519 520 return 0; 521 } 522