@@ -92,6 +92,9 @@ unsigned int has_hwp_request_pkg; /* IA32_HWP_REQUEST_PKG */
9292
9393unsigned int bdx_highest_ratio ;
9494
95+ #define PATH_TO_CPU "/sys/devices/system/cpu/"
96+ #define SYSFS_PATH_MAX 255
97+
9598/*
9699 * maintain compatibility with original implementation, but don't document it:
97100 */
@@ -669,6 +672,48 @@ int put_msr(int cpu, int offset, unsigned long long new_msr)
669672 return 0 ;
670673}
671674
675+ static unsigned int read_sysfs (const char * path , char * buf , size_t buflen )
676+ {
677+ ssize_t numread ;
678+ int fd ;
679+
680+ fd = open (path , O_RDONLY );
681+ if (fd == -1 )
682+ return 0 ;
683+
684+ numread = read (fd , buf , buflen - 1 );
685+ if (numread < 1 ) {
686+ close (fd );
687+ return 0 ;
688+ }
689+
690+ buf [numread ] = '\0' ;
691+ close (fd );
692+
693+ return (unsigned int ) numread ;
694+ }
695+
696+ static unsigned int write_sysfs (const char * path , char * buf , size_t buflen )
697+ {
698+ ssize_t numwritten ;
699+ int fd ;
700+
701+ fd = open (path , O_WRONLY );
702+ if (fd == -1 )
703+ return 0 ;
704+
705+ numwritten = write (fd , buf , buflen - 1 );
706+ if (numwritten < 1 ) {
707+ perror ("write failed\n" );
708+ close (fd );
709+ return -1 ;
710+ }
711+
712+ close (fd );
713+
714+ return (unsigned int ) numwritten ;
715+ }
716+
672717void print_hwp_cap (int cpu , struct msr_hwp_cap * cap , char * str )
673718{
674719 if (cpu != -1 )
@@ -746,17 +791,61 @@ void write_hwp_request(int cpu, struct msr_hwp_request *hwp_req, unsigned int ms
746791 put_msr (cpu , msr_offset , msr );
747792}
748793
794+ static int get_epb (int cpu )
795+ {
796+ char path [SYSFS_PATH_MAX ];
797+ char linebuf [3 ];
798+ char * endp ;
799+ long val ;
800+
801+ if (!has_epb )
802+ return -1 ;
803+
804+ snprintf (path , sizeof (path ), PATH_TO_CPU "cpu%u/power/energy_perf_bias" , cpu );
805+
806+ if (!read_sysfs (path , linebuf , 3 ))
807+ return -1 ;
808+
809+ val = strtol (linebuf , & endp , 0 );
810+ if (endp == linebuf || errno == ERANGE )
811+ return -1 ;
812+
813+ return (int )val ;
814+ }
815+
816+ static int set_epb (int cpu , int val )
817+ {
818+ char path [SYSFS_PATH_MAX ];
819+ char linebuf [3 ];
820+ char * endp ;
821+ int ret ;
822+
823+ if (!has_epb )
824+ return -1 ;
825+
826+ snprintf (path , sizeof (path ), PATH_TO_CPU "cpu%u/power/energy_perf_bias" , cpu );
827+ snprintf (linebuf , sizeof (linebuf ), "%d" , val );
828+
829+ ret = write_sysfs (path , linebuf , 3 );
830+ if (ret <= 0 )
831+ return -1 ;
832+
833+ val = strtol (linebuf , & endp , 0 );
834+ if (endp == linebuf || errno == ERANGE )
835+ return -1 ;
836+
837+ return (int )val ;
838+ }
839+
749840int print_cpu_msrs (int cpu )
750841{
751- unsigned long long msr ;
752842 struct msr_hwp_request req ;
753843 struct msr_hwp_cap cap ;
844+ int epb ;
754845
755- if (has_epb ) {
756- get_msr (cpu , MSR_IA32_ENERGY_PERF_BIAS , & msr );
757-
758- printf ("cpu%d: EPB %u\n" , cpu , (unsigned int ) msr );
759- }
846+ epb = get_epb (cpu );
847+ if (epb >= 0 )
848+ printf ("cpu%d: EPB %u\n" , cpu , (unsigned int ) epb );
760849
761850 if (!has_hwp )
762851 return 0 ;
@@ -1039,15 +1128,15 @@ int enable_hwp_on_cpu(int cpu)
10391128int update_cpu_msrs (int cpu )
10401129{
10411130 unsigned long long msr ;
1042-
1131+ int epb ;
10431132
10441133 if (update_epb ) {
1045- get_msr ( cpu , MSR_IA32_ENERGY_PERF_BIAS , & msr );
1046- put_msr (cpu , MSR_IA32_ENERGY_PERF_BIAS , new_epb );
1134+ epb = get_epb ( cpu );
1135+ set_epb (cpu , new_epb );
10471136
10481137 if (verbose )
10491138 printf ("cpu%d: ENERGY_PERF_BIAS old: %d new: %d\n" ,
1050- cpu , ( unsigned int ) msr , (unsigned int ) new_epb );
1139+ cpu , epb , (unsigned int ) new_epb );
10511140 }
10521141
10531142 if (update_turbo ) {
0 commit comments