@@ -55,6 +55,7 @@ struct timerlat_hist_params {
55
55
int entries ;
56
56
int warmup ;
57
57
int buffer_size ;
58
+ int deepest_idle_state ;
58
59
};
59
60
60
61
struct timerlat_hist_cpu {
@@ -655,7 +656,7 @@ static void timerlat_hist_usage(char *usage)
655
656
" [-t[file]] [-e sys[:event]] [--filter <filter>] [--trigger <trigger>] [-c cpu-list] [-H cpu-list]\\" ,
656
657
" [-P priority] [-E N] [-b N] [--no-irq] [--no-thread] [--no-header] [--no-summary] \\" ,
657
658
" [--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] " ,
659
660
"" ,
660
661
" -h/--help: print this menu" ,
661
662
" -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)
695
696
" -U/--user-load: enable timerlat for user-defined user-space workload" ,
696
697
" --warm-up s: let the workload run for s seconds before collecting data" ,
697
698
" --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" ,
698
700
NULL ,
699
701
};
700
702
@@ -732,6 +734,9 @@ static struct timerlat_hist_params
732
734
/* disabled by default */
733
735
params -> dma_latency = -1 ;
734
736
737
+ /* disabled by default */
738
+ params -> deepest_idle_state = -2 ;
739
+
735
740
/* display data in microseconds */
736
741
params -> output_divisor = 1000 ;
737
742
params -> bucket_size = 1 ;
@@ -772,6 +777,7 @@ static struct timerlat_hist_params
772
777
{"dump-task" , no_argument , 0 , '\1' },
773
778
{"warm-up" , required_argument , 0 , '\2' },
774
779
{"trace-buffer-size" , required_argument , 0 , '\3' },
780
+ {"deepest-idle-state" , required_argument , 0 , '\4' },
775
781
{0 , 0 , 0 , 0 }
776
782
};
777
783
@@ -960,6 +966,9 @@ static struct timerlat_hist_params
960
966
case '\3' :
961
967
params -> buffer_size = get_llong_from_str (optarg );
962
968
break ;
969
+ case '\4' :
970
+ params -> deepest_idle_state = get_llong_from_str (optarg );
971
+ break ;
963
972
default :
964
973
timerlat_hist_usage ("Invalid option" );
965
974
}
@@ -1152,6 +1161,7 @@ int timerlat_hist_main(int argc, char *argv[])
1152
1161
int return_value = 1 ;
1153
1162
pthread_t timerlat_u ;
1154
1163
int retval ;
1164
+ int nr_cpus , i ;
1155
1165
1156
1166
params = timerlat_hist_parse_args (argc , argv );
1157
1167
if (!params )
@@ -1201,6 +1211,28 @@ int timerlat_hist_main(int argc, char *argv[])
1201
1211
}
1202
1212
}
1203
1213
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
+
1204
1236
if (params -> trace_output ) {
1205
1237
record = osnoise_init_trace_tool ("timerlat" );
1206
1238
if (!record ) {
@@ -1332,6 +1364,13 @@ int timerlat_hist_main(int argc, char *argv[])
1332
1364
timerlat_aa_destroy ();
1333
1365
if (dma_latency_fd >= 0 )
1334
1366
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
+ }
1335
1374
trace_events_destroy (& record -> trace , params -> events );
1336
1375
params -> events = NULL ;
1337
1376
out_free :
@@ -1340,6 +1379,7 @@ int timerlat_hist_main(int argc, char *argv[])
1340
1379
osnoise_destroy_tool (record );
1341
1380
osnoise_destroy_tool (tool );
1342
1381
free (params );
1382
+ free_cpu_idle_disable_states ();
1343
1383
out_exit :
1344
1384
exit (return_value );
1345
1385
}
0 commit comments