diff --git a/config/pwrapi_msr.m4 b/config/pwrapi_msr.m4 new file mode 100644 index 00000000..5d2dbf69 --- /dev/null +++ b/config/pwrapi_msr.m4 @@ -0,0 +1,58 @@ + +AC_DEFUN([PWRAPI_CHECK_MSR], [ + AC_ARG_WITH([msr], [AS_HELP_STRING([--with-msr@<:@=DIR@:>@], [Use the msr binding in directory specified (DIR).])]) + + pwrapi_check_msr_happy="yes" + + CPPFLAGS_saved="$CPPFLAGS" + LDFLAGS_saved="$LDFLAGS" + LIBS_saved="$LIBS" + MSR_LIBS="" + + AS_IF([test -z "$with_msr"], + [MSR_CPPFLAGS= + MSR_LDFLAGS= + MSR_LIBS="-lmsr -lpthread" + LIBS="$LIBS $MSR_LIBS"], + [ AS_IF([test "x$with_msr" = "xyes"], + [MSR_CPPFLAGS= + MSR_LDFLAGS= + MSR_LIBS="-lmsr -lpthread" + LIBS="$LIBS $MSR_LIBS"], + [MSR_CPPFLAGS="-I$with_msr/include" + CPPFLAGS="$MSR_CPPFLAGS $CPPFLAGS" + MSR_LDFLAGS="-L$with_msr/lib" + LDFLAGS="$MSR_LDFLAGS $LDFLAGS" + MSR_LIBS="-lmsr -lpthread" + LIBS="$LIBS $MSR_LIBS"] + )] + ) + + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + + + AC_LINK_IFELSE([AC_LANG_PROGRAM([], [ + int a; + ])], [pwrapi_check_msr_lib_happy="yes"], + [pwrapi_check_msr_lib_happy="no"]) + + AS_IF([test "x$pwrapi_check_msr_lib_happy" = "xno"], + [pwrapi_check_msr_happy="no"]) + + AC_LANG_RESTORE + + CPPFLAGS="$CPPFLAGS_saved" + LDFLAGS="$LDFLAGS_saved" + LIBS="$LIBS_saved" + + AC_SUBST([MSR_CPPFLAGS]) + AC_SUBST([MSR_LDFLAGS]) + AC_SUBST([MSR_LIBS]) + + AM_CONDITIONAL([HAVE_MSR], [test "x$pwrapi_check_msr_happy" = "xyes"]) + AS_IF([test "x$pwrapi_check_msr_happy" = "xyes"], + [AC_DEFINE([HAVE_MSR], [1], [Set to 1 if msr is found during configuration])]) + + AS_IF([test "x$pwrapi_check_msr_happy" = "xyes"], [$1], [$2]) +]) diff --git a/configure.ac b/configure.ac index 33e6ab38..1531e936 100644 --- a/configure.ac +++ b/configure.ac @@ -38,6 +38,7 @@ m4_include([config/acx_mpi.m4]) m4_include([config/pwrapi_mpi.m4]) m4_include([config/pwrapi_hwloc.m4]) m4_include([config/pwrapi_mic.m4]) +m4_include([config/pwrapi_msr.m4]) m4_include([config/pwrapi_tx2mon.m4]) PWRAPI_CHECK_HWLOC([pwrapi_have_hwloc="yes"], [pwrapi_have_hwloc="no"]) @@ -49,9 +50,8 @@ PWRAPI_CHECK_POWERINSIGHT([pwrapi_have_powerinsight="yes"], [pwrapi_have_powerin PWRAPI_CHECK_POWERGADGET([pwrapi_have_powergadget="yes"], [pwrapi_have_powergadget="no"]) PWRAPI_CHECK_MPI([pwrapi_have_mpi="yes"], [pwrapi_have_mpi="no"]) - PWRAPI_CHECK_MIC([pwrapi_have_mic="yes"], [pwrapi_have_mic="no"]) - +PWRAPI_CHECK_MSR([pwrapi_have_msr="yes"], [pwrapi_have_msr="no"]) PWRAPI_CHECK_TX2MON([pwrapi_have_tx2mon="yes"], [pwrapi_have_tx2mon="no"]) PWRAPI_CHECK_DEBUG() @@ -62,6 +62,7 @@ AC_CONFIG_FILES([Makefile tools/script/hwloc_cpu_profile tools/script/hwloc_rapl_profile tools/script/hwloc_multi_profile + tools/script/hwloc_msr_profile tools/script/hwloc_astra_profile tools/script/hwloc_xt40_profile examples/script/xml_profile diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 0330e3d8..068c37fe 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -41,6 +41,14 @@ libpwr_micdev_la_CFLAGS = -I$(top_srcdir)/src/pwr $(MIC_INCLUDE) libpwr_micdev_la_LDFLAGS = -version-info 1:0:1 $(MIC_LDFLAGS) $(MIC_LIBS) endif +if HAVE_MSR +lib_LTLIBRARIES += libpwr_msrdev.la + +libpwr_msrdev_la_SOURCES = pwr_dev.c pwr_msrdev.c +libpwr_msrdev_la_CFLAGS = -I$(top_srcdir)/src/pwr $(MSR_CFLAGS) +libpwr_msrdev_la_LDFLAGS = -version-info 1:0:1 $(MSR_LDFLAGS) $(MSR_LIBS) +endif + if HAVE_TX2MON lib_LTLIBRARIES += libpwr_tx2mon.la diff --git a/src/plugins/README b/src/plugins/README index f5e77ae3..7e6cea22 100644 --- a/src/plugins/README +++ b/src/plugins/README @@ -25,15 +25,16 @@ Currently supported: libpwr_cpudev System level CPU adjustments libpwr_apmdev AMD Average Power Management libpwr_pmcdev IBM Power8 Power Management (INCOMPLETE) + libpwr_msrdev LIBMSR -Attributes PIAPI PI RAPL WU XTPM CPU APM PMC ----------- ----- -- ---- -- ---- --- --- --- - power G G G G G G - energy G G G G +Attributes PIAPI PI RAPL WU XTPM CPU APM PMC MSR +---------- ----- -- ---- -- ---- --- --- --- --- + power G G G G G G + energy G G G G G voltage G G G current G G G min_power G/S G/S - max_power G/S G/S + max_power G/S G/S G/S freq G/S temp G pstate G/S diff --git a/src/plugins/pwr_msrdev.c b/src/plugins/pwr_msrdev.c new file mode 100644 index 00000000..24375d50 --- /dev/null +++ b/src/plugins/pwr_msrdev.c @@ -0,0 +1,280 @@ +#include +#include "pwr_rapldev.h" +#include "pwr_dev.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pwr_msrdev.h" +typedef struct { + int fd; + double energy; +} pwr_msrdev_t; +typedef struct { + pwr_msrdev_t *dev; +} pwr_msrfd_t; +#define PWR_MSRFD(X) ((pwr_msrfd_t *)(X)) + + +static plugin_devops_t devops = { + .open = pwr_msrdev_open, + .close = pwr_msrdev_close, + .read = pwr_msrdev_read, + .write = pwr_msrdev_write, + .readv = pwr_msrdev_readv, + .writev = pwr_msrdev_writev, + .time = pwr_msrdev_time, + .clear = pwr_msrdev_clear, +#if 0 + .stat_get = pwr_dev_stat_get, + .stat_start = pwr_dev_stat_start, + .stat_stop = pwr_dev_stat_stop, + .stat_clear = pwr_dev_stat_clear, +#endif + .private_data = 0x0 +}; + + +static struct rapl_data *rdat; +static uint64_t *rflags; +plugin_devops_t *pwr_msrdev_init( const char *initstr ) +{ + int i; + + plugin_devops_t *dev = malloc( sizeof(plugin_devops_t) ); + + init_msr(); + rapl_init(&rdat, &rflags); + + *dev = devops; + dev->private_data = malloc( sizeof(pwr_msrdev_t) ); + bzero( dev->private_data, sizeof(pwr_msrdev_t) ); + return dev; +} + +int pwr_msrdev_final( plugin_devops_t *dev ) +{ + free( dev->private_data ); + free( dev ); + + return 0; +} +pwr_fd_t pwr_msrdev_open( plugin_devops_t *dev, const char *openstr ) +{ + pwr_msrfd_t *fd = malloc( sizeof(pwr_msrfd_t) ); + PWR_MSRFD(fd)->dev =(pwr_msrdev_t *)(dev->private_data); + PWR_MSRFD(fd)->dev->energy = 0.0; + return fd; +} +int pwr_msrdev_close( pwr_fd_t fd ) +{ + PWR_MSRFD(fd)->dev = 0x0; + free( fd ); + + return 0; +} + +int pwr_msrdev_read( pwr_fd_t fd, PWR_AttrName attr, void *value, unsigned int len, PWR_Time *timestamp ) +{ + int i; + double energy = 0.0; + double time = 0.0; + int policy = 0; +#ifndef USE_SYSTIME + struct timeval tv; +#endif + energy=PWR_MSRFD(fd)->dev->energy; + + if( len != sizeof(double) ) { + fprintf( stderr, "Error: value field size of %u incorrect, should be %ld\n", len, sizeof(double) ); + return -1; + } + poll_rapl_data(); + int snum = num_sockets(); + for(int s = 0; spkg_delta_joules[s]; //change to += to get total energy + } + double total; + switch( attr ) { + case PWR_ATTR_ENERGY: + *((double *)value) = energy; + break; + case PWR_ATTR_POWER_LIMIT_MAX: + total = 0; + for(int s = 0; sdev->energy=energy; +#ifndef USE_SYSTIME + gettimeofday( &tv, NULL ); + *timestamp = tv.tv_sec*1000000000ULL + tv.tv_usec*1000; +#else + *timestamp = (unsigned int)time*1000000000ULL + + (time-(unsigned int)time)*1000000000ULL; +#endif + + return 0; +} +int pwr_msrdev_write( pwr_fd_t fd, PWR_AttrName attr, void *value, unsigned int len ) +{ + + struct rapl_limit rlim; + struct rapl_limit rlim2; + int snum; + double val = *(double *)value; + poll_rapl_data(); + switch( attr ) + { + case PWR_ATTR_POWER_LIMIT_MAX: + snum = num_sockets(); + rlim.watts=val/snum; + rlim2.watts=val/snum; + rlim.bits=0; + rlim2.bits=0; + rlim.seconds=1; + rlim2.seconds=1; + for(int s = 0; s