Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'trace-latency-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull tracing latency update from Steven Rostedt:

- Add TIMERLAT_ALIGN osnoise option

Add a timer alignment option for timerlat that makes it work like the
cyclictest -A option. timelat creates threads to test the latency of
the kernel. The alignment option will have these threads trigger at
the alignment offsets from each other. Instead of having each thread
wake up at the exact same time, if the alignment is set to "20" each
thread will wake up at 20 microseconds from the previous one.

* tag 'trace-latency-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
tracing/osnoise: Add option to align tlat threads

+53 -1
+53 -1
kernel/trace/trace_osnoise.c
··· 58 58 OSN_PANIC_ON_STOP, 59 59 OSN_PREEMPT_DISABLE, 60 60 OSN_IRQ_DISABLE, 61 + OSN_TIMERLAT_ALIGN, 61 62 OSN_MAX 62 63 }; 63 64 ··· 67 66 "OSNOISE_WORKLOAD", 68 67 "PANIC_ON_STOP", 69 68 "OSNOISE_PREEMPT_DISABLE", 70 - "OSNOISE_IRQ_DISABLE" }; 69 + "OSNOISE_IRQ_DISABLE", 70 + "TIMERLAT_ALIGN" }; 71 71 72 72 #define OSN_DEFAULT_OPTIONS 0x2 73 73 static unsigned long osnoise_options = OSN_DEFAULT_OPTIONS; ··· 253 251 static DEFINE_PER_CPU(struct timerlat_variables, per_cpu_timerlat_var); 254 252 255 253 /* 254 + * timerlat wake-up offset for next thread with TIMERLAT_ALIGN set. 255 + */ 256 + static atomic64_t align_next; 257 + 258 + /* 256 259 * this_cpu_tmr_var - Return the per-cpu timerlat_variables on its relative CPU 257 260 */ 258 261 static inline struct timerlat_variables *this_cpu_tmr_var(void) ··· 275 268 276 269 /* Synchronize with the timerlat interfaces */ 277 270 mutex_lock(&interface_lock); 271 + 278 272 /* 279 273 * So far, all the values are initialized as 0, so 280 274 * zeroing the structure is perfect. ··· 286 278 hrtimer_cancel(&tlat_var->timer); 287 279 memset(tlat_var, 0, sizeof(*tlat_var)); 288 280 } 281 + /* 282 + * Reset also align_next, to be filled by a new offset by the first timerlat 283 + * thread that wakes up, if TIMERLAT_ALIGN is set. 284 + */ 285 + atomic64_set(&align_next, 0); 286 + 289 287 mutex_unlock(&interface_lock); 290 288 } 291 289 #else /* CONFIG_TIMERLAT_TRACER */ ··· 340 326 u64 stop_tracing_total; /* stop trace in the final operation (report/thread) */ 341 327 #ifdef CONFIG_TIMERLAT_TRACER 342 328 u64 timerlat_period; /* timerlat period */ 329 + u64 timerlat_align_us; /* timerlat alignment */ 343 330 u64 print_stack; /* print IRQ stack if total > */ 344 331 int timerlat_tracer; /* timerlat tracer */ 345 332 #endif ··· 353 338 #ifdef CONFIG_TIMERLAT_TRACER 354 339 .print_stack = 0, 355 340 .timerlat_period = DEFAULT_TIMERLAT_PERIOD, 341 + .timerlat_align_us = 0, 356 342 .timerlat_tracer = 0, 357 343 #endif 358 344 }; ··· 1846 1830 tlat->abs_period = (u64) ktime_to_ns(next_abs_period); 1847 1831 1848 1832 /* 1833 + * Align thread in the first cycle on each CPU to the set alignment 1834 + * if TIMERLAT_ALIGN is set. 1835 + * 1836 + * This is done by using an atomic64_t to store the next absolute period. 1837 + * The first thread that wakes up will set the atomic64_t to its 1838 + * absolute period, and the other threads will increment it by 1839 + * the alignment value. 1840 + */ 1841 + if (test_bit(OSN_TIMERLAT_ALIGN, &osnoise_options) && !tlat->count 1842 + && atomic64_cmpxchg_relaxed(&align_next, 0, tlat->abs_period)) { 1843 + /* 1844 + * A thread has already set align_next, use it and increment it 1845 + * to be used by the next thread that wakes up after this one. 1846 + */ 1847 + tlat->abs_period = atomic64_add_return_relaxed( 1848 + osnoise_data.timerlat_align_us * 1000, &align_next); 1849 + next_abs_period = ns_to_ktime(tlat->abs_period); 1850 + } 1851 + 1852 + /* 1849 1853 * If the new abs_period is in the past, skip the activation. 1850 1854 */ 1851 1855 while (ktime_compare(now, next_abs_period) > 0) { ··· 2686 2650 .min = &timerlat_min_period, 2687 2651 }; 2688 2652 2653 + /* 2654 + * osnoise/timerlat_align_us: align the first wakeup of all timerlat 2655 + * threads to a common boundary (in us). 0 means disabled. 2656 + */ 2657 + static struct trace_min_max_param timerlat_align_us = { 2658 + .lock = &interface_lock, 2659 + .val = &osnoise_data.timerlat_align_us, 2660 + .max = NULL, 2661 + .min = NULL, 2662 + }; 2663 + 2689 2664 static const struct file_operations timerlat_fd_fops = { 2690 2665 .open = timerlat_fd_open, 2691 2666 .read = timerlat_fd_read, ··· 2790 2743 2791 2744 tmp = tracefs_create_file("timerlat_period_us", TRACE_MODE_WRITE, top_dir, 2792 2745 &timerlat_period, &trace_min_max_fops); 2746 + if (!tmp) 2747 + return -ENOMEM; 2748 + 2749 + tmp = tracefs_create_file("timerlat_align_us", TRACE_MODE_WRITE, top_dir, 2750 + &timerlat_align_us, &trace_min_max_fops); 2793 2751 if (!tmp) 2794 2752 return -ENOMEM; 2795 2753