20
20
#include <assert.h>
21
21
#include <pthread.h>
22
22
#include <sys/ioctl.h>
23
+ #include <sys/ptrace.h>
24
+ #include <sys/wait.h>
23
25
#ifdef HAVE_LINUX_PERF_EVENT_H
24
26
#include <linux/perf_event.h>
25
27
#endif
@@ -483,15 +485,61 @@ int do_smt(char *state)
483
485
return rc ;
484
486
}
485
487
486
- int do_dscr (char * state )
488
+ #define PTRACE_DSCR 44
489
+
490
+ int do_dscr_pid (int dscr_state , pid_t pid )
491
+ {
492
+ int rc ;
493
+
494
+ rc = ptrace (PTRACE_ATTACH , pid , NULL , NULL );
495
+ if (rc ) {
496
+ fprintf (stderr , "Could not attach to process %d to %s the "
497
+ "DSCR value\n%s\n" , pid , (dscr_state ? "set" : "get" ),
498
+ strerror (errno ));
499
+ return rc ;
500
+ }
501
+
502
+ wait (NULL );
503
+
504
+ if (dscr_state ) {
505
+ rc = ptrace (PTRACE_POKEUSER , pid , PTRACE_DSCR << 3 , dscr_state );
506
+ if (rc ) {
507
+ fprintf (stderr , "Could not set the DSCR value for pid "
508
+ "%d\n%s\n" , pid , strerror (errno ));
509
+ ptrace (PTRACE_DETACH , pid , NULL , NULL );
510
+ return rc ;
511
+ }
512
+ }
513
+
514
+ rc = ptrace (PTRACE_PEEKUSER , pid , PTRACE_DSCR << 3 , NULL );
515
+ if (errno ) {
516
+ fprintf (stderr , "Could not get the DSCR value for pid "
517
+ "%d\n%s\n" , pid , strerror (errno ));
518
+ rc = -1 ;
519
+ } else {
520
+ printf ("DSCR for pid %d is %d\n" , pid , rc );
521
+ }
522
+
523
+ ptrace (PTRACE_DETACH , pid , NULL , NULL );
524
+ return rc ;
525
+ }
526
+
527
+ int do_dscr (char * state , pid_t pid )
487
528
{
488
529
int rc = 0 ;
530
+ int dscr_state = 0 ;
489
531
490
532
if (!is_dscr_capable ()) {
491
533
fprintf (stderr , "Machine is not DSCR capable\n" );
492
534
return -1 ;
493
535
}
494
536
537
+ if (state )
538
+ dscr_state = strtol (state , NULL , 0 );
539
+
540
+ if (pid != -1 )
541
+ return do_dscr_pid (dscr_state , pid );
542
+
495
543
if (!state ) {
496
544
int dscr ;
497
545
@@ -504,11 +552,11 @@ int do_dscr(char *state)
504
552
if (dscr == -1 )
505
553
printf ("Inconsistent DSCR\n" );
506
554
else
507
- printf ("dscr is %d\n" , dscr );
555
+ printf ("DSCR is %d\n" , dscr );
508
556
break ;
509
557
}
510
558
} else
511
- rc = set_dscr (strtol ( state , NULL , 0 ) );
559
+ rc = set_dscr (dscr_state );
512
560
513
561
return rc ;
514
562
}
@@ -908,20 +956,23 @@ int do_cores_online(char *state)
908
956
909
957
void usage (void )
910
958
{
911
- printf ("\tppc64_cpu --smt # Get current SMT state\n"
912
- "\tppc64_cpu --smt={on|off} # Turn SMT on/off\n"
913
- "\tppc64_cpu --smt=X # Set SMT state to X\n\n"
914
- "\tppc64_cpu --cores-present # Get the number of cores installed\n"
915
- "\tppc64_cpu --cores-on # Get the number of cores currently online\n"
916
- "\tppc64_cpu --cores-on=X # Put exactly X cores online\n\n"
917
-
918
- "\tppc64_cpu --dscr # Get current DSCR setting\n"
919
- "\tppc64_cpu --dscr=<val> # Change DSCR setting\n\n"
920
- "\tppc64_cpu --smt-snooze-delay # Get current smt-snooze-delay setting\n"
921
- "\tppc64_cpu --smt-snooze-delay=<val> # Change smt-snooze-delay setting\n\n"
922
- "\tppc64_cpu --run-mode # Get current diagnostics run mode\n"
923
- "\tppc64_cpu --run-mode=<val> # Set current diagnostics run mode\n\n"
924
- "\tppc64_cpu --frequency # Determine cpu frequency.\n\n" );
959
+ printf (
960
+ "Usage: ppc64_cpu [command] [options]\n"
961
+ "ppc64_cpu --smt # Get current SMT state\n"
962
+ "ppc64_cpu --smt={on|off} # Turn SMT on/off\n"
963
+ "ppc64_cpu --smt=X # Set SMT state to X\n\n"
964
+ "ppc64_cpu --cores-present # Get the number of cores present\n"
965
+ "ppc64_cpu --cores-on # Get the number of cores currently online\n"
966
+ "ppc64_cpu --cores-on=X # Put exactly X cores online\n\n"
967
+ "ppc64_cpu --dscr # Get current DSCR system setting\n"
968
+ "ppc64_cpu --dscr=<val> # Change DSCR system setting\n"
969
+ "ppc64_cpu --dscr [-p <pid>] # Get DSCR setting for process <pid>\n"
970
+ "ppc64_cpu --dscr=<val> [-p <pid>] # Change DSCR setting for process <pid>\n\n"
971
+ "ppc64_cpu --smt-snooze-delay # Get current smt-snooze-delay setting\n"
972
+ "ppc64_cpu --smt-snooze-delay=<val> # Change smt-snooze-delay setting\n\n"
973
+ "ppc64_cpu --run-mode # Get current diagnostics run mode\n"
974
+ "ppc64_cpu --run-mode=<val> # Set current diagnostics run mode\n\n"
975
+ "ppc64_cpu --frequency # Determine cpu frequency.\n\n" );
925
976
}
926
977
927
978
struct option longopts [] = {
@@ -939,8 +990,11 @@ struct option longopts[] = {
939
990
int main (int argc , char * argv [])
940
991
{
941
992
int rc = 0 ;
993
+ char * action ;
994
+ char * action_arg = NULL ;
995
+ char * equal_char ;
942
996
int opt ;
943
- int option_index ;
997
+ pid_t pid = -1 ;
944
998
945
999
if (argc == 1 ) {
946
1000
usage ();
@@ -953,47 +1007,67 @@ int main(int argc, char *argv[])
953
1007
return rc ;
954
1008
}
955
1009
956
- while ( 1 ) {
957
- opt = getopt_long ( argc , argv , "s::d::S::r::fCVc::" , longopts ,
958
- & option_index );
959
- if ( opt == -1 )
960
- break ;
1010
+ /* The first arg is the action to be taken with an optional action
1011
+ * arg in the form --action=XXX. Parse this out so we can call the
1012
+ * appropriate action.
1013
+ */
1014
+ action = argv [ 1 ] ;
961
1015
962
- switch (opt ) {
963
- case 's' :
964
- rc = do_smt (optarg );
965
- break ;
966
-
967
- case 'd' :
968
- rc = do_dscr (optarg );
969
- break ;
1016
+ /* skipp past the '--' */
1017
+ action += 2 ;
970
1018
971
- case 'S' :
972
- rc = do_smt_snooze_delay (optarg );
973
- break ;
1019
+ equal_char = strchr (action , '=' );
1020
+ if (equal_char ) {
1021
+ * equal_char = '\0' ;
1022
+ action_arg = equal_char + 1 ;
1023
+ }
974
1024
975
- case 'r' :
976
- rc = do_run_mode (optarg );
1025
+ /* Now parse out any additional options. Currently there is only
1026
+ * the -p <pid> option for the --dscr action.
1027
+ */
1028
+ optind = 2 ;
1029
+ while (1 ) {
1030
+ opt = getopt (argc , argv , "p:" );
1031
+ if (opt == -1 )
977
1032
break ;
978
1033
979
- case 'f' :
980
- rc = do_cpu_frequency ();
981
- break ;
1034
+ switch (opt ) {
1035
+ case 'p' :
1036
+ /* only valid for do_dscr option */
1037
+ if (strcmp (action , "dscr" )) {
1038
+ fprintf (stderr , "The p option is only valid "
1039
+ "with the --dscr option\n" );
1040
+ usage ();
1041
+ exit (-1 );
1042
+ }
982
1043
983
- case 'C' :
984
- rc = do_cores_present (optarg );
1044
+ pid = atoi (optarg );
985
1045
break ;
986
- case 'c' :
987
- rc = do_cores_online (optarg );
988
- break ;
989
- case 'V' :
990
- printf ("ppc64_cpu: version %s\n" , PPC64_CPU_VERSION );
991
- break ;
992
- default :
1046
+ default :
1047
+ fprintf (stderr , "%c is not a valid option\n" , opt );
993
1048
usage ();
994
- break ;
1049
+ exit ( -1 ) ;
995
1050
}
996
1051
}
997
1052
1053
+ if (!strcmp (action , "smt" ))
1054
+ rc = do_smt (action_arg );
1055
+ else if (!strcmp (action , "dscr" ))
1056
+ rc = do_dscr (action_arg , pid );
1057
+ else if (!strcmp (action , "smt-snooze-delay" ))
1058
+ rc = do_smt_snooze_delay (action_arg );
1059
+ else if (!strcmp (action , "run-mode" ))
1060
+ rc = do_run_mode (action_arg );
1061
+ else if (!strcmp (action , "frequency" ))
1062
+ rc = do_cpu_frequency ();
1063
+ else if (!strcmp (action , "cores-present" ))
1064
+ rc = do_cores_present (action_arg );
1065
+ else if (!strcmp (action , "cores-on" ))
1066
+ rc = do_cores_online (action_arg );
1067
+ else if (!strcmp (action , "version" ))
1068
+ printf ("ppc64_cpu: version %s\n" , PPC64_CPU_VERSION );
1069
+ else
1070
+ usage ();
1071
+
998
1072
return rc ;
999
1073
}
0 commit comments