@@ -55,6 +55,7 @@ struct timerlat_hist_params {
5555 int entries ;
5656 int warmup ;
5757 int buffer_size ;
58+ int deepest_idle_state ;
5859};
5960
6061struct timerlat_hist_cpu {
@@ -655,7 +656,7 @@ static void timerlat_hist_usage(char *usage)
655656 " [-t[file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\" ,
656657 " [-P priority] [-E N] [-b N] [--no-irq] [--no-thread] [--no-header] [--no-summary] \\" ,
657658 " [--no-index] [--with-zeros] [--dma-latency us] [-C[=cgroup_name]] [--no-aa] [--dump-task] [-u|-k]" ,
658- " [--warm-up s]" ,
659+ " [--warm-up s] [--deepest-idle-state n] " ,
659660 "" ,
660661 " -h/--help: print this menu" ,
661662 " -a/--auto: set automatic trace mode, stopping the session if argument in us latency is hit" ,
@@ -695,6 +696,7 @@ static void timerlat_hist_usage(char *usage)
695696 " -U/--user-load: enable timerlat for user-defined user-space workload" ,
696697 " --warm-up s: let the workload run for s seconds before collecting data" ,
697698 " --trace-buffer-size kB: set the per-cpu trace buffer size in kB" ,
699+ " --deepest-idle-state n: only go down to idle state n on cpus used by timerlat to reduce exit from idle latency" ,
698700 NULL ,
699701 };
700702
@@ -732,6 +734,9 @@ static struct timerlat_hist_params
732734 /* disabled by default */
733735 params -> dma_latency = -1 ;
734736
737+ /* disabled by default */
738+ params -> deepest_idle_state = -2 ;
739+
735740 /* display data in microseconds */
736741 params -> output_divisor = 1000 ;
737742 params -> bucket_size = 1 ;
@@ -772,6 +777,7 @@ static struct timerlat_hist_params
772777 {"dump-task" , no_argument , 0 , '\1' },
773778 {"warm-up" , required_argument , 0 , '\2' },
774779 {"trace-buffer-size" , required_argument , 0 , '\3' },
780+ {"deepest-idle-state" , required_argument , 0 , '\4' },
775781 {0 , 0 , 0 , 0 }
776782 };
777783
@@ -960,6 +966,9 @@ static struct timerlat_hist_params
960966 case '\3' :
961967 params -> buffer_size = get_llong_from_str (optarg );
962968 break ;
969+ case '\4' :
970+ params -> deepest_idle_state = get_llong_from_str (optarg );
971+ break ;
963972 default :
964973 timerlat_hist_usage ("Invalid option" );
965974 }
@@ -1152,6 +1161,7 @@ int timerlat_hist_main(int argc, char *argv[])
11521161 int return_value = 1 ;
11531162 pthread_t timerlat_u ;
11541163 int retval ;
1164+ int nr_cpus , i ;
11551165
11561166 params = timerlat_hist_parse_args (argc , argv );
11571167 if (!params )
@@ -1201,6 +1211,28 @@ int timerlat_hist_main(int argc, char *argv[])
12011211 }
12021212 }
12031213
1214+ if (params -> deepest_idle_state >= -1 ) {
1215+ if (!have_libcpupower_support ()) {
1216+ err_msg ("rtla built without libcpupower, --deepest-idle-state is not supported\n" );
1217+ goto out_free ;
1218+ }
1219+
1220+ nr_cpus = sysconf (_SC_NPROCESSORS_CONF );
1221+
1222+ for (i = 0 ; i < nr_cpus ; i ++ ) {
1223+ if (params -> cpus && !CPU_ISSET (i , & params -> monitored_cpus ))
1224+ continue ;
1225+ if (save_cpu_idle_disable_state (i ) < 0 ) {
1226+ err_msg ("Could not save cpu idle state.\n" );
1227+ goto out_free ;
1228+ }
1229+ if (set_deepest_cpu_idle_state (i , params -> deepest_idle_state ) < 0 ) {
1230+ err_msg ("Could not set deepest cpu idle state.\n" );
1231+ goto out_free ;
1232+ }
1233+ }
1234+ }
1235+
12041236 if (params -> trace_output ) {
12051237 record = osnoise_init_trace_tool ("timerlat" );
12061238 if (!record ) {
@@ -1332,6 +1364,13 @@ int timerlat_hist_main(int argc, char *argv[])
13321364 timerlat_aa_destroy ();
13331365 if (dma_latency_fd >= 0 )
13341366 close (dma_latency_fd );
1367+ if (params -> deepest_idle_state >= -1 ) {
1368+ for (i = 0 ; i < nr_cpus ; i ++ ) {
1369+ if (params -> cpus && !CPU_ISSET (i , & params -> monitored_cpus ))
1370+ continue ;
1371+ restore_cpu_idle_disable_state (i );
1372+ }
1373+ }
13351374 trace_events_destroy (& record -> trace , params -> events );
13361375 params -> events = NULL ;
13371376out_free :
@@ -1340,6 +1379,7 @@ int timerlat_hist_main(int argc, char *argv[])
13401379 osnoise_destroy_tool (record );
13411380 osnoise_destroy_tool (tool );
13421381 free (params );
1382+ free_cpu_idle_disable_states ();
13431383out_exit :
13441384 exit (return_value );
13451385}
0 commit comments