@@ -44,6 +44,7 @@ struct timerlat_top_params {
44
44
int hk_cpus ;
45
45
int user_top ;
46
46
int user_workload ;
47
+ int kernel_workload ;
47
48
int pretty_output ;
48
49
int warmup ;
49
50
cpu_set_t hk_cpu_set ;
@@ -445,7 +446,7 @@ static void timerlat_top_usage(char *usage)
445
446
"" ,
446
447
" usage: rtla timerlat [top] [-h] [-q] [-a us] [-d s] [-D] [-n] [-p us] [-i us] [-T us] [-s us] \\" ,
447
448
" [[-t[=file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\" ,
448
- " [-P priority] [--dma-latency us] [--aa-only us] [-C[=cgroup_name]] [-u] [--warm-up s]" ,
449
+ " [-P priority] [--dma-latency us] [--aa-only us] [-C[=cgroup_name]] [-u|-k ] [--warm-up s]" ,
449
450
"" ,
450
451
" -h/--help: print this menu" ,
451
452
" -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit" ,
@@ -474,7 +475,8 @@ static void timerlat_top_usage(char *usage)
474
475
" f:prio - use SCHED_FIFO with prio" ,
475
476
" d:runtime[us|ms|s]:period[us|ms|s] - use SCHED_DEADLINE with runtime and period" ,
476
477
" in nanoseconds" ,
477
- " -u/--user-threads: use rtla user-space threads instead of in-kernel timerlat threads" ,
478
+ " -u/--user-threads: use rtla user-space threads instead of kernel-space timerlat threads" ,
479
+ " -k/--kernel-threads: use timerlat kernel-space threads instead of rtla user-space threads" ,
478
480
" -U/--user-load: enable timerlat for user-defined user-space workload" ,
479
481
" --warm-up s: let the workload run for s seconds before collecting data" ,
480
482
NULL ,
@@ -536,6 +538,7 @@ static struct timerlat_top_params
536
538
{"thread" , required_argument , 0 , 'T' },
537
539
{"trace" , optional_argument , 0 , 't' },
538
540
{"user-threads" , no_argument , 0 , 'u' },
541
+ {"kernel-threads" , no_argument , 0 , 'k' },
539
542
{"user-load" , no_argument , 0 , 'U' },
540
543
{"trigger" , required_argument , 0 , '0' },
541
544
{"filter" , required_argument , 0 , '1' },
@@ -550,7 +553,7 @@ static struct timerlat_top_params
550
553
/* getopt_long stores the option index here. */
551
554
int option_index = 0 ;
552
555
553
- c = getopt_long (argc , argv , "a:c:C::d:De:hH:i:np :P:qs:t::T:uU0:1:2:345:6:" ,
556
+ c = getopt_long (argc , argv , "a:c:C::d:De:hH:i:knp :P:qs:t::T:uU0:1:2:345:6:" ,
554
557
long_options , & option_index );
555
558
556
559
/* detect the end of the options. */
@@ -635,6 +638,9 @@ static struct timerlat_top_params
635
638
case 'i' :
636
639
params -> stop_us = get_llong_from_str (optarg );
637
640
break ;
641
+ case 'k' :
642
+ params -> kernel_workload = true;
643
+ break ;
638
644
case 'n' :
639
645
params -> output_divisor = 1 ;
640
646
break ;
@@ -729,6 +735,9 @@ static struct timerlat_top_params
729
735
if (params -> no_aa && params -> aa_only )
730
736
timerlat_top_usage ("--no-aa and --aa-only are mutually exclusive!" );
731
737
738
+ if (params -> kernel_workload && params -> user_workload )
739
+ timerlat_top_usage ("--kernel-threads and --user-threads are mutually exclusive!" );
740
+
732
741
return params ;
733
742
}
734
743
@@ -807,6 +816,22 @@ timerlat_top_apply_config(struct osnoise_tool *top, struct timerlat_top_params *
807
816
auto_house_keeping (& params -> monitored_cpus );
808
817
}
809
818
819
+ /*
820
+ * If the user did not specify a type of thread, try user-threads first.
821
+ * Fall back to kernel threads otherwise.
822
+ */
823
+ if (!params -> kernel_workload && !params -> user_workload ) {
824
+ retval = tracefs_file_exists (NULL , "osnoise/per_cpu/cpu0/timerlat_fd" );
825
+ if (retval ) {
826
+ debug_msg ("User-space interface detected, setting user-threads\n" );
827
+ params -> user_workload = 1 ;
828
+ params -> user_top = 1 ;
829
+ } else {
830
+ debug_msg ("User-space interface not detected, setting kernel-threads\n" );
831
+ params -> kernel_workload = 1 ;
832
+ }
833
+ }
834
+
810
835
if (params -> user_top ) {
811
836
retval = osnoise_set_workload (top -> context , 0 );
812
837
if (retval ) {
0 commit comments