@@ -44,6 +44,7 @@ static int cmd_help;
44
44
static int force_online_offline ;
45
45
static int auto_mode ;
46
46
static int fact_enable_fail ;
47
+ static int cgroupv2 ;
47
48
48
49
/* clos related */
49
50
static int current_clos = -1 ;
@@ -834,7 +835,137 @@ int find_phy_core_num(int logical_cpu)
834
835
return - EINVAL ;
835
836
}
836
837
838
+ int use_cgroupv2 (void )
839
+ {
840
+ return cgroupv2 ;
841
+ }
842
+
843
+ int enable_cpuset_controller (void )
844
+ {
845
+ int fd , ret ;
846
+
847
+ fd = open ("/sys/fs/cgroup/cgroup.subtree_control" , O_RDWR , 0 );
848
+ if (fd < 0 ) {
849
+ debug_printf ("Can't activate cpuset controller\n" );
850
+ debug_printf ("Either you are not root user or CGroup v2 is not supported\n" );
851
+ return fd ;
852
+ }
853
+
854
+ ret = write (fd , " +cpuset" , strlen (" +cpuset" ));
855
+ close (fd );
856
+
857
+ if (ret == -1 ) {
858
+ debug_printf ("Can't activate cpuset controller: Write failed\n" );
859
+ return ret ;
860
+ }
861
+
862
+ return 0 ;
863
+ }
864
+
865
+ int isolate_cpus (struct isst_id * id , int mask_size , cpu_set_t * cpu_mask , int level )
866
+ {
867
+ int i , first , curr_index , index , ret , fd ;
868
+ static char str [512 ], dir_name [64 ];
869
+ static char cpuset_cpus [128 ];
870
+ int str_len = sizeof (str );
871
+ DIR * dir ;
872
+
873
+ snprintf (dir_name , sizeof (dir_name ), "/sys/fs/cgroup/%d-%d-%d" , id -> pkg , id -> die , id -> punit );
874
+ dir = opendir (dir_name );
875
+ if (!dir ) {
876
+ ret = mkdir (dir_name , 0744 );
877
+ if (ret ) {
878
+ debug_printf ("Can't create dir:%s errno:%d\n" , dir_name , errno );
879
+ return ret ;
880
+ }
881
+ }
882
+ closedir (dir );
883
+
884
+ if (!level ) {
885
+ sprintf (cpuset_cpus , "%s/cpuset.cpus.partition" , dir_name );
886
+
887
+ fd = open (cpuset_cpus , O_RDWR , 0 );
888
+ if (fd < 0 ) {
889
+ return fd ;
890
+ }
891
+
892
+ ret = write (fd , "member" , strlen ("member" ));
893
+ if (ret == -1 ) {
894
+ printf ("Can't update to member\n" );
895
+ return ret ;
896
+ }
897
+
898
+ return 0 ;
899
+ }
900
+
901
+ if (!CPU_COUNT_S (mask_size , cpu_mask )) {
902
+ return -1 ;
903
+ }
837
904
905
+ curr_index = 0 ;
906
+ first = 1 ;
907
+ str [0 ] = '\0' ;
908
+ for (i = 0 ; i < get_topo_max_cpus (); ++ i ) {
909
+ if (!is_cpu_in_power_domain (i , id ))
910
+ continue ;
911
+
912
+ if (CPU_ISSET_S (i , mask_size , cpu_mask ))
913
+ continue ;
914
+
915
+ if (!first ) {
916
+ index = snprintf (& str [curr_index ],
917
+ str_len - curr_index , "," );
918
+ curr_index += index ;
919
+ if (curr_index >= str_len )
920
+ break ;
921
+ }
922
+ index = snprintf (& str [curr_index ], str_len - curr_index , "%d" ,
923
+ i );
924
+ curr_index += index ;
925
+ if (curr_index >= str_len )
926
+ break ;
927
+ first = 0 ;
928
+ }
929
+
930
+ debug_printf ("isolated CPUs list: package:%d curr_index:%d [%s]\n" , id -> pkg , curr_index ,str );
931
+
932
+ snprintf (cpuset_cpus , sizeof (cpuset_cpus ), "%s/cpuset.cpus" , dir_name );
933
+
934
+ fd = open (cpuset_cpus , O_RDWR , 0 );
935
+ if (fd < 0 ) {
936
+ return fd ;
937
+ }
938
+
939
+ ret = write (fd , str , strlen (str ));
940
+ close (fd );
941
+
942
+ if (ret == -1 ) {
943
+ debug_printf ("Can't activate cpuset controller: Write failed\n" );
944
+ return ret ;
945
+ }
946
+
947
+ snprintf (cpuset_cpus , sizeof (cpuset_cpus ), "%s/cpuset.cpus.partition" , dir_name );
948
+
949
+ fd = open (cpuset_cpus , O_RDWR , 0 );
950
+ if (fd < 0 ) {
951
+ return fd ;
952
+ }
953
+
954
+ ret = write (fd , "isolated" , strlen ("isolated" ));
955
+ if (ret == -1 ) {
956
+ debug_printf ("Can't update to isolated\n" );
957
+ ret = write (fd , "root" , strlen ("root" ));
958
+ if (ret == -1 )
959
+ debug_printf ("Can't update to root\n" );
960
+ }
961
+
962
+ close (fd );
963
+
964
+ if (ret < 0 )
965
+ return ret ;
966
+
967
+ return 0 ;
968
+ }
838
969
839
970
static int isst_fill_platform_info (void )
840
971
{
@@ -1273,6 +1404,23 @@ static void set_tdp_level_for_cpu(struct isst_id *id, void *arg1, void *arg2, vo
1273
1404
isst_display_error_info_message (1 , "Can't get coremask, online/offline option is ignored" , 0 , 0 );
1274
1405
goto free_mask ;
1275
1406
}
1407
+
1408
+ if (use_cgroupv2 ()) {
1409
+ int ret ;
1410
+
1411
+ fprintf (stderr , "Using cgroup v2 in lieu of online/offline\n" );
1412
+ ret = enable_cpuset_controller ();
1413
+ if (ret )
1414
+ goto use_offline ;
1415
+
1416
+ ret = isolate_cpus (id , ctdp_level .core_cpumask_size , ctdp_level .core_cpumask , tdp_level );
1417
+ if (ret )
1418
+ goto use_offline ;
1419
+
1420
+ goto free_mask ;
1421
+ }
1422
+
1423
+ use_offline :
1276
1424
if (ctdp_level .cpu_count ) {
1277
1425
int i , max_cpus = get_topo_max_cpus ();
1278
1426
for (i = 0 ; i < max_cpus ; ++ i ) {
@@ -2787,6 +2935,7 @@ static void usage(void)
2787
2935
printf ("\t[-b|--oob : Start a daemon to process HFI events for perf profile change from Out of Band agent.\n" );
2788
2936
printf ("\t[-n|--no-daemon : Don't run as daemon. By default --oob will turn on daemon mode\n" );
2789
2937
printf ("\t[-w|--delay : Delay for reading config level state change in OOB poll mode.\n" );
2938
+ printf ("\t[-g|--cgroupv2 : Try to use cgroup v2 CPU isolation instead of CPU online/offline.\n" );
2790
2939
printf ("\nResult format\n" );
2791
2940
printf ("\tResult display uses a common format for each command:\n" );
2792
2941
printf ("\tResults are formatted in text/JSON with\n" );
@@ -2839,6 +2988,7 @@ static void cmdline(int argc, char **argv)
2839
2988
{ "oob" , no_argument , 0 , 'b' },
2840
2989
{ "no-daemon" , no_argument , 0 , 'n' },
2841
2990
{ "poll-interval" , required_argument , 0 , 'w' },
2991
+ { "cgroupv2" , required_argument , 0 , 'g' },
2842
2992
{ 0 , 0 , 0 , 0 }
2843
2993
};
2844
2994
@@ -2869,7 +3019,7 @@ static void cmdline(int argc, char **argv)
2869
3019
goto out ;
2870
3020
2871
3021
progname = argv [0 ];
2872
- while ((opt = getopt_long_only (argc , argv , "+c:df:hio:vabw:n " , long_options ,
3022
+ while ((opt = getopt_long_only (argc , argv , "+c:df:hio:vabw:ng " , long_options ,
2873
3023
& option_index )) != -1 ) {
2874
3024
switch (opt ) {
2875
3025
case 'a' :
@@ -2928,6 +3078,9 @@ static void cmdline(int argc, char **argv)
2928
3078
}
2929
3079
poll_interval = ret ;
2930
3080
break ;
3081
+ case 'g' :
3082
+ cgroupv2 = 1 ;
3083
+ break ;
2931
3084
default :
2932
3085
usage ();
2933
3086
}
0 commit comments