├── README.md ├── VERSION ├── src ├── CMake │ ├── Setup3rdParty.cmake │ ├── SetupExternalProjects.cmake │ └── thirdparty │ │ └── SetupHwloc.cmake ├── CMakeLists.txt ├── libmsr_error.c ├── memhdlr.c ├── msr_clocks.c ├── msr_misc.c ├── csr_core.c └── msr_turbo.c ├── documentation ├── Libmsr.pdf ├── Libmsr_CSR.pdf ├── Libmsr_Batch.pdf ├── Libmsr_Perf.pdf ├── Libmsr_RAPL.pdf └── Libmsr_General.pdf ├── AUTHORS ├── msrmod ├── CMakeLists.txt └── README.md ├── include ├── CMakeLists.txt ├── libmsr_debug.h ├── memhdlr.h ├── libmsr_error.h ├── msr_clocks.h ├── msr_turbo.h ├── csr_core.h ├── csr_imc.h └── cpuid.h ├── dox └── CMakeLists.txt ├── test ├── CMakeLists.txt ├── turbo_test.c ├── read_rapl_data.c ├── power_unit_test.c ├── translate_pkg_rapl_limit.c ├── pstate_test.c ├── power_cap_test.c └── libmsr_dump_data.c ├── .gitignore ├── libmsr-config.cmake.in ├── demoapps └── powmon │ ├── README.md │ ├── CMakeLists.txt │ ├── highlander.h │ ├── rapl.h │ ├── common.c │ ├── rapl2.c │ ├── highlander.c │ ├── ghighres.c │ ├── power_wrapper_static.c │ ├── power_wrapper_dynamic.c │ └── powmon.c ├── patches └── fix_hyperthreads_enabled.patch ├── NOTICE ├── TODO ├── CONTRIBUTING.md ├── changelog.txt ├── CMakeLists.txt ├── README ├── autoconf.c └── platform_headers └── Intel2D.h /README.md: -------------------------------------------------------------------------------- 1 | README -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 0.3.0 2 | -------------------------------------------------------------------------------- /src/CMake/Setup3rdParty.cmake: -------------------------------------------------------------------------------- 1 | include(CMake/thirdparty/SetupHwloc.cmake) 2 | -------------------------------------------------------------------------------- /documentation/Libmsr.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LLNL/libmsr/HEAD/documentation/Libmsr.pdf -------------------------------------------------------------------------------- /documentation/Libmsr_CSR.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LLNL/libmsr/HEAD/documentation/Libmsr_CSR.pdf -------------------------------------------------------------------------------- /documentation/Libmsr_Batch.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LLNL/libmsr/HEAD/documentation/Libmsr_Batch.pdf -------------------------------------------------------------------------------- /documentation/Libmsr_Perf.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LLNL/libmsr/HEAD/documentation/Libmsr_Perf.pdf -------------------------------------------------------------------------------- /documentation/Libmsr_RAPL.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LLNL/libmsr/HEAD/documentation/Libmsr_RAPL.pdf -------------------------------------------------------------------------------- /documentation/Libmsr_General.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LLNL/libmsr/HEAD/documentation/Libmsr_General.pdf -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | We'd like to acknowledge previous developers who have contributed to the libmsr 2 | project: 3 | 4 | Peter Bailey 5 | Daniel Ellsworth 6 | Stephanie Brink (Labasan) 7 | Lauren Morita 8 | Tapasya Patki 9 | Barry Rountree 10 | Kathleen Shoga 11 | Scott Walker 12 | -------------------------------------------------------------------------------- /msrmod/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | include_directories(${PROJECT_SOURCE_DIR}/include) 4 | 5 | add_executable (msrmod msrmod.c) 6 | set_target_properties(${execname} PROPERTIES COMPILE_FLAGS "-g -Wall -D_GNU_SOURCE") 7 | target_link_libraries (msrmod msr) 8 | 9 | install(TARGETS msrmod EXPORT libmsr-libs DESTINATION 10 | "${CMAKE_INSTALL_PREFIX}/bin" 11 | ) 12 | -------------------------------------------------------------------------------- /include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LIBMSR_HEADERS 2 | cpuid.h 3 | csr_core.h 4 | csr_imc.h 5 | libmsr_error.h 6 | master.h 7 | memhdlr.h 8 | msr_clocks.h 9 | msr_core.h 10 | msr_counters.h 11 | msr_misc.h 12 | msr_rapl.h 13 | msr_thermal.h 14 | msr_turbo.h 15 | ) 16 | 17 | install(FILES ${LIBMSR_HEADERS} DESTINATION 18 | "${CMAKE_INSTALL_PREFIX}/include" 19 | ) 20 | -------------------------------------------------------------------------------- /dox/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Doxygen) 2 | if (DOXYGEN_FOUND) 3 | add_custom_target(doc 4 | ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile 5 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 6 | COMMENT "Generating API documentation with Doxygen" VERBATIM 7 | ) 8 | 9 | add_custom_target(latex_doc 10 | make 11 | DEPENDS doc 12 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/latex 13 | COMMENT "Building Doxygen Latex documentation" VERBATIM 14 | ) 15 | endif(DOXYGEN_FOUND) 16 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | set(LIBMSR_TESTS 4 | power_unit_test 5 | libmsr_test 6 | pstate_test 7 | read_rapl_data 8 | translate_pkg_rapl_limit 9 | turbo_test 10 | libmsr_dump_data 11 | power_cap_test 12 | ) 13 | 14 | foreach(TEST ${LIBMSR_TESTS}) 15 | add_executable(${TEST} ${TEST}.c) 16 | set_target_properties(${TEST} PROPERTIES COMPILE_FLAGS "-g -Wall -D_GNU_SOURCE") 17 | target_link_libraries(${TEST} msr) 18 | endforeach() 19 | 20 | include_directories(${PROJECT_SOURCE_DIR}/include) 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.core 2 | *.o 3 | *.so 4 | *.swp 5 | ._autoconf_ 6 | CMakeCache.txt 7 | CMakeFiles/ 8 | cmake_install.cmake 9 | Makefile 10 | demoapps/powmon/power_wrapper_dynamic 11 | demoapps/powmon/power_wrapper_static 12 | demoapps/powmon/powmon 13 | documentation/doxygen_*.pdf 14 | dox/html 15 | dox/latex 16 | include/master.h 17 | install_manifest.txt 18 | lib/ 19 | libmsr-config.cmake 20 | msrmod/msrmod 21 | test/libmsr_dump_data 22 | test/libmsr_test 23 | test/power_cap_test 24 | test/power_unit_test 25 | test/pstate_test 26 | test/read_rapl_data 27 | test/translate_pkg_rapl_limit 28 | test/turbo_test 29 | -------------------------------------------------------------------------------- /libmsr-config.cmake.in: -------------------------------------------------------------------------------- 1 | # Lauren Morita 2 | 3 | # libmsr config 4 | if (NOT libmsr_CONFIG_LOADED) 5 | set(libmsr_CONFIG_LOADED TRUE) 6 | 7 | #Install layout 8 | set(libmsr_INSTALL_PREFIX @CMAKE_INSTALL_PREFIX@) 9 | set(libmsr_INCLUDE_DIR ${libmsr_INSTALL_PREFIX}/include) 10 | set(libmsr_LIB_DIR ${libmsr_INSTALL_PREFIX}/lib) 11 | 12 | #Includes needed to use libmsr 13 | set(libmsr_INCLUDE_PATH ${libmsr_INCLUDE_DIR}) 14 | set(libmsr_LIB_PATH ${libmsr_LIB_DIR}) 15 | 16 | #Library targets imported from file 17 | include(${libmsr_INSTALL_PREFIX}/share/cmake/libmsr/libmsr-libs.cmake) 18 | endif() 19 | -------------------------------------------------------------------------------- /msrmod/README.md: -------------------------------------------------------------------------------- 1 | v0.0 alpha 2 | This tool is in alpha and has not been fully tested. Additionally, updates will 3 | be sparse. 4 | 5 | EXAMPLES 6 | ======== 7 | To set a package-level power limit on socket 0 (add -v for a verbose print out): 8 | 9 | ./msrmod -s package -c 0 -a 100 -b 1 -e 120 -f 3 (-v) 10 | 11 | To restore default power limits on socket 1: 12 | 13 | ./msrmod -s default -c 1 14 | 15 | To see current package-level and dram-level power limits: 16 | 17 | ./msrmod -p rapl 18 | 19 | To explicitly write a new hex value into register MSR_PKG_POWER_LIMIT 0x610 on 20 | CPU 3 (i.e., socket 0): 21 | 22 | ./msrmod -w 610 -t 3 -d 7845000158320 23 | -------------------------------------------------------------------------------- /demoapps/powmon/README.md: -------------------------------------------------------------------------------- 1 | POWMON 2 | ====== 3 | This directory contains three libmsr-based power monitors. 4 | 5 | powmon 6 | ------ 7 | Samples and prints power consumption and allocation per socket for 8 | systems with two sockets 9 | 10 | power_wrapper_static 11 | -------------------- 12 | Samples and prints power consumption and allocation per socket for systems with 13 | two sockets after setting a power cap 14 | 15 | power_wrapper_dynamic 16 | -------------------- 17 | Samples and prints power consumption and allocation per socket for systems with 18 | two sockets and adjusts the cap stepwise every 500 ms 19 | 20 | 21 | Notes 22 | ----- 23 | Each monitor includes a usage string. All three monitors are wrappers around 24 | some other process that will be executing on the node and include logic so that 25 | only one monitor is run per node. 26 | -------------------------------------------------------------------------------- /patches/fix_hyperthreads_enabled.patch: -------------------------------------------------------------------------------- 1 | From f9ba57ff3fd14ce0a8708e45bd0d973aedc3e4f6 Mon Sep 17 00:00:00 2001 2 | From: Stephanie Labasan 3 | Date: Tue, 3 Jan 2017 12:08:12 -0800 4 | Subject: [PATCH] Manually setting threadsPerCore to 1 to bypass duplicate 5 | readings across sockets in a hyperthreaded environment. 6 | 7 | Signed-off-by: Stephanie Labasan 8 | --- 9 | src/msr_core.c | 1 + 10 | 1 file changed, 1 insertion(+) 11 | 12 | diff --git a/src/msr_core.c b/src/msr_core.c 13 | index 873dda9..83060d3 100644 14 | --- a/src/msr_core.c 15 | +++ b/src/msr_core.c 16 | @@ -798,6 +798,7 @@ int load_socket_batch(off_t msr, uint64_t **val, int batchnum) 17 | #endif 18 | if (CPU_DEV_VER == 1) 19 | { 20 | + threadsPerCore = 1; 21 | for (dev_idx = 0, val_idx = 0; dev_idx < NUM_DEVS; dev_idx += coresPerSocket * threadsPerCore, val_idx++) 22 | { 23 | create_batch_op(msr, dev_idx, &val[val_idx], batchnum); 24 | -- 25 | 2.8.3 26 | 27 | -------------------------------------------------------------------------------- /src/CMake/SetupExternalProjects.cmake: -------------------------------------------------------------------------------- 1 | # Necessary for ExternalProject_Add 2 | include(ExternalProject) 3 | 4 | message(STATUS " [+] Adding external project: hwloc") 5 | ExternalProject_Add(libhwloc 6 | GIT_REPOSITORY https://github.com/open-mpi/hwloc.git 7 | UPDATE_COMMAND "" 8 | PATCH_COMMAND "" 9 | SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/thirdparty_builtin/hwloc 10 | CONFIGURE_COMMAND ${CMAKE_CURRENT_BINARY_DIR}/thirdparty_builtin/hwloc/autogen.sh && ${CMAKE_CURRENT_BINARY_DIR}/thirdparty_builtin/hwloc/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/thirdparty_builtin/libhwloc-prefix 11 | PREFIX ${CMAKE_CURRENT_BINARY_DIR}/thirdparty_builtin/libhwloc-prefix 12 | BUILD_COMMAND make 13 | INSTALL_COMMAND make install 14 | BUILD_IN_SOURCE 1 15 | ) 16 | 17 | ExternalProject_Get_property(libhwloc INSTALL_DIR) 18 | set(HWLOC_INCLUDE_DIRS 19 | ${INSTALL_DIR}/include 20 | CACHE INTERNAL "") 21 | 22 | set(HWLOC_LIBRARY 23 | ${INSTALL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}hwloc${CMAKE_SHARED_LIBRARY_SUFFIX} 24 | CACHE INTERNAL "") 25 | 26 | include_directories(${HWLOC_INCLUDES}) 27 | -------------------------------------------------------------------------------- /demoapps/powmon/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | set(CMAKE_C_FLAGS "-pthread") 4 | set(CMAKE_CXX_FLAGS "-pthread") 5 | 6 | set(POWMON_SOURCES 7 | highlander.c 8 | powmon.c 9 | rapl2.c) 10 | set(POWER_WRAPPER_STATIC_SOURCES 11 | highlander.c 12 | power_wrapper_static.c 13 | rapl2.c) 14 | set(POWER_WRAPPER_DYNAMIC_SOURCES 15 | highlander.c 16 | power_wrapper_dynamic.c 17 | rapl2.c) 18 | 19 | include_directories(${PROJECT_SOURCE_DIR}/include) 20 | 21 | add_executable (powmon ${POWMON_SOURCES}) 22 | add_executable (power_wrapper_static ${POWER_WRAPPER_STATIC_SOURCES}) 23 | add_executable (power_wrapper_dynamic ${POWER_WRAPPER_DYNAMIC_SOURCES}) 24 | 25 | target_link_libraries (powmon msr) 26 | target_link_libraries (power_wrapper_static msr) 27 | target_link_libraries (power_wrapper_dynamic msr) 28 | 29 | install(TARGETS powmon EXPORT libmsr-libs DESTINATION 30 | "${CMAKE_INSTALL_PREFIX}/bin" 31 | ) 32 | install(TARGETS power_wrapper_static EXPORT libmsr-libs DESTINATION 33 | "${CMAKE_INSTALL_PREFIX}/bin" 34 | ) 35 | install(TARGETS power_wrapper_dynamic EXPORT libmsr-libs DESTINATION 36 | "${CMAKE_INSTALL_PREFIX}/bin" 37 | ) 38 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(CMake/Setup3rdParty.cmake) 2 | 3 | # 4 | # Static and dynamic libs have the same sources, so make a variable. 5 | # 6 | set(LIBMSR_SOURCES 7 | cpuid.c 8 | csr_core.c 9 | csr_imc.c 10 | memhdlr.c 11 | libmsr_error.c 12 | msr_clocks.c 13 | msr_core.c 14 | msr_counters.c 15 | msr_misc.c 16 | msr_rapl.c 17 | msr_thermal.c 18 | msr_turbo.c 19 | ) 20 | 21 | # 22 | # Add dynamic library 23 | # 24 | add_library(msr SHARED ${LIBMSR_SOURCES}) 25 | target_link_libraries(msr ${HWLOC_LIBRARY}) 26 | target_link_libraries(msr m) 27 | if(HWLOC_EXT) 28 | add_dependencies(msr libhwloc) 29 | endif() 30 | 31 | # 32 | # Add static library with same base name as the dynamic lib. 33 | # 34 | add_library(msr-static STATIC ${LIBMSR_SOURCES}) 35 | target_link_libraries(msr-static ${HWLOC_LIBRARY}) 36 | target_link_libraries(msr-static m) 37 | set_target_properties(msr-static PROPERTIES OUTPUT_NAME "msr") 38 | if(HWLOC_EXT) 39 | add_dependencies(msr-static libhwloc) 40 | endif() 41 | 42 | # 43 | # Install target should install the two library targets above. 44 | # 45 | install(TARGETS msr msr-static DESTINATION "${CMAKE_INSTALL_PREFIX}/lib" EXPORT libmsr-libs) 46 | 47 | # 48 | # Headers are in ../include 49 | # 50 | include_directories(${PROJECT_SOURCE_DIR}/include 51 | ${HWLOC_INCLUDE_DIRS}) 52 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | OUR NOTICE AND TERMS OF CONDITIONS OF THE GNU GENERAL PUBLIC LICENSE 2 | 3 | Our Preamble Notice 4 | 5 | A. This notice is required to be provided under our contract with the U.S. 6 | Department of Energy (DOE). This work was produced at the Lawrence Livermore 7 | National Laboratory under Contract No. DE-AC52-07NA27344 with the DOE. 8 | 9 | B. Neither the United States Government nor Lawrence Livermore National 10 | Security, LLC nor any of their employees, makes any warranty, express or 11 | implied, or assumes any liability or responsibility for the accuracy, 12 | completeness, or usefulness of any information, apparatus, product, or process 13 | disclosed, or represents that its use would not infringe privately-owned 14 | rights. 15 | 16 | C. Also, reference herein to any specific commercial products, process, or 17 | services by trade name, trademark, manufacturer or otherwise does not 18 | necessarily constitute or imply its endorsement, recommendation, or favoring by 19 | the United States Government or Lawrence Livermore National Security, LLC. The 20 | views and opinions of authors expressed herein do not necessarily state or 21 | reflect those of the United States Government or Lawrence Livermore National 22 | Security, LLC, and shall not be used for advertising or product endorsement 23 | purposes. 24 | 25 | See LICENSE for the precise terms and conditions for copying, distribution, and 26 | modification. 27 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Todo Tags 2 | --------- 3 | 4 | src/csr_imc.c Combine into 1 counter batch and 1 event batch. 5 | src/msr_rapl.c Should we flip bits for pkg_limit? 6 | src/msr_rapl.c Currently unused, but if it ever is used, we need a fix for 7 | Haswell 8 | 9 | Ongoing 10 | ------- 11 | 12 | - [2016-08-08] Finish tagging PCI configuration (CSR) files with Doxygen tags. 13 | 14 | - [2016-08-11] Add member variables for converted bit fields (i.e., 15 | human-readable values) in performance counter structs. Current implementation 16 | only stores raw values of bit fields. 17 | 18 | - [2016-08-11] Finish CSRs for QPI, PCU, caching agent, iMC, currently only 19 | have a partial implementation for iMC. 20 | 21 | Optimizations 22 | ------------- 23 | 24 | - [2016-08-11] Clean up memory incrementally along the way, instead of doing a 25 | big clean up before terminating. 26 | - [2016-08-11] Define width of struct member variables. For example, if we have 27 | an int, but are only going to store a 0 or 1 in it, we can re-define this 28 | variable and tell the compiler we will only use 1 byte instead of the default 29 | 4 bytes. 30 | 31 | Known Bugs 32 | ---------- 33 | 34 | - [2016-08-11] msr-safe and enabling hyperthreads in slurm. 35 | 36 | - [2016-08-11] msr-safe is not compatible with msub scheduler. 37 | 38 | Needs Testing 39 | ------------- 40 | 41 | - [2016-08-11] Libmsr in MPI program. 42 | 43 | - [2016-08-11] Libmsr in Openmp program. 44 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | CONTRIBUTING 2 | ============ 3 | 4 | This file will describe how to provide feedback to the Libmsr project. 5 | 6 | 7 | Code Formatting 8 | --------------- 9 | 10 | We ask that you use four spaces for indentation, remove all trailing 11 | whitespace, use broken enclosing brackets, and indent the contents of classes, 12 | switches, and namespace. 13 | 14 | Code formatting can be automated using astyle with the following parameters: 15 | 16 | $ astyle --style=allman --indent=spaces=4 -y -S -C -N 17 | 18 | 19 | Change Requests 20 | --------------- 21 | 22 | The easiest way to contribute a change request is to make all of your changes on 23 | a new branch in a fork of libmsr. Make sure your `master` is up-to-date and 24 | create a new branch off of it: 25 | 26 | $ git checkout master 27 | $ git pull 28 | $ git branch 29 | $ git checkout 30 | 31 | Edit a few files and commit them. It is important to add a descriptive commit 32 | message so that others can easily find (and understand) the changes when 33 | looking back at them in the future. 34 | 35 | $ git add 36 | $ git commit -m 37 | 38 | Next, push it to your remote fork and create a PR: 39 | 40 | $ git push origin 41 | 42 | GitHub provides a tutorial on how to file a pull request. When you send the 43 | request, make `master` the destination branch. 44 | 45 | 46 | Bug Requests 47 | ------------ 48 | 49 | Please open a new issue on GitHub. 50 | -------------------------------------------------------------------------------- /include/libmsr_debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #ifndef LIBMSR_DEBUG_H_INCLUDE 32 | #define LIBMSR_DEBUG_H_INCLUDE 33 | 34 | //#define CPUID_DEBUG 35 | //#define MEMHDLR_DEBUG 36 | //#define LIBMSR_DEBUG 1 37 | //#define STORAGE_DEBUG 1 38 | //#define CSRDEBUG 39 | #define LIBMSR_DEBUG_TAG "LIBMSR" 40 | //#define BATCH_DEBUG 1 41 | //#define THERM_DEBUG 1 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /demoapps/powmon/highlander.h: -------------------------------------------------------------------------------- 1 | /* highlander.h 2 | * 3 | * Copyright (c) 2011-2016, Lawrence Livermore National Security, LLC. 4 | * LLNL-CODE-645430 5 | * 6 | * Produced at Lawrence Livermore National Laboratory 7 | * Written by Barry Rountree, rountree@llnl.gov 8 | * Daniel Ellsworth, ellsworth8@llnl.gov 9 | * Scott Walker, walker91@llnl.gov 10 | * Kathleen Shoga, shoga1@llnl.gov 11 | * 12 | * All rights reserved. 13 | * 14 | * This file is part of libmsr. 15 | * 16 | * libmsr is free software: you can redistribute it and/or modify it under the 17 | * terms of the GNU Lesser General Public License as published by the Free 18 | * Software Foundation, either version 3 of the License, or (at your option) 19 | * any later version. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 24 | * details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr. If not, see . 28 | * 29 | * This material is based upon work supported by the U.S. Department of 30 | * Energy's Lawrence Livermore National Laboratory. Office of Science, under 31 | * Award number DE-AC52-07NA27344. 32 | * 33 | */ 34 | 35 | #ifndef HIGHLANDER_H 36 | #define HIGHLANDER_H 37 | 38 | /// @brief Determines/initializes the process highlander status. 39 | int highlander(void); 40 | 41 | /// @brief Causes the highlander to wait until all foes have called wait. 42 | int highlander_wait(void); 43 | 44 | /// @brief Remove outstanding semaphores. 45 | int highlander_clean(void); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/CMake/thirdparty/SetupHwloc.cmake: -------------------------------------------------------------------------------- 1 | # First check for user-specified HWLOC_DIR 2 | if(HWLOC_DIR) 3 | MESSAGE(STATUS "Looking for Hwloc using HWLOC_DIR = ${HWLOC_DIR}") 4 | 5 | set(HWLOC_FOUND TRUE) 6 | set(HWLOC_INCLUDE_DIRS ${HWLOC_DIR}/include) 7 | set(HWLOC_LIBRARY ${HWLOC_DIR}/lib/libhwloc.so) 8 | 9 | set(HWLOC_DIR ${HWLOC_DIR} CACHE PATH "" FORCE) 10 | 11 | message(STATUS "FOUND Hwloc at ${HWLOC_DIR}") 12 | message(STATUS " HWLOC_INCLUDE_DIRS = ${HWLOC_INCLUDE_DIRS}") 13 | message(STATUS " HWLOC_LIBRARY = ${HWLOC_LIBRARY}") 14 | # If HWLOC_DIR not specified, then try to automatically find the HWLOC header 15 | # and library 16 | elseif(NOT HWLOC_DIR) 17 | find_path(HWLOC_INCLUDE_DIRS 18 | NAMES hwloc.h 19 | ) 20 | 21 | find_library(HWLOC_LIBRARY 22 | NAMES libhwloc.so 23 | ) 24 | 25 | if(HWLOC_INCLUDE_DIRS AND HWLOC_LIBRARY) 26 | set(HWLOC_FOUND TRUE) 27 | message(STATUS "HWLOC library found using find_library()") 28 | message(STATUS " HWLOC_INCLUDE_DIRS = ${HWLOC_INCLUDE_DIRS}") 29 | message(STATUS " HWLOC_LIBRARY = ${HWLOC_LIBRARY}") 30 | endif() 31 | endif() 32 | 33 | # If HWLOC is still not found, then download and build HWLOC from source 34 | if(NOT HWLOC_INCLUDE_DIRS AND NOT HWLOC_LIBRARY) 35 | MESSAGE(STATUS "Downloading and building Hwloc from source") 36 | include(CMake/SetupExternalProjects.cmake) 37 | 38 | set(HWLOC_EXT TRUE) 39 | 40 | message(STATUS "ExternalProject Hwloc") 41 | message(STATUS " HWLOC_INCLUDE_DIRS = ${HWLOC_INCLUDE_DIRS}") 42 | message(STATUS " HWLOC_LIBRARY = ${HWLOC_LIBRARY}") 43 | set(HWLOC_FOUND TRUE) 44 | endif() 45 | 46 | # Abort if all methods fail 47 | if(NOT HWLOC_FOUND) 48 | MESSAGE(FATAL_ERROR "Hwloc support needed") 49 | endif() 50 | -------------------------------------------------------------------------------- /demoapps/powmon/rapl.h: -------------------------------------------------------------------------------- 1 | /* rapl.h 2 | * 3 | * Copyright (c) 2011-2016, Lawrence Livermore National Security, LLC. 4 | * LLNL-CODE-645430 5 | * 6 | * Produced at Lawrence Livermore National Laboratory 7 | * Written by Barry Rountree, rountree@llnl.gov 8 | * Daniel Ellsworth, ellsworth8@llnl.gov 9 | * Scott Walker, walker91@llnl.gov 10 | * Kathleen Shoga, shoga1@llnl.gov 11 | * 12 | * All rights reserved. 13 | * 14 | * This file is part of libmsr. 15 | * 16 | * libmsr is free software: you can redistribute it and/or modify it under the 17 | * terms of the GNU Lesser General Public License as published by the Free 18 | * Software Foundation, either version 3 of the License, or (at your option) 19 | * any later version. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 24 | * details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr. If not, see . 28 | * 29 | * This material is based upon work supported by the U.S. Department of 30 | * Energy's Lawrence Livermore National Laboratory. Office of Science, under 31 | * Award number DE-AC52-07NA27344. 32 | * 33 | */ 34 | 35 | /// @brief Initialize the library to read from the rapl MSRs. 36 | void read_rapl_init(void); 37 | 38 | /// @brief Read the current consumption and allocation. 39 | /// 40 | /// Variable ret must be an array of length 8. 41 | /// idx 0,1 report consumption in joules for sockets 0 and 1. 42 | /// idx 2,3 report allocation in joules for sockets 0 and 1. 43 | /// idx 4,5 report consumption in watts for sockets 0 and 1. 44 | /// idx 6,7 report allocation in joules for sockets 0 and 1. 45 | void read_rapl_energy_and_power(double *ret); 46 | 47 | void set_rapl_power(double s0bound, double s1bound); 48 | 49 | -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 | v0.3.0 Cleanup, New features 2 | + added three new features related to Turbo Boost and clocks 3 | + change frequency of a given domain (e.g., core, socket) 4 | + get maximum Turbo Boost ratio fused on the processor given a number of 5 | cores active 6 | + read MSR_TURBO_ACTIVATION_RATIO to get the max non-turbo ratio currently 7 | set on the processor 8 | + standardized libmsr error and warning messages 9 | + standardized code format 10 | + in-depth documentation of libmsr code base 11 | - removing deprecated variables from code base 12 | 13 | v0.2.0 Auto 14 | + added new build system 15 | + must be installed with included install.sh 16 | + supports Sandy Bridge, Ivy Bridge, and Haswell 17 | + added autoconf.c header file generator 18 | 19 | v0.1.18 CSR 20 | + added PCI configuration register (CSR) support 21 | + (note that this currently requires CSR-SAFE) 22 | + (also only supports Intel CSRs) 23 | + added iMC performance counters 24 | + MC0 Channel 0-3 perf counters 25 | + MC1 Channel 0-3 perf counters 26 | + added Cbo (caching agent) performance counters 27 | + C#MSR_PMON_CTL# 28 | + C#_MSR_PMON_CTR# 29 | + C#_MSR_PMON_BOX_FILTER 30 | + C#_MSR_PMON_BOX_FILTER1 31 | + C#_MSR_PMON_BOX_CTL 32 | + fixed problem in RAPL architecture detection 33 | 34 | v0.1.17 Request 35 | + will attempt to work even without whitelist (subject to change) 36 | + detects the kernel's core layout decisions at runtime 37 | + added MSRs 38 | + 0x3F8 - 0x3FE // in msr_misc.c 39 | + 0x60D // in msr_misc.c 40 | + 0xC30 - 0xC33 // in msr_counters.c 41 | + 0xC36 - 0xC39 // in msr_counters.c 42 | + 0x19D // in msr_thermal.c 43 | + will get energy readings if energy_status registers exist rather 44 | than power_limit 45 | + power unit fixed for DRAM on Haswell 46 | 47 | v0.1.16 Mission 48 | - Removed deprecated variable from cpuid.c 49 | + cpuid.c get_core_conf() function has been reworked to be more portable 50 | - Removed extraneous code in msr_rapl.c 51 | + msr_core.c devidx() function now works with even-odd cpu ordering schemes 52 | + msr_init() now stats msr_whitelist 53 | + libmsr_test now has an message saying if libmsr is working (WIP) 54 | + libmsr_test now explicitly resets power values to defaults 55 | 56 | v0.1.15 Batch 57 | + Added msrmod command line utility 58 | - Removed msr 0x63B from architecture 06_3C 59 | + updated msr_rapl to use the latest batch interface, details below 60 | + read_rapl_data() no longer takes any arguments 61 | + read_rapl_data() now uses the new batch interface 62 | + rapl_data struct has been changed, see msr_rapl.h for details 63 | + delta_rapl_data() no longer takes arguments 64 | + poll_rapl_data() no longer takes arguments 65 | + dump_rapl_data() arguments have changed, now only takes a FILE* 66 | -------------------------------------------------------------------------------- /demoapps/powmon/common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Daniel Ellsworth , 7 | * Scott Walker , and 8 | * Kathleen Shoga . 9 | * 10 | * LLNL-CODE-645430 11 | * 12 | * All rights reserved. 13 | * 14 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 15 | * 16 | * Please also read libmsr/LICENSE for our notice and the LGPL. 17 | * 18 | * libmsr is free software: you can redistribute it and/or modify it under the 19 | * terms of the GNU Lesser General Public License (as published by the Free 20 | * Software Foundation) version 2.1 dated February 1999. 21 | * 22 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 23 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 24 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 25 | * General Public License for more details. 26 | * 27 | * You should have received a copy of the GNU Lesser General Public License 28 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 29 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 30 | */ 31 | 32 | #include 33 | 34 | int init_data(void) 35 | { 36 | return 0; 37 | } 38 | 39 | void take_measurement(void) 40 | { 41 | uint64_t instr0 = 0; 42 | uint64_t instr1 = 0; 43 | uint64_t core0 = 0; 44 | uint64_t core1 = 0; 45 | double rapl_data[10]; 46 | pthread_mutex_lock(&mlock); 47 | 48 | /* RAPL reads. */ 49 | read_rapl_energy_and_power(rapl_data); 50 | 51 | total_joules += rapl_data[0] + rapl_data[1]; 52 | limit_joules += rapl_data[2] + rapl_data[3]; 53 | if (max_watts < rapl_data[4]) 54 | { 55 | max_watts = rapl_data[4]; 56 | } 57 | if (max_watts < rapl_data[5]) 58 | { 59 | max_watts = rapl_data[5]; 60 | } 61 | if (min_watts > rapl_data[4]) 62 | { 63 | min_watts = rapl_data[4]; 64 | } 65 | if (min_watts > rapl_data[5]) 66 | { 67 | min_watts = rapl_data[5]; 68 | } 69 | fprintf(logfile, "%ld %lf %lf %lf %lf %lf %lf %lu %lu %lu %lu\n", now_ms(), rapl_data[0], rapl_data[1], rapl_data[6], rapl_data[7], rapl_data[8], rapl_data[9], instr0, instr1, core0, core1); 70 | pthread_mutex_unlock(&mlock); 71 | } 72 | 73 | void *power_measurement(void *arg) 74 | { 75 | struct mstimer timer; 76 | // According to the Intel docs, the counter wraps at most once per second. 77 | // 100 ms should be short enough to always get good information. 78 | init_msTimer(&timer, 100); 79 | init_data(); 80 | read_rapl_init(); 81 | start = now_ms(); 82 | 83 | timer_sleep(&timer); 84 | while (running) 85 | { 86 | take_measurement(); 87 | timer_sleep(&timer); 88 | } 89 | return arg; 90 | } 91 | -------------------------------------------------------------------------------- /demoapps/powmon/rapl2.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Daniel Ellsworth , 7 | * Scott Walker , and 8 | * Kathleen Shoga . 9 | * 10 | * LLNL-CODE-645430 11 | * 12 | * All rights reserved. 13 | * 14 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 15 | * 16 | * Please also read libmsr/LICENSE for our notice and the LGPL. 17 | * 18 | * libmsr is free software: you can redistribute it and/or modify it under the 19 | * terms of the GNU Lesser General Public License (as published by the Free 20 | * Software Foundation) version 2.1 dated February 1999. 21 | * 22 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 23 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 24 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 25 | * General Public License for more details. 26 | * 27 | * You should have received a copy of the GNU Lesser General Public License 28 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 29 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 30 | */ 31 | 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | 38 | static struct rapl_data *rdat; 39 | static uint64_t *rflags; 40 | 41 | void read_rapl_init(void) 42 | { 43 | init_msr(); 44 | rapl_init(&rdat, &rflags); 45 | /* DRAM_PERF_STATUS not implemented yet in libmsr. */ 46 | *rflags = *rflags & ~DRAM_PERF_STATUS; 47 | 48 | static struct rapl_limit rlim[4]; 49 | get_pkg_rapl_limit(0, &(rlim[0]), NULL); 50 | get_pkg_rapl_limit(1, &(rlim[1]), NULL); 51 | get_dram_rapl_limit(0, &(rlim[2])); 52 | get_dram_rapl_limit(1, &(rlim[3])); 53 | } 54 | 55 | void read_rapl_energy_and_power(double *ret) 56 | { 57 | static struct rapl_limit rlim[4]; 58 | /* RAPL reads. */ 59 | poll_rapl_data(); 60 | get_pkg_rapl_limit(0, &(rlim[0]), NULL); 61 | get_pkg_rapl_limit(1, &(rlim[1]), NULL); 62 | get_dram_rapl_limit(0, &(rlim[2])); 63 | get_dram_rapl_limit(1, &(rlim[3])); 64 | 65 | ret[0] = rdat->pkg_delta_joules[0]; 66 | ret[1] = rdat->pkg_delta_joules[1]; 67 | ret[2] = rlim[0].watts * rdat->elapsed; 68 | ret[3] = rlim[1].watts * rdat->elapsed; 69 | ret[4] = rdat->pkg_delta_joules[0] / rdat->elapsed; 70 | ret[5] = rdat->pkg_delta_joules[1] / rdat->elapsed; 71 | ret[6] = rlim[0].watts; 72 | ret[7] = rlim[1].watts; 73 | ret[8] = rdat->dram_delta_joules[0]; 74 | ret[9] = rdat->dram_delta_joules[1]; 75 | } 76 | 77 | void set_rapl_power(double s0bound, double s1bound) 78 | { 79 | static struct rapl_limit rlim[2]; 80 | rlim[0].watts = s0bound; 81 | rlim[1].watts = s1bound; 82 | rlim[0].bits = 0; 83 | rlim[1].bits = 0; 84 | rlim[0].seconds = 1; 85 | rlim[1].seconds = 1; 86 | set_pkg_rapl_limit(0, &(rlim[0]), &(rlim[1])); 87 | set_pkg_rapl_limit(1, &(rlim[0]), &(rlim[1])); 88 | 89 | get_pkg_rapl_limit(0, &(rlim[0]), NULL); 90 | get_pkg_rapl_limit(1, &(rlim[1]), NULL); 91 | } 92 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(libmsr C) 2 | cmake_minimum_required(VERSION 2.8) 3 | 4 | set(CMAKE_C_COMPILER "gcc") 5 | set(CMAKE_CXX_COMPILER "g++") 6 | 7 | # Add -Wall if it is not there already. 8 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -O3") 9 | 10 | # Force default build type to be RelWithDebInfo 11 | if (NOT CMAKE_BUILD_TYPE) 12 | set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo." FORCE) 13 | endif() 14 | 15 | # Build and run autoconf utility 16 | set(LIBMSR_AUTOCONF ${CMAKE_BINARY_DIR}/._autoconf_) 17 | execute_process(COMMAND gcc -o ${LIBMSR_AUTOCONF} ${CMAKE_SOURCE_DIR}/autoconf.c) 18 | set(LIBMSR_TARGET_ARCH "" CACHE STRING "Force configuring for a particular architecture") 19 | if (LIBMSR_TARGET_ARCH) 20 | execute_process(COMMAND ${LIBMSR_AUTOCONF} -f ${LIBMSR_TARGET_ARCH} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) 21 | else() 22 | execute_process(COMMAND ${LIBMSR_AUTOCONF} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) 23 | endif() 24 | 25 | # Headers are in top level include directory 26 | include_directories(${PROJECT_SOURCE_DIR}/include) 27 | 28 | # Make libmsr findable 29 | configure_file( 30 | ${PROJECT_SOURCE_DIR}/libmsr-config.cmake.in 31 | ${PROJECT_BINARY_DIR}/libmsr-config.cmake 32 | @ONLY 33 | ) 34 | 35 | install(FILES ${PROJECT_BINARY_DIR}/libmsr-config.cmake DESTINATION 36 | "${CMAKE_INSTALL_PREFIX}/share/cmake/libmsr" 37 | ) 38 | install(EXPORT libmsr-libs DESTINATION 39 | "${CMAKE_INSTALL_PREFIX}/share/cmake/libmsr" 40 | ) 41 | 42 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) 43 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) 44 | 45 | add_subdirectory(src) 46 | add_subdirectory(include) 47 | add_subdirectory(dox) 48 | 49 | add_subdirectory(test) 50 | add_subdirectory(msrmod) 51 | add_subdirectory(demoapps/powmon) 52 | 53 | add_custom_target(distclean 54 | rm -f ._autoconf_ 55 | rm -f CMakeCache.txt 56 | rm -f Makefile 57 | rm -f cmake_install.cmake 58 | rm -f demoapps/powmon/cmake_install.cmake 59 | rm -f demoapps/powmon/Makefile 60 | rm -f demoapps/powmon/power_wrapper_dynamic 61 | rm -f demoapps/powmon/power_wrapper_static 62 | rm -f demoapps/powmon/powmon 63 | rm -f dox/CMakeCache.txt 64 | rm -f dox/Makefile 65 | rm -f dox/cmake_install.cmake 66 | rm -f include/Makefile 67 | rm -f include/cmake_install.cmake 68 | rm -f include/master.h 69 | rm -f install_manifest.txt 70 | rm -f libmsr-config.cmake 71 | rm -f msrmod/cmake_install.cmake 72 | rm -f msrmod/Makefile 73 | rm -f msrmod/msrmod 74 | rm -f src/cmake_install.cmake 75 | rm -f src/Makefile 76 | rm -f test/CMakeCache.txt 77 | rm -f test/cmake_install.cmake 78 | rm -f test/Makefile 79 | rm -f test/dump-data 80 | rm -f test/libmsr-test 81 | rm -f test/pstate-test 82 | rm -f test/rapl-data 83 | rm -f test/translate 84 | rm -f test/turbo-test 85 | rm -f test/unit-test 86 | rm -rf CMakeFiles/ 87 | rm -rf demoapps/powmon/CMakeFiles 88 | rm -rf dox/CMakeFiles/ 89 | rm -rf dox/html/ 90 | rm -rf dox/latex/ 91 | rm -rf include/CMakeFiles/ 92 | rm -rf lib/ 93 | rm -rf msrmod/CMakeFiles 94 | rm -rf src/CMakeFiles/ 95 | rm -rf test/CMakeFiles/ 96 | rm -rf wrap/CMakeFiles/ 97 | COMMENT "Cleaning up unwanted files" VERBATIM 98 | ) 99 | -------------------------------------------------------------------------------- /demoapps/powmon/highlander.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Daniel Ellsworth , 7 | * Scott Walker , and 8 | * Kathleen Shoga . 9 | * 10 | * LLNL-CODE-645430 11 | * 12 | * All rights reserved. 13 | * 14 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 15 | * 16 | * Please also read libmsr/LICENSE for our notice and the LGPL. 17 | * 18 | * libmsr is free software: you can redistribute it and/or modify it under the 19 | * terms of the GNU Lesser General Public License (as published by the Free 20 | * Software Foundation) version 2.1 dated February 1999. 21 | * 22 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 23 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 24 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 25 | * General Public License for more details. 26 | * 27 | * You should have received a copy of the GNU Lesser General Public License 28 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 29 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 30 | */ 31 | 32 | /// Highlander... because there can be only one. 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | static int amHighlander = -1; 40 | 41 | static sem_t *semk = NULL; 42 | static sem_t *seml = NULL; 43 | 44 | /// @brief Determines/initializes the process highlander status. 45 | int highlander(void) 46 | { 47 | if (amHighlander != -1) 48 | { 49 | return amHighlander; 50 | } 51 | 52 | semk = sem_open("/power_wrapperK", O_CREAT | O_EXCL, 0600, 0); 53 | if(semk == NULL || semk == SEM_FAILED) 54 | { 55 | semk = sem_open("/power_wrapperK", O_CREAT, 0600, 0); 56 | seml = sem_open("/power_wrapperL", O_CREAT, 0600, 0); 57 | sem_post(semk); 58 | int v; 59 | sem_getvalue(semk, &v); 60 | amHighlander = 0; 61 | return 0; 62 | } 63 | seml = sem_open("/power_wrapperL", O_CREAT, 0600, 0); 64 | amHighlander = 1; 65 | return 1; 66 | } 67 | 68 | int highlander_clean(void) 69 | { 70 | // remove the named semaphores 71 | fprintf(stdout, "Removing named semaphore /power_wrapperK\n"); 72 | sem_unlink("/power_wrapperK"); 73 | fprintf(stdout, "Removing named semaphore /power_wrapperL\n"); 74 | sem_unlink("/power_wrapperL"); 75 | return 1; 76 | } 77 | 78 | /// @brief Causes the highlander to wait until all foes have called wait. 79 | int highlander_wait(void) 80 | { 81 | if (amHighlander < 0) 82 | { 83 | return 1; 84 | } 85 | if (amHighlander) 86 | { 87 | int v; 88 | sem_getvalue(semk, &v); 89 | while (v > 1) 90 | { 91 | sem_wait(seml); 92 | } 93 | 94 | sem_close(semk); 95 | sem_close(seml); 96 | sem_unlink("/power_wrapperK"); 97 | sem_unlink("/power_wrapperL"); 98 | 99 | return 0; 100 | } 101 | else 102 | { 103 | sem_wait(semk); 104 | sem_post(seml); 105 | sem_close(semk); 106 | sem_close(seml); 107 | return 0; 108 | } 109 | return 1; 110 | } 111 | -------------------------------------------------------------------------------- /include/memhdlr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #ifndef MEMHDLR_H_INCLUDE 32 | #define MEMHDLR_H_INCLUDE 33 | 34 | #include 35 | 36 | // These functions are for libmsr use only. Use outside of libmsr may cause 37 | // segfaults or disrupt libmsr functions. 38 | // The primary purpose of these functions is to simplify memory management and 39 | // debugging (debugging much easier), but there are plans to add more 40 | // functionality in the future. 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /// @brief Enum encompassing types of libmsr memory management. 47 | enum libmsr_mem_mgmt_e 48 | { 49 | LIBMSR_FREE, 50 | LIBMSR_MALLOC, 51 | LIBMSR_CALLOC, 52 | LIBMSR_REALLOC, 53 | LIBMSR_FINALIZE 54 | }; 55 | 56 | /// @brief Allocate size bytes with malloc(). 57 | /// 58 | /// @param [in] size Number of bytes. 59 | /// 60 | /// @return Pointer to dynamic array. 61 | void *libmsr_malloc(size_t size); 62 | 63 | /// @brief Allocate memory for an array of num elements of size bytes each with 64 | /// calloc(). 65 | /// 66 | /// @param [in] size Number of bytes. 67 | /// 68 | /// @param [in] num Number of elements. 69 | /// 70 | /// @return Pointer to dynamic array. 71 | void *libmsr_calloc(size_t num, 72 | size_t size); 73 | 74 | /// @brief Change allocation of existing memory to size bytes with realloc(). 75 | /// 76 | /// @param [out] addr Pointer to dynamic array. 77 | /// 78 | /// @param [in] size Number of bytes. 79 | /// 80 | /// @return Pointer to dynamic array. 81 | void *libmsr_realloc(void *addr, 82 | size_t size); 83 | 84 | /// @brief Free single dynamic memory allocation. 85 | /// 86 | /// @param [in] addr Pointer to dynamic array. 87 | /// 88 | /// @return Null pointer. 89 | void *libmsr_free(void *addr); 90 | 91 | /// @brief Deallocate any remaining memory allocations and deallocate tracking 92 | /// structure. 93 | /// 94 | /// @return Null pointer. 95 | void *memhdlr_finalize(void); 96 | 97 | /// @brief Track all dynamic arrays allocated in libmsr to make deallocation 98 | /// simple. 99 | /// 100 | /// @param [out] address Pointer to dynamic array. 101 | /// 102 | /// @param [out] oldaddr Pointer to dynamic array. 103 | /// 104 | /// @param [in] type libmsr_mem_mgmt_e memory management identifier. 105 | /// 106 | /// @return 0 if successful, -1 if malloc() or realloc() fails. 107 | int memory_handler(void *address, 108 | void *oldaddr, 109 | int type); 110 | 111 | #ifdef __cplusplus 112 | } 113 | #endif 114 | #endif 115 | -------------------------------------------------------------------------------- /demoapps/powmon/ghighres.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Daniel Ellsworth , 7 | * Scott Walker , and 8 | * Kathleen Shoga . 9 | * 10 | * LLNL-CODE-645430 11 | * 12 | * All rights reserved. 13 | * 14 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 15 | * 16 | * Please also read libmsr/LICENSE for our notice and the LGPL. 17 | * 18 | * libmsr is free software: you can redistribute it and/or modify it under the 19 | * terms of the GNU Lesser General Public License (as published by the Free 20 | * Software Foundation) version 2.1 dated February 1999. 21 | * 22 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 23 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 24 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 25 | * General Public License for more details. 26 | * 27 | * You should have received a copy of the GNU Lesser General Public License 28 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 29 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 30 | */ 31 | 32 | /// high resolution sleep function 33 | 34 | #include 35 | #include 36 | 37 | struct mstimer 38 | { 39 | /// @brief When we started tracking the timer. 40 | unsigned long startms; 41 | /// @brief Which time is the next interval. 42 | uint step; 43 | /// @brief How many ms between firings. 44 | uint interval; 45 | /// @brief When does the timer expire next. 46 | unsigned long nextms; 47 | }; 48 | 49 | #if 0 /* Deprecated. */ 50 | /* Get a number of millis from realtime clock. */ 51 | unsigned long now_rt_ms(void) 52 | { 53 | struct timespec t; 54 | clock_gettime(CLOCK_REALTIME, &t); 55 | unsigned long sec = t.tv_sec * 1000; 56 | unsigned long msec = (t.tv_nsec + 500000) / 1000000; 57 | return sec + msec; 58 | } 59 | #endif 60 | 61 | /// @brief Get a number of millis from a monotonic clock. 62 | unsigned long now_ms(void) 63 | { 64 | struct timespec t; 65 | clock_gettime(CLOCK_REALTIME, &t); 66 | unsigned long sec = t.tv_sec * 1000; 67 | unsigned long msec = (t.tv_nsec + 500000) / 1000000; 68 | return sec + msec; 69 | } 70 | 71 | /// @brief Use a select to sleep a given number of millis. 72 | void sleep_ms(long ms) 73 | { 74 | struct timeval i; 75 | i.tv_sec = ms / 1000; 76 | i.tv_usec = (ms%1000) * 1000; 77 | select(0, NULL, NULL, NULL, &i); 78 | } 79 | 80 | /// @brief Initialize a msTimer. 81 | void init_msTimer(struct mstimer *t, int ms_interval) 82 | { 83 | t->step = 1; 84 | t->interval = ms_interval; 85 | t->startms = now_ms(); 86 | t->nextms = t->startms + t->step * t->interval; 87 | } 88 | 89 | /// @brief Initialize a msTimer. 90 | void init_sync_msTimer(struct mstimer *t, int ms_interval, unsigned long start) 91 | { 92 | t->step = 1; 93 | t->interval = ms_interval; 94 | t->startms = start; 95 | t->nextms = t->startms + t->step * t->interval; 96 | } 97 | 98 | /// @brief Sleep until timer time has elapsed. 99 | int timer_sleep(struct mstimer *t) 100 | { 101 | unsigned long now = now_ms(); 102 | if (now >= t->nextms) 103 | { 104 | int cadd = 0; 105 | while (t->nextms <= now) 106 | { 107 | cadd++; 108 | t->step++; 109 | t->nextms = t->startms + t->step * t->interval; 110 | } 111 | /* We slept this many intervals. */ 112 | return cadd; 113 | } 114 | sleep_ms(t->nextms - now); 115 | t->step++; 116 | t->nextms = t->startms + t->step * t->interval; 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /test/turbo_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "cpuid.h" 39 | #include "memhdlr.h" 40 | #include "msr_core.h" 41 | #include "msr_rapl.h" 42 | #include "msr_thermal.h" 43 | #include "msr_counters.h" 44 | #include "msr_clocks.h" 45 | #include "msr_misc.h" 46 | #include "msr_turbo.h" 47 | #include "csr_core.h" 48 | #include "csr_imc.h" 49 | #include "libmsr_error.h" 50 | #ifdef MPI 51 | #include 52 | #endif 53 | 54 | void turbo_test() 55 | { 56 | dump_turbo(stdout); 57 | 58 | static uint64_t sockets = 0; 59 | #ifndef IS_ARCH_2D 60 | int i; 61 | struct turbo_activation_ratio_data tar; 62 | struct turbo_limit_data tl, tl2; 63 | #endif 64 | 65 | if (!sockets) 66 | { 67 | core_config(NULL, NULL, &sockets, NULL); 68 | } 69 | 70 | #ifndef IS_ARCH_2D 71 | fprintf(stdout, "\n--- MSR_TURBO_ACTIVATION_RATIO ---\n"); 72 | for (i = 0; i < sockets; i++) 73 | { 74 | fprintf(stdout, "Socket %d:\n", i); 75 | get_max_turbo_activation_ratio(i, &tar); 76 | } 77 | 78 | fprintf(stdout, "\n--- MSR_TURBO_RATIO_LIMIT ---\n"); 79 | for (i = 0; i < sockets; i++) 80 | { 81 | fprintf(stdout, "Socket %d:\n", i); 82 | get_turbo_ratio_limit(i, &tl, &tl2); 83 | } 84 | #endif 85 | 86 | printf("\n"); 87 | } 88 | 89 | // TODO: check if test for oversized bitfield is in place, change that warning 90 | // to an error 91 | int main(int argc, char **argv) 92 | { 93 | struct rapl_data *rd = NULL; 94 | uint64_t *rapl_flags = NULL; 95 | uint64_t cores = 0; 96 | uint64_t threads = 0; 97 | uint64_t sockets = 0; 98 | int ri_stat = 0; 99 | 100 | if (!sockets) 101 | { 102 | core_config(&cores, &threads, &sockets, NULL); 103 | } 104 | 105 | if (init_msr()) 106 | { 107 | libmsr_error_handler("Unable to initialize libmsr", LIBMSR_ERROR_MSR_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 108 | return -1; 109 | } 110 | fprintf(stdout, "\n===== MSR Init Done =====\n"); 111 | 112 | ri_stat = rapl_init(&rd, &rapl_flags); 113 | if (ri_stat < 0) 114 | { 115 | libmsr_error_handler("Unable to initialize rapl", LIBMSR_ERROR_RAPL_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 116 | return -1; 117 | } 118 | fprintf(stdout, "\n===== RAPL Init Done =====\n"); 119 | 120 | fprintf(stdout, "\n===== Turbo Test =====\n"); 121 | turbo_test(); 122 | 123 | finalize_msr(); 124 | fprintf(stdout, "===== MSR Finalized =====\n"); 125 | 126 | fprintf(stdout, "\n===== Test Finished Successfully =====\n"); 127 | 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | # DEPRECATED 2 | ***Libmsr is no longer actively maintained -- libmsr has evolved into Variorum, which can be found on github: https://github.com/llnl/variorum.*** 3 | 4 | LIBMSR 5 | ====== 6 | 7 | [![Read the Docs](http://readthedocs.org/projects/hatchet/badge/?version=latest)](http://hatchet.readthedocs.io) 8 | 9 | Welcome to Libmsr, a friendly (well, friendlier) interface to many of the 10 | model-specific registers in Intel processors. Now with PCI configuration 11 | register support for some Intel hardware. 12 | 13 | version 0.3.1 14 | 15 | **Important** 16 | 17 | Libmsr is no longer being actively developed. Variorum 18 | https://variorum.readthedocs.io/ is an evolution of and a successor to 19 | libmsr. Variorum can be found on github: 20 | 21 | https://github.com/llnl/variorum 22 | 23 | 24 | Last Update 25 | ----------- 26 | 24 March 2020 27 | 28 | 29 | Webpages 30 | -------- 31 | http://software.llnl.gov/libmsr
32 | https://github.com/llnl/libmsr 33 | 34 | 35 | Overview 36 | -------- 37 | 38 | Libmsr provides an interface to accessing the model-specific registers (MSRs) 39 | on Intel platforms, which provide privileged functionality for monitoring and 40 | controlling various CPU features. 41 | 42 | 43 | Installation 44 | ------------ 45 | 46 | Installation is simple. You will need [CMAKE](http://www.cmake.org) version 2.8 47 | or higher and GCC. In most cases, the installation is as follows: 48 | 49 | $ cmake . -DCMAKE_INSTALL_PREFIX=${HOME}/build/libmsr 50 | $ make 51 | $ make install 52 | 53 | The installation depends on a `master.h` file, which defines the offsets for 54 | several MSRs given a particular architecture (e.g., Sandy Bridge, Ivy Bridge, 55 | Haswell, etc.). The auto-configuration tool can be forced to use the header 56 | file of a specific architecture or can auto-detect the architecture. To specify 57 | a particular architecture, run `cmake` with the option 58 | `-DLIBMSR_TARGET_ARCH=` where `ARG` is in hexadecimal. In the future, we 59 | plan to have a set of architecture-specific configuration files that can be 60 | pre-loaded to CMake to populate the cache. 61 | 62 | Currently supported architectures are Intel Xeon v1-3 (Sandy Bridge, Ivy 63 | Bridge, and Haswell server processors). The library technically supports all 64 | processors based on these architectures, but some features may be missing from 65 | client products. Using the wrong header file is likely to cause problems. 66 | 67 | Supported Architectures: 68 | 69 | 2D (Sandy Bridge) 57 (Knights Landing) 70 | 3E (Ivy Bridge) 71 | 3F (Haswell) 72 | 4F (Broadwell) 73 | 55 (Skylake)* 74 | 75 | If you are unsure of your architecture number, check the "model" field in `lscpu` 76 | or `/proc/cpuinfo` (note that it will not be in hexadecimal). 77 | 78 | *The Skylake support is currently experimental and requires more testing/validation. 79 | 80 | Notes 81 | ----- 82 | 83 | This software depends on the files `/dev/cpu/*/msr` being present. Recent 84 | kernels require additional capabilities. We have found it easier to use our own 85 | [MSR-SAFE](https://github.com/LLNL/msr-safe) kernel 86 | module with R/W permissions, but running as root (or going through the bother 87 | of adding the capabilities to the binaries) is another option. 88 | 89 | If you need PCI configuration register (CSR) support in Libmsr, you MUST have 90 | CSR-SAFE installed. This code is not currently on Github -- you will need to 91 | request it. 92 | 93 | Call `msr_init()` before using any of the APIs. 94 | 95 | For sample code, see `libmsr_test.c` in the `test/` directory. 96 | 97 | Our most up-to-date documentation for Libmsr can be generated with `make doc` 98 | and `make latex_doc` for HTML and PDF versions, respectively. There are also 99 | some useful PDF files in the `documentation/` directory. 100 | 101 | 102 | Contact 103 | ------- 104 | 105 | Barry Rountree, Project Lead,
106 | Stephanie Brink, Developer, 107 | 108 | Please feel free to contact the developers with any questions or feedback. 109 | 110 | We are collecting names of those who have previously contributed to libmsr over 111 | the years. See the current list in the `AUTHORS` file. Please contact the 112 | developers to have your name added to the list. 113 | 114 | 115 | Release 116 | ------- 117 | 118 | libmsr is released under the GPLv2.1 license. For more details, see the 119 | [LICENSE](https://github.com/LLNL/libmsr/blob/master/LICENSE) file. 120 | 121 | LLNL-CODE-645430 122 | -------------------------------------------------------------------------------- /src/libmsr_error.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "libmsr_error.h" 37 | 38 | void libmsr_error_message(int err, char *msg, size_t size) 39 | { 40 | switch (err) 41 | { 42 | case LIBMSR_ERROR_PLATFORM_NOT_SUPPORTED: 43 | strncpy(msg, " Feature not supported on this architecture", size); 44 | break; 45 | case LIBMSR_ERROR_ARRAY_BOUNDS: 46 | strncpy(msg, " Accessing element outside allocated bounds", size); 47 | break; 48 | case LIBMSR_ERROR_MSR_BATCH: 49 | strncpy(msg, " Could not perform MSR batch operation", size); 50 | break; 51 | case LIBMSR_ERROR_PLATFORM_ENV: 52 | strncpy(msg, " Invalid or incorrect architecture configuration", size); 53 | break; 54 | case LIBMSR_ERROR_MSR_MODULE: 55 | strncpy(msg, " Could not locate MSR device", size); 56 | break; 57 | case LIBMSR_ERROR_MSR_OPEN: 58 | strncpy(msg, " Could not open MSR device", size); 59 | break; 60 | case LIBMSR_ERROR_MSR_CLOSE: 61 | strncpy(msg, " Could not close MSR device", size); 62 | break; 63 | case LIBMSR_ERROR_MSR_READ: 64 | strncpy(msg, " Could not read MSR device", size); 65 | break; 66 | case LIBMSR_ERROR_MSR_WRITE: 67 | strncpy(msg, " Could not write MSR device", size); 68 | break; 69 | case LIBMSR_ERROR_RUNTIME: 70 | strncpy(msg, " Runtime error", size); 71 | break; 72 | case LIBMSR_ERROR_RAPL_INIT: 73 | strncpy(msg, " Could not initialize RAPL", size); 74 | break; 75 | case LIBMSR_ERROR_MSR_INIT: 76 | strncpy(msg, " Could not initialize MSR", size); 77 | break; 78 | case LIBMSR_ERROR_INVAL: 79 | strncpy(msg, " Invalid value", size); 80 | break; 81 | case LIBMSR_ERROR_NOT_IMPLEMENTED_YET: 82 | strncpy(msg, " This has not yet been implemented by libmsr", size); 83 | break; 84 | case LIBMSR_ERROR_MEMORY_ALLOCATION: 85 | strncpy(msg, " Could not allocate memory", size); 86 | break; 87 | case LIBMSR_ERROR_CSR_INIT: 88 | strncpy(msg, " Could not initialize CSR", size); 89 | break; 90 | case LIBMSR_ERROR_CSR_COUNTERS: 91 | strncpy(msg, " CSR performance counter error.", size); 92 | break; 93 | default: 94 | strncpy(msg, " Undefined error code", size); 95 | break; 96 | } 97 | if (size > 0) 98 | { 99 | msg[size-1] = '\0'; 100 | } 101 | } 102 | 103 | char *get_libmsr_error_message(int err) 104 | { 105 | char *brief_msg = (char *) malloc(NAME_MAX * sizeof(char)); 106 | if (err) 107 | { 108 | err = err; 109 | } 110 | else 111 | { 112 | err = LIBMSR_ERROR_RUNTIME; 113 | } 114 | libmsr_error_message(err, brief_msg, NAME_MAX); 115 | return brief_msg; 116 | } 117 | 118 | void libmsr_error_handler(const char *desc, int err, const char *host, const char *filename, int line) 119 | { 120 | fprintf(stderr, "Error: %s: %s: %s:%s::%d\n", get_libmsr_error_message(err), desc, host, filename, line); 121 | } 122 | -------------------------------------------------------------------------------- /test/read_rapl_data.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include "cpuid.h" 38 | #include "msr_core.h" 39 | #include "msr_rapl.h" 40 | #include "msr_thermal.h" 41 | #include "msr_counters.h" 42 | #include "msr_clocks.h" 43 | #include "msr_misc.h" 44 | #include "msr_turbo.h" 45 | #include "csr_core.h" 46 | #include "csr_imc.h" 47 | #include "libmsr_error.h" 48 | #ifdef MPI 49 | #include 50 | #endif 51 | 52 | struct rapl_limit l1, l2; 53 | 54 | void get_limits() 55 | { 56 | int i; 57 | static uint64_t sockets = 0; 58 | 59 | if (!sockets) 60 | { 61 | core_config(NULL, NULL, &sockets, NULL); 62 | } 63 | for (i = 0; i < sockets; i++) 64 | { 65 | if (i != 0) 66 | { 67 | fprintf(stdout, "\n"); 68 | } 69 | fprintf(stdout, "Socket %d:\n", i); 70 | if (get_pkg_rapl_limit(i, &l1, &l2) == 0) 71 | { 72 | fprintf(stdout, "Pkg Domain Power Lim 1 (lower lim)\n"); 73 | dump_rapl_limit(&l1, stdout); 74 | fprintf(stdout, "\n"); 75 | fprintf(stdout, "Pkg Domain Power Lim 2 (upper lim)\n"); 76 | dump_rapl_limit(&l2, stdout); 77 | } 78 | } 79 | } 80 | 81 | void rapl_r_test(struct rapl_data **rd) 82 | { 83 | poll_rapl_data(); 84 | fprintf(stdout, "Sample #1:\n"); 85 | dump_rapl_data(stdout); 86 | 87 | poll_rapl_data(); 88 | fprintf(stdout, "\nSample #2:\n"); 89 | dump_rapl_data(stdout); 90 | } 91 | 92 | #define PT_INC 100000 93 | 94 | int repeated_poll_test() 95 | { 96 | usleep(PT_INC); 97 | poll_rapl_data(); 98 | fprintf(stdout, "Sample #1:\n"); 99 | dump_rapl_data(stdout); 100 | usleep(PT_INC); 101 | poll_rapl_data(); 102 | fprintf(stdout, "\nSample #2:\n"); 103 | dump_rapl_data(stdout); 104 | usleep(PT_INC); 105 | poll_rapl_data(); 106 | fprintf(stdout, "\nSample #3:\n"); 107 | dump_rapl_data(stdout); 108 | usleep(PT_INC); 109 | poll_rapl_data(); 110 | fprintf(stdout, "\nSample #4:\n"); 111 | dump_rapl_data(stdout); 112 | usleep(PT_INC); 113 | poll_rapl_data(); 114 | fprintf(stdout, "\nSample #5:\n"); 115 | dump_rapl_data(stdout); 116 | usleep(PT_INC); 117 | poll_rapl_data(); 118 | fprintf(stdout, "\nSample #6:\n"); 119 | dump_rapl_data(stdout); 120 | return 0; 121 | } 122 | 123 | int main(int argc, char **argv) 124 | { 125 | struct rapl_data *rd = NULL; 126 | uint64_t *rapl_flags = NULL; 127 | uint64_t cores = 0; 128 | uint64_t threads = 0; 129 | uint64_t sockets = 0; 130 | int ri_stat = 0; 131 | 132 | if (!sockets) 133 | { 134 | core_config(&cores, &threads, &sockets, NULL); 135 | } 136 | if (init_msr()) 137 | { 138 | libmsr_error_handler("Unable to initialize libmsr", LIBMSR_ERROR_MSR_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 139 | return -1; 140 | } 141 | fprintf(stdout, "\n===== MSR Init Done =====\n"); 142 | 143 | ri_stat = rapl_init(&rd, &rapl_flags); 144 | if (ri_stat < 0) 145 | { 146 | libmsr_error_handler("Unable to initialize rapl", LIBMSR_ERROR_RAPL_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 147 | return -1; 148 | } 149 | fprintf(stdout, "\n===== RAPL Init Done =====\n"); 150 | 151 | fprintf(stdout, "\n===== POWER INFO =====\n"); 152 | dump_rapl_power_info(stdout); 153 | 154 | fprintf(stdout, "\n===== Get Initial RAPL Power Limits =====\n"); 155 | get_limits(); 156 | 157 | fprintf(stdout, "\n===== Poll RAPL Data 2X =====\n"); 158 | rapl_r_test(&rd); 159 | 160 | fprintf(stdout, "\n===== Repeated RAPL Polling Test =====\n"); 161 | repeated_poll_test(); 162 | 163 | finalize_msr(); 164 | fprintf(stdout, "===== MSR Finalized =====\n"); 165 | 166 | fprintf(stdout, "\n===== Test Finished Successfully =====\n"); 167 | 168 | return 0; 169 | } 170 | -------------------------------------------------------------------------------- /demoapps/powmon/power_wrapper_static.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Daniel Ellsworth , 7 | * Scott Walker , and 8 | * Kathleen Shoga . 9 | * 10 | * LLNL-CODE-645430 11 | * 12 | * All rights reserved. 13 | * 14 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 15 | * 16 | * Please also read libmsr/LICENSE for our notice and the LGPL. 17 | * 18 | * libmsr is free software: you can redistribute it and/or modify it under the 19 | * terms of the GNU Lesser General Public License (as published by the Free 20 | * Software Foundation) version 2.1 dated February 1999. 21 | * 22 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 23 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 24 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 25 | * General Public License for more details. 26 | * 27 | * You should have received a copy of the GNU Lesser General Public License 28 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 29 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 30 | */ 31 | 32 | #define _GNU_SOURCE 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #include "ghighres.c" 46 | #include "highlander.h" 47 | #include "rapl.h" 48 | 49 | /********/ 50 | /* RAPL */ 51 | /********/ 52 | static double total_joules = 0.0; 53 | static double limit_joules = 0.0; 54 | static double max_watts = 0.0; 55 | static double min_watts = 1024.0; 56 | 57 | /*************************/ 58 | /* HW Counter Structures */ 59 | /*************************/ 60 | static unsigned long start; 61 | static unsigned long end; 62 | static FILE *logfile = NULL; 63 | static double watt_cap = 0.0; 64 | 65 | static pthread_mutex_t mlock; 66 | static int *shmseg; 67 | static int shmid; 68 | 69 | static int running = 1; 70 | 71 | #include "common.c" 72 | 73 | int main(int argc, char **argv) 74 | { 75 | printf("starting wrapper\n"); 76 | if (argc < 3) 77 | { 78 | printf("Usage: %s ...\n", argv[0]); 79 | return 1; 80 | } 81 | 82 | if (highlander()) 83 | { 84 | /* Start the log file. */ 85 | int logfd; 86 | char hostname[64]; 87 | gethostname(hostname, 64); 88 | 89 | char *fname; 90 | int ret = asprintf(&fname, "%s.power.dat", hostname); 91 | if (ret < 0) 92 | { 93 | printf("Fatal Error: Cannot allocate memory for fname.\n"); 94 | return 1; 95 | } 96 | 97 | logfd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_NOATIME|O_NDELAY, S_IRUSR|S_IWUSR); 98 | if (logfd < 0) 99 | { 100 | printf("Fatal Error: %s on %s cannot open the appropriate fd.\n", argv[0], hostname); 101 | return 1; 102 | } 103 | logfile = fdopen(logfd, "w"); 104 | 105 | read_rapl_init(); 106 | 107 | /* Set the cap. */ 108 | watt_cap = strtod(argv[1], NULL); 109 | set_rapl_power(watt_cap, watt_cap); 110 | 111 | /* Start power measurement thread. */ 112 | pthread_t mthread; 113 | pthread_mutex_init(&mlock, NULL); 114 | pthread_create(&mthread, NULL, power_measurement, NULL); 115 | 116 | /* Fork. */ 117 | pid_t app_pid = fork(); 118 | if(app_pid == 0) 119 | { 120 | /* I'm the child. */ 121 | execvp(argv[2], &argv[2]); 122 | return 1; 123 | } 124 | /* Wait. */ 125 | waitpid(app_pid, NULL, 0); 126 | sleep(1); 127 | 128 | highlander_wait(); 129 | 130 | /* Stop power measurement thread. */ 131 | running = 0; 132 | take_measurement(); 133 | end = now_ms(); 134 | 135 | /* Output summary data. */ 136 | char *msg; 137 | ret = asprintf(&msg, "host: %s\npid: %d\ntotal: %lf\nallocated: %lf\nmax_watts: %lf\nmin_watts: %lf\nruntime ms: %lu\n,start: %lu\nend: %lu\n", hostname, app_pid, total_joules, limit_joules, max_watts, min_watts, end-start, start, end); 138 | 139 | if (ret < 0) 140 | { 141 | printf("Fatal Error: Cannot allocate memory for msg\n"); 142 | return 1; 143 | } 144 | fprintf(logfile, "%s", msg); 145 | fclose(logfile); 146 | close(logfd); 147 | shmctl(shmid, IPC_RMID, NULL); 148 | shmdt(shmseg); 149 | } 150 | else 151 | { 152 | /* Fork. */ 153 | pid_t app_pid = fork(); 154 | if (app_pid == 0) 155 | { 156 | /* I'm the child. */ 157 | execvp(argv[2], &argv[2]); 158 | return 1; 159 | } 160 | /* Wait. */ 161 | waitpid(app_pid, NULL, 0); 162 | 163 | highlander_wait(); 164 | } 165 | 166 | return 0; 167 | } 168 | -------------------------------------------------------------------------------- /include/libmsr_error.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #ifndef LIBMSR_ERROR_H_INCLUDE 32 | #define LIBMSR_ERROR_H_INCLUDE 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | #ifndef NAME_MAX 39 | #define NAME_MAX 1024 40 | #endif 41 | 42 | /// @brief Structure encompassing libmsr errors. 43 | enum libmsr_error_e 44 | { 45 | /// @brief Default error if value is 0 or -1. 46 | LIBMSR_ERROR_RUNTIME = -1, 47 | /// @brief Features not supported on a given platform (i.e., 48 | /// MSR_TURBO_BOOST_RATIO, PP1 power domain). 49 | LIBMSR_ERROR_PLATFORM_NOT_SUPPORTED = -2, 50 | /// @brief Accessing array index out of bounds. 51 | LIBMSR_ERROR_ARRAY_BOUNDS = -3, 52 | /// @brief MSR batch problems. 53 | LIBMSR_ERROR_MSR_BATCH = -4, 54 | /// @brief Platform hardware environment (i.e., num sockets, num cores, num 55 | /// threads). 56 | LIBMSR_ERROR_PLATFORM_ENV = -5, 57 | /// @brief Access msr or msr_batch modules. 58 | LIBMSR_ERROR_MSR_MODULE = -6, 59 | /// @brief Opening MSR file descriptors for reads/writes. 60 | LIBMSR_ERROR_MSR_OPEN = -7, 61 | /// @brief Closing MSR file descriptors. 62 | LIBMSR_ERROR_MSR_CLOSE = -8, 63 | /// @brief Reading MSRs. 64 | LIBMSR_ERROR_MSR_READ = -9, 65 | /// @brief Writing MSRs. 66 | LIBMSR_ERROR_MSR_WRITE = -10, 67 | /// @brief Initializing RAPL. 68 | LIBMSR_ERROR_RAPL_INIT = -11, 69 | /// @brief Initializing MSR. 70 | LIBMSR_ERROR_MSR_INIT = -12, 71 | /// @brief Invalid value in MSR. 72 | LIBMSR_ERROR_INVAL = -13, 73 | /// @brief Feature not yet implemented. 74 | LIBMSR_ERROR_NOT_IMPLEMENTED_YET = -14, 75 | /// @brief Memory allocation. 76 | LIBMSR_ERROR_MEMORY_ALLOCATION = -15, 77 | /// @brief Initializing CSRs. 78 | LIBMSR_ERROR_CSR_INIT = -16, 79 | /// @brief CSR counters. 80 | LIBMSR_ERROR_CSR_COUNTERS = -17, 81 | }; 82 | 83 | /// @brief Display error message to user. 84 | /// 85 | /// This is the generic libmsr error handling API. Use this function to report 86 | /// when errors arise. If an error is not defined in libmsr_error_e, add 87 | /// it to the aforementioned enum with the next sequential error code and 88 | /// define its brief error message in the / source file. 89 | /// 90 | /// @param [in] desc Extension to default libmsr error message. 91 | /// 92 | /// @param [in] err libmsr_error_e error code, positive values are system 93 | /// errors, negative values are libmsr errors. LIBMSR_ERROR_RUNTIME is 94 | /// assumed if error code is 0. 95 | /// 96 | /// @param [in] host Hostname environment variable. 97 | /// 98 | /// @param [in] filename Name of source file where error occurred (use standard 99 | /// predefined macro __FILE__). 100 | /// 101 | /// @param [in] line Line number in source file where error occurred (use 102 | /// standard predefined macro __LINE__). 103 | void libmsr_error_handler(const char *desc, 104 | int err, 105 | const char *host, 106 | const char *filename, 107 | int line); 108 | 109 | /// @brief Get brief libmsr error message based on error code. 110 | /// 111 | /// @param [in] err libmsr_error_e error code, positive values are system 112 | /// errors, negative values are libmsr errors. LIBMSR_ERROR_RUNTIME is 113 | /// assumed if error code is 0. 114 | /// 115 | /// @return Default libmsr error message. 116 | char *get_libmsr_error_message(int err); 117 | 118 | /// @brief Convert error code to brief libmsr error message. 119 | /// 120 | /// @param [in] err libmsr_error_e error code, positive values are system 121 | /// errors, negative values are libmsr errors. LIBMSR_ERROR_RUNTIME is 122 | /// assumed if error code is 0. 123 | /// 124 | /// @param [in] size Max length (in bytes) of brief libmsr error message. 125 | /// 126 | /// @param [out] msg Brief libmsr error message. 127 | void libmsr_error_message(int err, 128 | char *msg, 129 | size_t size); 130 | 131 | #ifdef __cplusplus 132 | } 133 | #endif 134 | #endif 135 | -------------------------------------------------------------------------------- /test/power_unit_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include "cpuid.h" 38 | #include "msr_core.h" 39 | #include "msr_rapl.h" 40 | #include "msr_thermal.h" 41 | #include "msr_counters.h" 42 | #include "msr_clocks.h" 43 | #include "msr_misc.h" 44 | #include "msr_turbo.h" 45 | #include "csr_core.h" 46 | #include "csr_imc.h" 47 | #include "libmsr_error.h" 48 | 49 | struct rapl_limit l1, l2; 50 | 51 | void get_limits() 52 | { 53 | int i; 54 | static uint64_t sockets = 0; 55 | 56 | if (!sockets) 57 | { 58 | core_config(NULL, NULL, &sockets, NULL); 59 | } 60 | for (i = 0; i < sockets; i++) 61 | { 62 | if (i != 0) 63 | { 64 | fprintf(stdout, "\n"); 65 | } 66 | fprintf(stdout, "Socket %d:\n", i); 67 | if (get_pkg_rapl_limit(i, &l1, &l2) == 0) 68 | { 69 | fprintf(stdout, "Pkg Domain Power Lim 1 (lower lim)\n"); 70 | dump_rapl_limit(&l1, stdout); 71 | fprintf(stdout, "\n"); 72 | fprintf(stdout, "Pkg Domain Power Lim 2 (upper lim)\n"); 73 | dump_rapl_limit(&l2, stdout); 74 | } 75 | } 76 | } 77 | 78 | void set_to_defaults() 79 | { 80 | int socket = 0; 81 | int numsockets = num_sockets(); 82 | struct rapl_power_info raplinfo; 83 | struct rapl_limit socketlim, socketlim2; 84 | 85 | for (socket = 0; socket < numsockets; socket++) 86 | { 87 | if (socket != 0) 88 | { 89 | fprintf(stdout, "\n"); 90 | } 91 | fprintf(stdout, "Socket %d:\n", socket); 92 | get_rapl_power_info(socket, &raplinfo); 93 | socketlim.bits = 0; 94 | socketlim.watts = raplinfo.pkg_therm_power; 95 | socketlim.seconds = 1; 96 | socketlim2.bits = 0; 97 | socketlim2.watts = raplinfo.pkg_therm_power * 1.2; 98 | socketlim2.seconds = 3; 99 | fprintf(stdout, "Pkg Domain Power Lim 1 (lower lim)\n"); 100 | dump_rapl_limit(&socketlim, stdout); 101 | fprintf(stdout, "\n"); 102 | fprintf(stdout, "Pkg Domain Power Lim 2 (upper lim)\n"); 103 | dump_rapl_limit(&socketlim2, stdout); 104 | set_pkg_rapl_limit(socket, &socketlim, &socketlim2); 105 | } 106 | } 107 | 108 | int main(int argc, char **argv) 109 | { 110 | struct rapl_data *rd = NULL; 111 | uint64_t *rapl_flags = NULL; 112 | uint64_t cores = 0; 113 | uint64_t threads = 0; 114 | uint64_t sockets = 0; 115 | int ri_stat = 0; 116 | 117 | if (!sockets) 118 | { 119 | core_config(&cores, &threads, &sockets, NULL); 120 | } 121 | 122 | if (init_msr()) 123 | { 124 | libmsr_error_handler("Unable to initialize libmsr", LIBMSR_ERROR_MSR_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 125 | return -1; 126 | } 127 | fprintf(stdout, "\n===== MSR Init Done =====\n"); 128 | 129 | ri_stat = rapl_init(&rd, &rapl_flags); 130 | if (ri_stat < 0) 131 | { 132 | libmsr_error_handler("Unable to initialize rapl", LIBMSR_ERROR_RAPL_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 133 | return -1; 134 | } 135 | fprintf(stdout, "\n===== RAPL Init Done =====\n"); 136 | 137 | fprintf(stdout, "\n===== Available RAPL Registers =====\n"); 138 | print_available_rapl(); 139 | 140 | fprintf(stdout, "\n===== Available Performance Counters =====\n"); 141 | print_available_counters(); 142 | 143 | fprintf(stdout, "\n===== POWER INFO =====\n"); 144 | dump_rapl_power_info(stdout); 145 | 146 | fprintf(stdout, "\n===== POWER UNIT =====\n"); 147 | dump_rapl_power_unit(stdout); 148 | 149 | fprintf(stdout, "\n===== Get Initial RAPL Power Limits =====\n"); 150 | get_limits(); 151 | 152 | fprintf(stdout, "\n===== Setting Defaults =====\n"); 153 | set_to_defaults(); 154 | 155 | finalize_msr(); 156 | fprintf(stdout, "\n===== MSR Finalized =====\n"); 157 | 158 | fprintf(stdout, "\n===== Test Finished Successfully =====\n"); 159 | if (ri_stat) 160 | { 161 | fprintf(stdout, "\nFound %d locked rapl register(s)\n", ri_stat); 162 | } 163 | 164 | return 0; 165 | } 166 | -------------------------------------------------------------------------------- /autoconf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | // This code will generate the correct header files for the target 32 | // architecture. 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #define FNAME_SIZE 128 42 | #define BUFFER_SIZE 512 43 | 44 | uint64_t detect_arch(void) 45 | { 46 | uint64_t rax = 1; 47 | uint64_t rbx = 0; 48 | uint64_t rcx = 0; 49 | uint64_t rdx = 0; 50 | 51 | asm volatile( 52 | "cpuid" 53 | : "=a" (rax), "=b" (rbx), "=c" (rcx), "=d" (rdx) 54 | : "0" (rax), "2" (rcx)); 55 | 56 | return ((rax >> 4) & 0xF) | ((rax >> 12) & 0xF0); 57 | } 58 | 59 | FILE *open_header(char *a) 60 | { 61 | FILE *header = NULL; 62 | char fname[FNAME_SIZE]; 63 | uint64_t arch = detect_arch(); 64 | 65 | if (a != NULL) { 66 | snprintf(fname, FNAME_SIZE, "platform_headers/Intel%s.h", a); 67 | } 68 | else { 69 | snprintf(fname, FNAME_SIZE, "platform_headers/Intel%lX.h", arch); 70 | } 71 | header = fopen(fname, "r"); 72 | if (header == NULL) { 73 | fprintf(stderr, "ERROR: unable to open file %s\n", fname); 74 | if (a != NULL) { 75 | fprintf(stderr, "Model %s may not be supported. No matching header files found in platform_headers/.\n", a); 76 | } 77 | else { 78 | fprintf(stderr, "Model %lx may not be supported. Use -f to force.\n", arch); 79 | } 80 | exit(-1); 81 | } 82 | return header; 83 | } 84 | 85 | FILE *open_master(void) 86 | { 87 | FILE *master = fopen("include/master.h", "w"); 88 | 89 | if (master == NULL) { 90 | fprintf(stderr, "ERROR: unable to open file include/master.h\n"); 91 | exit(-2); 92 | } 93 | return master; 94 | } 95 | 96 | int copy(char *arch) 97 | { 98 | FILE *header = open_header(arch); 99 | FILE *master = open_master(); 100 | char *buffer = (char *) malloc(BUFFER_SIZE * sizeof(char)); 101 | size_t bsize = BUFFER_SIZE; 102 | size_t ret = 0; 103 | 104 | fprintf(master, "// This file was generated automatically by autoconf.c\n"); 105 | fprintf(master, "// You should not modify it unless you really know what you're doing.\n"); 106 | 107 | while ((ret = getline(&buffer, &bsize, header)) != -1) { 108 | fprintf(master, "%s", buffer); 109 | } 110 | 111 | if (header != NULL) { 112 | fclose(header); 113 | } 114 | if (master != NULL) { 115 | fclose(master); 116 | } 117 | if (buffer != NULL) { 118 | free(buffer); 119 | } 120 | return 0; 121 | } 122 | 123 | int main(int argc, char **argv) 124 | { 125 | const char *usage = "\n" 126 | "NAME\n" 127 | " autoconf - Detect architecture model for MSR definitions\n" 128 | "SYNOPSIS\n" 129 | " %s [--help | -h] [-f]\n" 130 | "OVERVIEW\n" 131 | " Autoconf was built to determine the architecture model for\n" 132 | " which libmsr is being built on. The architecture determines\n" 133 | " the offsets for several MSRs, which may be architecture-specific.\n" 134 | "OPTIONS\n" 135 | " --help | -h\n" 136 | " Display this help information, then exit.\n" 137 | " -f\n" 138 | " Target architecture model.\n" 139 | "\n"; 140 | if (argc > 1 && (strncmp(argv[1], "--help", strlen("--help")) == 0 || 141 | strncmp(argv[1], "-h", strlen("-h")) == 0 )) { 142 | printf(usage, argv[0]); 143 | return EXIT_SUCCESS; 144 | } 145 | if (argc > 3) { 146 | printf(usage, argv[0]); 147 | return EXIT_FAILURE; 148 | } 149 | /* Auto-detect architecture model. */ 150 | if (argc == 1) { 151 | copy(NULL); 152 | return EXIT_SUCCESS; 153 | } 154 | 155 | int opt; 156 | while ((opt = getopt(argc, argv, "f:")) != -1) { 157 | switch(opt) { 158 | case 'f': 159 | copy(optarg); 160 | break; 161 | default: 162 | fprintf(stderr, "\nError: unknown parameter \"%c\"\n", opt); 163 | fprintf(stderr, usage, argv[0]); 164 | return EXIT_FAILURE; 165 | } 166 | } 167 | return EXIT_SUCCESS; 168 | } 169 | -------------------------------------------------------------------------------- /include/msr_clocks.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #ifndef MSR_CLOCKS_H_INCLUDE 32 | #define MSR_CLOCKS_H_INCLUDE 33 | 34 | #include 35 | 36 | #include "master.h" 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | /// @brief Structure containing data for IA32_CLOCK_MODULATION. 43 | /// 44 | /// There is a bit at 0 that can be used for Extended On-Demand Clock 45 | /// Modulation Duty Cycle. It is added with the bits 3:1. When used, the 46 | /// granularity of clock modulation duty cycle is increased to 6.25% as opposed 47 | /// to 12.5%. To enable this, must have CPUID.06H:EAX[Bit 5] = 1. I am not sure 48 | /// how to check that because otherwise bit 0 is reserved. 49 | struct clock_mod 50 | { 51 | /// @brief Raw 64-bit value stored in IA32_CLOCK_MODULATION. 52 | uint64_t raw; 53 | /// @brief Enable/disable on-demand software-controlled clock modulation. 54 | int duty_cycle_enable; 55 | /// @brief On-demand clock modulation duty cycle. 56 | int duty_cycle; 57 | // Value | Duty Cycle 58 | // 000b = 0 | Reserved 59 | // 001b = 1 | 12.5% (default) 60 | // 010b = 2 | 25.0% 61 | // 011b = 3 | 37.5% 62 | // 100b = 4 | 50.0% 63 | // 101b = 5 | 63.5% 64 | // 110b = 6 | 75.0% 65 | // 111b = 7 | 87.5% 66 | }; 67 | 68 | /// @brief Structure containing data for IA32_APERF, IA32_MPERF, and 69 | /// IA32_TIME_STAMP_COUNTER. 70 | struct clocks_data 71 | { 72 | /// @brief Raw 64-bit value stored in IA32_APERF. 73 | uint64_t **aperf; 74 | /// @brief Raw 64-bit value stored in IA32_MPERF. 75 | uint64_t **mperf; 76 | /// @brief Raw 64-bit value stored in IA32_TIME_STAMP_COUNTER. 77 | uint64_t **tsc; 78 | }; 79 | 80 | /// @brief Structure containing data for IA32_PERF_STATUS and IA32_PERF_CTL. 81 | struct perf_data 82 | { 83 | /// @brief Raw 64-bit value stored in IA32_PERF_STATUS. 84 | uint64_t **perf_status; 85 | /// @brief Raw 64-bit value stored in IA32_PERF_CTL. 86 | uint64_t **perf_ctl; 87 | }; 88 | 89 | /// @brief Allocate array for storing raw register data from IA32_APERF, 90 | /// IA32_MPERF, and IA32_TIME_STAMP_COUNTER. 91 | /// 92 | /// There are plans to use a struct to make the indirection less crazy. 93 | /// 94 | /// @param [in] cd Pointer to clock-related data. 95 | void clocks_storage(struct clocks_data **cd); 96 | 97 | /// @brief Allocate array for storing raw register data from IA32_PERF_STATUS 98 | /// and IA32_PERF_CTL. 99 | /// 100 | /// @param [in] pd Pointer to perf-related data. 101 | void perf_storage(struct perf_data **pd); 102 | 103 | /// @brief Print the label for the abbreviated clocks data print out. 104 | /// 105 | /// @param [in] writedest File stream where output will be written to. 106 | void dump_clocks_data_terse_label(FILE *writedest); 107 | 108 | /// @brief Print abbreviated clocks data. 109 | /// 110 | /// @param [in] writedest File stream where output will be written to. 111 | void dump_clocks_data_terse(FILE *writedest); 112 | 113 | /// @brief Print current p-state. 114 | /// 115 | /// @param [in] writedest File stream where output will be written to. 116 | void dump_p_state(FILE *writedest); 117 | 118 | /// @brief Request new current p-state. 119 | /// 120 | /// @param [in] socket Unique socket/package identifier. 121 | /// 122 | /// @param [in] pstate Desired p-state. 123 | void set_p_state(unsigned socket, 124 | uint64_t pstate); 125 | 126 | /// @brief Print detailed clocks data. 127 | /// 128 | /// @param [in] writedest File stream where output will be written to. 129 | void dump_clocks_data_readable(FILE *writedest); 130 | 131 | /****************************************/ 132 | /* Software Controlled Clock Modulation */ 133 | /****************************************/ 134 | 135 | /// @brief Print clock modulation data. 136 | /// 137 | /// @param [in] s Data for clock modulation. 138 | /// 139 | /// @param [in] writedest File stream where output will be written to. 140 | void dump_clock_mod(struct clock_mod *s, 141 | FILE *writedest); 142 | 143 | /// @brief Get contents of IA32_CLOCK_MODULATION. 144 | /// 145 | /// @param [in] socket Unique socket/package identifier. 146 | /// 147 | /// @param [in] core Unique core identifier. 148 | /// 149 | /// @param [out] s Data for clock modulation. 150 | void get_clock_mod(int socket, 151 | int core, 152 | struct clock_mod *s); 153 | 154 | /// @brief Change value of IA32_CLOCK_MODULATION. 155 | /// 156 | /// @param [in] socket Unique socket/package identifier. 157 | /// 158 | /// @param [in] core Unique core identifier. 159 | /// 160 | /// @param [in] s Data for clock modulation. 161 | int set_clock_mod(int socket, 162 | int core, 163 | struct clock_mod *s); 164 | 165 | #ifdef __cplusplus 166 | } 167 | #endif 168 | #endif 169 | -------------------------------------------------------------------------------- /src/memhdlr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | #include "memhdlr.h" 35 | #include "libmsr_error.h" 36 | #include "libmsr_debug.h" 37 | 38 | void *libmsr_malloc(size_t size) 39 | { 40 | void *result = malloc(size); 41 | #ifdef MEMHDLR_DEBUG 42 | fprintf(stderr, "MEMHDLR: (malloc) allocated new array at %p\n", result); 43 | #endif 44 | if (result == NULL) 45 | { 46 | libmsr_error_handler("libmsr_malloc(): malloc failed.", LIBMSR_ERROR_MEMORY_ALLOCATION, getenv("HOSTNAME"), __FILE__, __LINE__); 47 | exit(-1); 48 | } 49 | memory_handler(result, NULL, LIBMSR_MALLOC); 50 | return result; 51 | } 52 | 53 | void *libmsr_calloc(size_t num, size_t size) 54 | { 55 | void *result = calloc(num, size); 56 | #ifdef MEMHDLR_DEBUG 57 | fprintf(stderr, "MEMHDLR: (calloc) allocated new array at %p\n", result); 58 | #endif 59 | if (result == NULL) 60 | { 61 | libmsr_error_handler("libmsr_calloc(): calloc failed.", LIBMSR_ERROR_MEMORY_ALLOCATION, getenv("HOSTNAME"), __FILE__, __LINE__); 62 | exit(-1); 63 | } 64 | memory_handler(result, NULL, LIBMSR_CALLOC); 65 | return result; 66 | } 67 | 68 | void *libmsr_realloc(void *addr, size_t size) 69 | { 70 | void *result = realloc(addr, size); 71 | #ifdef MEMHDLR_DEBUG 72 | fprintf(stderr, "MEMHDLR: (realloc) allocated new array at %p (from %p) with new size %lu\n", result, addr, size); 73 | #endif 74 | if (result == NULL) 75 | { 76 | libmsr_error_handler("libmsr_realloc(): realloc failed.", LIBMSR_ERROR_MEMORY_ALLOCATION, getenv("HOSTNAME"), __FILE__, __LINE__); 77 | exit(-1); 78 | } 79 | memory_handler(result, addr, LIBMSR_REALLOC); 80 | return result; 81 | } 82 | 83 | void *libmsr_free(void *addr) 84 | { 85 | memory_handler(NULL, addr, LIBMSR_FREE); 86 | return NULL; 87 | } 88 | 89 | void *memhdlr_finalize(void) 90 | { 91 | memory_handler(NULL, NULL, LIBMSR_FINALIZE); 92 | return NULL; 93 | } 94 | 95 | int memory_handler(void *address, void *oldaddr, int type) 96 | { 97 | static void **arrays = NULL; 98 | static unsigned last = 0; 99 | static unsigned size = 16; 100 | int i; 101 | 102 | switch (type) 103 | { 104 | case LIBMSR_FINALIZE: 105 | for (i = 0; i < last; i++) 106 | { 107 | if (arrays[i] != NULL) 108 | { 109 | #ifdef MEMHDLR_DEBUG 110 | fprintf(stderr, "MEMHDLR: data at %p (number %d) has been deallocated\n", arrays[i], i); 111 | fprintf(stderr, "\tlast is %d, size is %d\n", last, size); 112 | #endif 113 | free(arrays[i]); 114 | } 115 | } 116 | if (arrays != NULL) 117 | { 118 | free(arrays); 119 | } 120 | return 0; 121 | case LIBMSR_REALLOC: 122 | #ifdef MEMHDLR_DEBUG 123 | fprintf(stderr, "MEMHDLR: received address %p, (realloc %p)\n", address, oldaddr); 124 | #endif 125 | for (i = 0; i < last; i++) 126 | { 127 | if (arrays[i] == oldaddr) 128 | { 129 | arrays[i] = address; 130 | } 131 | } 132 | return 0; 133 | case LIBMSR_FREE: 134 | for (i = 0; i < last; i++) 135 | { 136 | if (arrays[i] == oldaddr) 137 | { 138 | free(oldaddr); 139 | arrays[i] = NULL; 140 | } 141 | } 142 | return 0; 143 | case LIBMSR_CALLOC: 144 | case LIBMSR_MALLOC: 145 | if (arrays == NULL) 146 | { 147 | arrays = (void **) malloc(size * sizeof(void *)); 148 | if (arrays == NULL) 149 | { 150 | libmsr_error_handler("memory_handler(): malloc failed.", LIBMSR_ERROR_MEMORY_ALLOCATION, getenv("HOSTNAME"), __FILE__, __LINE__); 151 | exit(-1); 152 | } 153 | } 154 | #ifdef MEMHDLR_DEBUG 155 | fprintf(stderr, "MEMHDLR: arrays tracker is at %p\n", arrays); 156 | #endif 157 | if (last >= size) 158 | { 159 | void **temp = arrays; 160 | size *= 2; 161 | temp = (void **) realloc(arrays, size * sizeof(void *)); 162 | if (temp == NULL) 163 | { 164 | libmsr_error_handler("memory_handler(): realloc failed.", LIBMSR_ERROR_MEMORY_ALLOCATION, getenv("HOSTNAME"), __FILE__, __LINE__); 165 | exit(-1); 166 | } 167 | arrays = temp; 168 | } 169 | if (address != NULL) 170 | { 171 | arrays[last] = address; 172 | last++; 173 | } 174 | return 0; 175 | } 176 | return 0; 177 | } 178 | -------------------------------------------------------------------------------- /demoapps/powmon/power_wrapper_dynamic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Daniel Ellsworth , 7 | * Scott Walker , and 8 | * Kathleen Shoga . 9 | * 10 | * LLNL-CODE-645430 11 | * 12 | * All rights reserved. 13 | * 14 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 15 | * 16 | * Please also read libmsr/LICENSE for our notice and the LGPL. 17 | * 18 | * libmsr is free software: you can redistribute it and/or modify it under the 19 | * terms of the GNU Lesser General Public License (as published by the Free 20 | * Software Foundation) version 2.1 dated February 1999. 21 | * 22 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 23 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 24 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 25 | * General Public License for more details. 26 | * 27 | * You should have received a copy of the GNU Lesser General Public License 28 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 29 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 30 | */ 31 | 32 | #define _GNU_SOURCE 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #include "ghighres.c" 46 | #include "highlander.h" 47 | #include "rapl.h" 48 | //#include "../config.h" 49 | 50 | /********/ 51 | /* RAPL */ 52 | /********/ 53 | static double total_joules = 0.0; 54 | static double limit_joules = 0.0; 55 | static double max_watts = 0.0; 56 | static double min_watts = 1024.0; 57 | 58 | static unsigned long start; 59 | static unsigned long end; 60 | static FILE *logfile = NULL; 61 | static double watt_cap = 0.0; 62 | static volatile int poll_num = 0; 63 | static volatile int poll_dir = 5; 64 | 65 | static pthread_mutex_t mlock; 66 | static int *shmseg; 67 | static int shmid; 68 | 69 | static int running = 1; 70 | 71 | #include "common.c" 72 | 73 | void *power_set_measurement(void *arg) 74 | { 75 | unsigned long poll_num = 0; 76 | struct mstimer timer; 77 | set_rapl_power(watt_cap, watt_cap); 78 | double watts = watt_cap; 79 | // According to the Intel docs, the counter wraps a most once per second. 80 | // 100 ms should be short enough to always get good information. 81 | init_msTimer(&timer, 1500); 82 | init_data(); 83 | start = now_ms(); 84 | 85 | poll_num++; 86 | timer_sleep(&timer); 87 | while (running) 88 | { 89 | take_measurement(); 90 | if (poll_num%5 == 0) 91 | { 92 | if (watts >= watt_cap) 93 | { 94 | poll_dir = -5; 95 | } 96 | if (watts <= 30) 97 | { 98 | poll_dir = 5; 99 | } 100 | watts += poll_dir; 101 | set_rapl_power(watts, watts); 102 | } 103 | poll_num++; 104 | timer_sleep(&timer); 105 | } 106 | } 107 | 108 | int main(int argc, char**argv) 109 | { 110 | printf("starting wrapper\n"); 111 | if (argc < 3) 112 | { 113 | printf("Usage: %s ...\n", argv[0]); 114 | return 1; 115 | } 116 | 117 | if (highlander()) 118 | { 119 | /* Start the log file. */ 120 | int logfd; 121 | char hostname[64]; 122 | gethostname(hostname, 64); 123 | 124 | char *fname; 125 | int ret = asprintf(&fname, "%s.power.dat", hostname); 126 | if (ret < 0) 127 | { 128 | printf("Fatal Error: Cannot allocate memory for fname.\n"); 129 | return 1; 130 | } 131 | 132 | logfd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_NOATIME|O_NDELAY, S_IRUSR|S_IWUSR); 133 | if (logfd < 0) 134 | { 135 | printf("Fatal Error: %s on %s cannot open the appropriate fd.\n", argv[0], hostname); 136 | return 1; 137 | } 138 | logfile = fdopen(logfd, "w"); 139 | 140 | read_rapl_init(); 141 | 142 | /* Set the cap. */ 143 | watt_cap = strtod(argv[1], NULL); 144 | set_rapl_power(watt_cap, watt_cap); 145 | 146 | /* Start power measurement thread. */ 147 | pthread_t mthread; 148 | pthread_create(&mthread, NULL, power_set_measurement, NULL); 149 | 150 | /* Fork. */ 151 | pid_t app_pid = fork(); 152 | if (app_pid == 0) 153 | { 154 | /* I'm the child. */ 155 | execvp(argv[2], &argv[2]); 156 | return 1; 157 | } 158 | /* Wait. */ 159 | waitpid(app_pid, NULL, 0); 160 | sleep(1); 161 | 162 | highlander_wait(); 163 | 164 | /* Stop power measurement thread. */ 165 | running = 0; 166 | take_measurement(); 167 | end = now_ms(); 168 | 169 | /* Output summary data. */ 170 | char *msg; 171 | ret = asprintf(&msg, "host: %s\npid: %d\ntotal: %lf\nallocated: %lf\nmax_watts: %lf\nmin_watts: %lf\nruntime ms: %lu\n,start: %lu\nend: %lu\n", hostname, app_pid, total_joules, limit_joules, max_watts, min_watts, end-start, start, end); 172 | if (ret < 0) 173 | { 174 | printf("Fatal Error: Cannot allocate memory for msg.\n"); 175 | return 1; 176 | } 177 | 178 | fprintf(logfile, "%s", msg); 179 | fclose(logfile); 180 | close(logfd); 181 | shmctl(shmid, IPC_RMID, NULL); 182 | shmdt(shmseg); 183 | } 184 | else 185 | { 186 | /* Fork. */ 187 | pid_t app_pid = fork(); 188 | if (app_pid == 0) 189 | { 190 | /* I'm the child. */ 191 | execvp(argv[2], &argv[2]); 192 | return 1; 193 | } 194 | /* Wait. */ 195 | waitpid(app_pid, NULL, 0); 196 | 197 | highlander_wait(); 198 | } 199 | 200 | return 0; 201 | } 202 | -------------------------------------------------------------------------------- /test/translate_pkg_rapl_limit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include "cpuid.h" 38 | #include "msr_core.h" 39 | #include "msr_rapl.h" 40 | #include "msr_thermal.h" 41 | #include "msr_counters.h" 42 | #include "msr_clocks.h" 43 | #include "msr_misc.h" 44 | #include "msr_turbo.h" 45 | #include "csr_core.h" 46 | #include "csr_imc.h" 47 | #include "libmsr_error.h" 48 | 49 | struct rapl_limit l1, l2, l3; 50 | 51 | void get_limits() 52 | { 53 | int i; 54 | static uint64_t sockets = 0; 55 | 56 | if (!sockets) 57 | { 58 | core_config(NULL, NULL, &sockets, NULL); 59 | } 60 | for (i = 0; i < sockets; i++) 61 | { 62 | if (i != 0) 63 | { 64 | fprintf(stdout, "\n"); 65 | } 66 | fprintf(stdout, "Socket %d:\n", i); 67 | if (get_pkg_rapl_limit(i, &l1, &l2) == 0) 68 | { 69 | fprintf(stdout, "Pkg Domain Power Lim 1 (lower lim)\n"); 70 | dump_rapl_limit(&l1, stdout); 71 | fprintf(stdout, "\n"); 72 | fprintf(stdout, "Pkg Domain Power Lim 2 (upper lim)\n"); 73 | dump_rapl_limit(&l2, stdout); 74 | } 75 | } 76 | } 77 | 78 | void test_pkg_lower_limit(unsigned s) 79 | { 80 | struct rapl_power_info raplinfo; 81 | double power_cap_percentage = 0.7; 82 | get_rapl_power_info(s, &raplinfo); 83 | 84 | double power_cap = raplinfo.pkg_therm_power * power_cap_percentage; 85 | printf("Setting socket %d PL1 to %.1fW (%.0f%%)\n", s, power_cap, power_cap_percentage*100); 86 | l1.watts = 95; 87 | l1.seconds = 1; 88 | l1.bits = 0; 89 | set_pkg_rapl_limit(s, &l1, NULL); 90 | get_limits(); 91 | } 92 | 93 | void test_pkg_upper_limit(unsigned s) 94 | { 95 | struct rapl_power_info raplinfo; 96 | double power_cap_percentage = 0.9; 97 | get_rapl_power_info(s, &raplinfo); 98 | 99 | double power_cap = raplinfo.pkg_therm_power * power_cap_percentage; 100 | printf("Setting socket %d PL2 to %.1fW (%.0f%%)\n", s, power_cap, power_cap_percentage*100); 101 | l2.watts = power_cap; 102 | l2.seconds = 9; 103 | l2.bits = 0; 104 | set_pkg_rapl_limit(s, NULL, &l2); 105 | get_limits(); 106 | } 107 | 108 | void set_to_defaults() 109 | { 110 | int socket = 0; 111 | int numsockets = num_sockets(); 112 | struct rapl_power_info raplinfo; 113 | struct rapl_limit socketlim, socketlim2; 114 | 115 | for (socket = 0; socket < numsockets; socket++) 116 | { 117 | if (socket != 0) 118 | { 119 | fprintf(stdout, "\n"); 120 | } 121 | fprintf(stdout, "Socket %d:\n", socket); 122 | get_rapl_power_info(socket, &raplinfo); 123 | socketlim.bits = 0; 124 | socketlim.watts = raplinfo.pkg_therm_power; 125 | socketlim.seconds = 1; 126 | socketlim2.bits = 0; 127 | socketlim2.watts = raplinfo.pkg_therm_power * 1.2; 128 | socketlim2.seconds = 3; 129 | fprintf(stdout, "Pkg Domain Power Lim 1 (lower lim)\n"); 130 | dump_rapl_limit(&socketlim, stdout); 131 | fprintf(stdout, "\n"); 132 | fprintf(stdout, "Pkg Domain Power Lim 2 (upper lim)\n"); 133 | dump_rapl_limit(&socketlim2, stdout); 134 | set_pkg_rapl_limit(socket, &socketlim, &socketlim2); 135 | } 136 | } 137 | 138 | int main(int argc, char **argv) 139 | { 140 | struct rapl_data *rd = NULL; 141 | uint64_t *rapl_flags = NULL; 142 | uint64_t cores = 0; 143 | uint64_t threads = 0; 144 | uint64_t sockets = 0; 145 | int ri_stat = 0; 146 | unsigned i; 147 | 148 | if (!sockets) 149 | { 150 | core_config(&cores, &threads, &sockets, NULL); 151 | } 152 | 153 | if (init_msr()) 154 | { 155 | libmsr_error_handler("Unable to initialize libmsr", LIBMSR_ERROR_MSR_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 156 | return -1; 157 | } 158 | fprintf(stdout, "\n===== MSR Init Done =====\n"); 159 | 160 | ri_stat = rapl_init(&rd, &rapl_flags); 161 | if (ri_stat < 0) 162 | { 163 | libmsr_error_handler("Unable to initialize rapl", LIBMSR_ERROR_RAPL_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 164 | return -1; 165 | } 166 | fprintf(stdout, "\n===== RAPL Init Done =====\n"); 167 | 168 | fprintf(stdout, "\n===== Get Initial RAPL Power Limits =====\n"); 169 | get_limits(); 170 | 171 | for (i = 0; i < sockets; i++) 172 | { 173 | fprintf(stdout, "\n===== Start Socket %u RAPL Power Limit Test =====\n", i); 174 | fprintf(stdout, "\n--- Testing Pkg Domain Lower Limit ---\n"); 175 | test_pkg_lower_limit(i); 176 | fprintf(stdout, "\n--- Testing Pkg Domain Upper Limit ---\n"); 177 | test_pkg_upper_limit(i); 178 | fprintf(stdout, "\n===== End Socket %u RAPL Power Limit Test =====\n", i); 179 | } 180 | 181 | fprintf(stdout, "\n===== Setting Defaults =====\n"); 182 | set_to_defaults(); 183 | 184 | finalize_msr(); 185 | fprintf(stdout, "===== MSR Finalized =====\n"); 186 | 187 | fprintf(stdout, "\n===== Test Finished Successfully =====\n"); 188 | if (ri_stat) 189 | { 190 | fprintf(stdout, "\nFound %d locked rapl register(s)\n", ri_stat); 191 | } 192 | 193 | return 0; 194 | } 195 | -------------------------------------------------------------------------------- /include/msr_turbo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #ifndef MSR_TURBO_H_INCLUDE 32 | #define MSR_TURBO_H_INCLUDE 33 | 34 | #include 35 | 36 | #include "master.h" 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | /// @brief Structure containing data for MSR_TURBO_ACTIVATION_RATIO. 43 | struct turbo_activation_ratio_data 44 | { 45 | /// @brief Raw 64-bit value stored in MSR_TURBO_ACTIVATION RATIO. 46 | uint64_t bits; 47 | /// @brief Max non-turbo ratio bit-field (bits [7:0]) converted to a 48 | /// p-state in MHz. 49 | double max_non_turbo_ratio; 50 | }; 51 | 52 | /// @brief Structure holding data from the turbo ratio limit register(s). 53 | /// 54 | /// Structure can hold data from MSR_TURBO_RATIO_LIMIT and 55 | /// MSR_TURBO_RATIO_LIMIT1, the latter will exist depending on the number 56 | /// of physical cores in the platform (i.e., server products). 57 | struct turbo_limit_data 58 | { 59 | /// @brief Raw 64-bit value stored in turbo ratio limit register. 60 | uint64_t bits; 61 | /// @brief Max turbo ratio (in MHz) when 1 core (or 9 cores) is/are active. 62 | double max_1c; 63 | /// @brief Max turbo ratio (in MHz) when 2/10 cores are active. 64 | double max_2c; 65 | /// @brief Max turbo ratio (in MHz) when 3/11 cores are active. 66 | double max_3c; 67 | /// @brief Max turbo ratio (in MHz) when 4/12 cores are active. 68 | double max_4c; 69 | /// @brief Max turbo ratio (in MHz) when 5/13 cores are active. 70 | double max_5c; 71 | /// @brief Max turbo ratio (in MHz) when 6/14 cores are active. 72 | double max_6c; 73 | /// @brief Max turbo ratio (in MHz) when 7/15 cores are active. 74 | double max_7c; 75 | /// @brief Max turbo ratio (in MHz) when 8/16 cores are active. 76 | double max_8c; 77 | }; 78 | 79 | /// @brief Allocate array for storing raw register data from IA32_PERF_CTL. 80 | /// 81 | /// There are plans to use a struct to make the indirection less crazy. 82 | /// 83 | /// @param [in] val Pointer to array of raw IA32_PERF_CTL data, length equal to 84 | /// the total number of logical processors. 85 | void turbo_storage(uint64_t ***val); 86 | 87 | /// @brief Enable turbo by modifying IA32_PERF_CTL on each logical processor. 88 | /// 89 | /// Enable Intel Dynamic Acceleration (IDA) and Intel Turbo Boost Technology by 90 | /// setting bit 32 of IA32_PERF_CTL to 0. This bit is not shared across logical 91 | /// processors in a package, so it must be modified to the same value across 92 | /// all logical processors in the same package. 93 | void enable_turbo(void); 94 | 95 | /// @brief Disable turbo by modifying IA32_PERF_CTL on each logical processor. 96 | /// 97 | /// Disable Intel Dynamic Acceleration (IDA) and Intel Turbo Boost Technology by 98 | /// setting bit 32 of IA32_PERF_CTL to 1. This bit is not shared across logical 99 | /// processors in a package, so it must be modified to the same value across 100 | /// all logical processors in the same package. 101 | void disable_turbo(void); 102 | 103 | /// @brief Print turbo data for each logical processor. 104 | /// 105 | /// For each logical processor, print the unique core identifier, the value of 106 | /// bit 32 for IA32_PERF_CTL (1 indicates IDA/Turbo Boost is enabled) and the 107 | /// value of bit 38 for IA32_MISC_ENABLE (1 indicates support for IDA/Turbo 108 | /// Boost by the platform). 109 | /// 110 | /// @param [in] writedest File stream where output will be written to. 111 | void dump_turbo(FILE *writedest); 112 | 113 | /// @brief Convert raw bits of MSR_TURBO_ACTIVATION_RATIO to human-readable 114 | /// values. 115 | /// 116 | /// @param [in] socket Unique socket/package identifier. 117 | /// 118 | /// @param [out] info Data for turbo activation ratio. 119 | void calc_max_non_turbo(const unsigned socket, 120 | struct turbo_activation_ratio_data *info); 121 | 122 | /// @brief Read value of the MSR_TURBO_ACTIVATION_RATIO register and translate 123 | /// bit fields to human-readable values. 124 | /// 125 | /// @param [in] socket Unique socket/package identifier. 126 | /// 127 | /// @param [out] info Data for turbo activation ratio. 128 | /// 129 | /// @return 0 if successful, else -1 if rapl_storage() fails. 130 | int get_max_turbo_activation_ratio(const unsigned socket, 131 | struct turbo_activation_ratio_data *info); 132 | 133 | /// @brief Convert raw bits of turbo ratio limit register to human-readable 134 | /// values. 135 | /// 136 | /// @param [in] socket Unique socket/package identifier. 137 | /// 138 | /// @param [out] info Data for turbo ratio limit. 139 | /// 140 | /// @param [out] info2 Data for turbo ratio limit 1 (platform dependent). 141 | void calc_max_turbo_ratio(const unsigned socket, 142 | struct turbo_limit_data *info, 143 | struct turbo_limit_data *info2); 144 | 145 | /// @brief Read value of the turbo ratio limit register and translate bit 146 | /// fields to human-readable values. 147 | /// 148 | /// @param [in] socket Unique socket/package identifier. 149 | /// 150 | /// @param [out] info Data for turbo ratio limit. 151 | /// 152 | /// @param [out] info2 Data for turbo ratio limit 1 (platform dependent). 153 | /// 154 | /// @return 0 if successful, else -1 if rapl_storage() fails. 155 | int get_turbo_ratio_limit(const unsigned socket, 156 | struct turbo_limit_data *info, 157 | struct turbo_limit_data *info2); 158 | 159 | #ifdef __cplusplus 160 | } 161 | #endif 162 | #endif 163 | -------------------------------------------------------------------------------- /demoapps/powmon/powmon.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Daniel Ellsworth , 7 | * Scott Walker , and 8 | * Kathleen Shoga . 9 | * 10 | * LLNL-CODE-645430 11 | * 12 | * All rights reserved. 13 | * 14 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 15 | * 16 | * Please also read libmsr/LICENSE for our notice and the LGPL. 17 | * 18 | * libmsr is free software: you can redistribute it and/or modify it under the 19 | * terms of the GNU Lesser General Public License (as published by the Free 20 | * Software Foundation) version 2.1 dated February 1999. 21 | * 22 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 23 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 24 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 25 | * General Public License for more details. 26 | * 27 | * You should have received a copy of the GNU Lesser General Public License 28 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 29 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 30 | */ 31 | 32 | #define _GNU_SOURCE 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include 47 | #include 48 | #include "ghighres.c" 49 | #include "highlander.h" 50 | #include "rapl.h" 51 | 52 | /********/ 53 | /* RAPL */ 54 | /********/ 55 | static double total_joules = 0.0; 56 | static double limit_joules = 0.0; 57 | static double max_watts = 0.0; 58 | static double min_watts = 1024.0; 59 | 60 | /*************************/ 61 | /* HW Counter Structures */ 62 | /*************************/ 63 | static unsigned long start; 64 | static unsigned long end; 65 | static FILE *logfile = NULL; 66 | static FILE *summaryfile = NULL; 67 | 68 | static pthread_mutex_t mlock; 69 | static int *shmseg; 70 | static int shmid; 71 | 72 | static int running = 1; 73 | 74 | #include "common.c" 75 | 76 | int main(int argc, char **argv) 77 | { 78 | const char *usage = "\n" 79 | "NAME\n" 80 | " powmon - Package and DRAM power monitor\n" 81 | "SYNOPSIS\n" 82 | " %s [--help | -h] [-c] ...\n" 83 | "OVERVIEW\n" 84 | " Powmon is a utility for sampling and printing the\n" 85 | " power consumption (for package and DRAM) and power\n" 86 | " limit per socket for systems with two sockets.\n" 87 | "OPTIONS\n" 88 | " --help | -h\n" 89 | " Display this help information, then exit.\n" 90 | " -c\n" 91 | " Remove stale shared memory.\n" 92 | "\n"; 93 | if (argc == 1 || (argc > 1 && ( 94 | strncmp(argv[1], "--help", strlen("--help")) == 0 || 95 | strncmp(argv[1], "-h", strlen("-h")) == 0 ))) 96 | { 97 | printf(usage, argv[0]); 98 | return 0; 99 | } 100 | if (argc < 2) 101 | { 102 | printf(usage, argv[0]); 103 | return 1; 104 | } 105 | 106 | int opt; 107 | while ((opt = getopt(argc, argv, "c")) != -1) 108 | { 109 | switch(opt) 110 | { 111 | case 'c': 112 | highlander_clean(); 113 | return 0; 114 | default: 115 | fprintf(stderr, "\nError: unknown paramater \"%c\"\n", opt); 116 | fprintf(stderr, usage, argv[0]); 117 | return -1; 118 | } 119 | } 120 | 121 | if (highlander()) 122 | { 123 | /* Start the log file. */ 124 | int logfd; 125 | char hostname[64]; 126 | gethostname(hostname,64); 127 | 128 | char *fname; 129 | int ret = asprintf(&fname, "%s.power.dat", hostname); 130 | if (ret < 0) 131 | { 132 | printf("Fatal Error: Cannot allocate memory for fname.\n"); 133 | return 1; 134 | } 135 | 136 | logfd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_NOATIME|O_NDELAY, S_IRUSR|S_IWUSR); 137 | if (logfd < 0) 138 | { 139 | printf("Fatal Error: %s on %s cannot open the appropriate fd.\n", argv[0], hostname); 140 | return 1; 141 | } 142 | logfile = fdopen(logfd, "w"); 143 | fprintf(logfile, "time pkg_joules0 pkg_joules1 pkg_limwatts0 pkg_limwatts1 dram_joules0 dram_joules1 instr0 instr1 core0 core1\n"); 144 | 145 | /* Start power measurement thread. */ 146 | pthread_t mthread; 147 | pthread_mutex_init(&mlock, NULL); 148 | pthread_create(&mthread, NULL, power_measurement, NULL); 149 | 150 | /* Fork. */ 151 | pid_t app_pid = fork(); 152 | if (app_pid == 0) 153 | { 154 | /* I'm the child. */ 155 | execvp(argv[1], &argv[1]); 156 | printf("fork failure\n"); 157 | return 1; 158 | } 159 | /* Wait. */ 160 | waitpid(app_pid, NULL, 0); 161 | sleep(1); 162 | 163 | highlander_wait(); 164 | 165 | /* Stop power measurement thread. */ 166 | running = 0; 167 | take_measurement(); 168 | end = now_ms(); 169 | 170 | /* Output summary data. */ 171 | ret = asprintf(&fname, "%s.power.summary", hostname); 172 | if (ret < 0) 173 | { 174 | printf("Fatal Error: Cannot allocate memory for fname.\n"); 175 | return 1; 176 | } 177 | 178 | logfd = open(fname, O_WRONLY|O_CREAT|O_EXCL|O_NOATIME|O_NDELAY, S_IRUSR|S_IWUSR); 179 | if (logfd < 0) 180 | { 181 | printf("Fatal Error: %s on %s cannot open the appropriate fd.\n", argv[0], hostname); 182 | return 1; 183 | } 184 | summaryfile = fdopen(logfd, "w"); 185 | char *msg; 186 | ret = asprintf(&msg, "host: %s\npid: %d\ntotal_joules: %lf\nallocated: %lf\nmax_watts: %lf\nmin_watts: %lf\nruntime ms: %lu\nstart: %lu\nend: %lu\n", hostname, app_pid, total_joules, limit_joules, max_watts, min_watts, end-start, start, end); 187 | if (ret < 0) 188 | { 189 | printf("Fatal Error: Cannot allocate memory for msg.\n"); 190 | return 1; 191 | } 192 | 193 | fprintf(summaryfile, "%s", msg); 194 | fclose(summaryfile); 195 | close(logfd); 196 | 197 | shmctl(shmid, IPC_RMID, NULL); 198 | shmdt(shmseg); 199 | } 200 | else 201 | { 202 | /* Fork. */ 203 | pid_t app_pid = fork(); 204 | if (app_pid == 0) 205 | { 206 | /* I'm the child. */ 207 | execvp(argv[1], &argv[1]); 208 | printf("Fork failure\n"); 209 | return 1; 210 | } 211 | /* Wait. */ 212 | waitpid(app_pid, NULL, 0); 213 | 214 | highlander_wait(); 215 | } 216 | 217 | return 0; 218 | } 219 | -------------------------------------------------------------------------------- /include/csr_core.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #ifndef CSR_CORE_H_INCLUDE 32 | #define CSR_CORE_H_INCLUDE 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #define CSRSAFE_8086_BATCH _IOWR('a', 0x05, struct csr_batch_array) 44 | #define CSR_FILENAME_SIZE 128 45 | #define CSR_MODULE "/dev/cpu/csr_safe" 46 | 47 | /// @brief Enum encompassing type of data being read to/written from uncore 48 | /// registers. 49 | enum csr_data_type_e 50 | { 51 | /// @brief Integrated memory controller counter measurements. 52 | CSR_IMC_CTRS, 53 | /// @brief Integrated memory controller performance event measurements. 54 | CSR_IMC_EVTS, 55 | /// @brief UBox PMON global control data for integrated memory controller. 56 | CSR_IMC_PMONUNITCTRL, 57 | /// @brief UBox PMON global status data for integrated memory controller. 58 | CSR_IMC_PMONUNITSTAT, 59 | /* Currently unused */ 60 | //CSR_IMC_MEMCTRA, 61 | //CSR_IMC_MEMCTRR, 62 | //CSR_IMC_MEMCTRW, 63 | //CSR_IMC_IMCCTR, 64 | //CSR_QPI_CTRS, 65 | //CSR_QPI_EVTS 66 | }; 67 | 68 | /// @brief Structure holding information for a single read/write operation to 69 | /// an uncore register. 70 | struct csr_batch_op 71 | { 72 | /// @brief Bus identifier where read/write of uncore register will be 73 | /// executed. 74 | uint8_t bus; 75 | /// @brief Device identifier where read/write of uncore register will be 76 | /// executed. 77 | uint8_t device; 78 | /// @brief Function identifier where read/write of uncore register will be 79 | /// executed. 80 | uint8_t function; 81 | /// @brief Socket identifier where read/write of uncore register will be 82 | /// executed. 83 | uint8_t socket; 84 | /// @brief Address of uncore register to perform operation. 85 | uint16_t offset; 86 | /// @brief Stores error code. 87 | int err; 88 | /// @brief Identify if operation is read (non-zero) or write (0). 89 | uint8_t isread; 90 | /// @brief Stores input to or result from operation. 91 | uint64_t csrdata; 92 | /// @brief Write mask applied to uncore register. 93 | uint64_t wmask; 94 | /// @brief Number of batch operations. 95 | uint8_t size; 96 | }; 97 | 98 | /// @brief Structure holding multiple read/write operations to various MSRs. 99 | struct csr_batch_array 100 | { 101 | /// @brief Number of operations to execute. 102 | uint32_t numops; 103 | /// @brief Array of length numops of operations to execute. 104 | struct csr_batch_op *ops; 105 | }; 106 | 107 | /// @brief Open the module file descriptors exposed in the /dev filesystem. 108 | /// 109 | /// @return 0 if initialization was a success, else -1 if could not stat file 110 | /// descriptors or open any csr module. 111 | int init_csr(void); 112 | 113 | /// @brief Close the module file descriptors exposed in the /dev filesystem. 114 | /// 115 | /// @return 0 if finalization was a success, else -1 if could not close file 116 | /// descriptors. 117 | int finalize_csr(void); 118 | 119 | /// @brief Allocate space for uncore batch arrays. 120 | /// 121 | /// @param [out] batchsel Storage for uncore batch operations. 122 | /// 123 | /// @param [in] batchnum csr_data_type_e data type of batch operation. 124 | /// 125 | /// @param [out] opssize Size of specific set of batch operations. 126 | /// 127 | /// @return 0 if successful, else NULL pointer as a result of libmsr_calloc() 128 | /// or libmsr_realloc(). 129 | int csr_batch_storage(struct csr_batch_array **batchsel, 130 | const int batchnum, 131 | unsigned **opssize); 132 | 133 | /// @brief Allocate space for new uncore batch operation. 134 | /// 135 | /// @param [in] batchnum csr_data_type_e data type of batch operation. 136 | /// 137 | /// @param [in] bsize Size of batch operation. 138 | /// 139 | /// @return 0 if allocation was a success, else -1 if csr_batch_storage() fails. 140 | int allocate_csr_batch(const int batchnum, 141 | size_t bsize); 142 | 143 | /// @brief Deallocate memory for specific set of uncore batch operations. 144 | /// 145 | /// @param [in] batchnum csr_data_type_e data type of batch operation. 146 | /// 147 | /// @return 0 if successful, else -1 if csr_batch_storage() fails. 148 | int free_csr_batch(const int batchnum); 149 | 150 | /// @brief Create new uncore batch operation. 151 | /// 152 | /// @param [in] csr Address of uncore register for which operation will take 153 | /// place. 154 | /// 155 | /// @param [in] bus Bus where batch operation will take place. 156 | /// 157 | /// @param [in] device Device where batch operation will take place. 158 | /// 159 | /// @param [in] function Function where batch operation will take place. 160 | /// 161 | /// @param [in] socket Socket where batch operation will take place. 162 | /// 163 | /// @param [in] isread Indicates read or write to uncore register. 164 | /// 165 | /// @param [in] opsize Size of operation. 166 | /// 167 | /// @param [in] dest Stores data resulting from read or necessary for write to 168 | /// uncore register. 169 | /// 170 | /// @param [in] batchnum csr_data_type_e data type of batch operation. 171 | /// 172 | /// @return 0 if creation was a success, else -1 if csr_batch_storage() fails 173 | /// or if the number of batch operations exceeds the allocated size. 174 | int create_csr_batch_op(off_t csr, 175 | uint8_t bus, 176 | uint8_t device, 177 | uint8_t function, 178 | uint8_t socket, 179 | uint8_t isread, 180 | size_t opsize, 181 | uint64_t **dest, 182 | const int batchnum); 183 | 184 | /// @brief Execute read/write batch operation on a specific set of batch 185 | /// uncore registers. 186 | /// 187 | /// @param [in] batchnum csr_data_type_e data type of batch operation. 188 | /// 189 | /// @return 0 if successful, else -1 if csr_batch_storage() fails or if batch 190 | /// allocation is for 0 or less operations. 191 | int do_csr_batch_op(const int batchnum); 192 | 193 | #endif 194 | -------------------------------------------------------------------------------- /test/pstate_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "cpuid.h" 39 | #include "memhdlr.h" 40 | #include "msr_core.h" 41 | #include "msr_rapl.h" 42 | #include "msr_thermal.h" 43 | #include "msr_counters.h" 44 | #include "msr_clocks.h" 45 | #include "msr_misc.h" 46 | #include "msr_turbo.h" 47 | #include "csr_core.h" 48 | #include "csr_imc.h" 49 | #include "libmsr_error.h" 50 | #ifdef MPI 51 | #include 52 | #endif 53 | 54 | struct rapl_limit l1, l2, l3; 55 | 56 | void get_limits() 57 | { 58 | int i; 59 | static uint64_t sockets = 0; 60 | 61 | if (!sockets) 62 | { 63 | core_config(NULL, NULL, &sockets, NULL); 64 | } 65 | for (i = 0; i < sockets; i++) 66 | { 67 | if (i != 0) 68 | { 69 | fprintf(stdout, "\n"); 70 | } 71 | fprintf(stdout, "Socket %d:\n", i); 72 | if (get_pkg_rapl_limit(i, &l1, &l2) == 0) 73 | { 74 | fprintf(stdout, "Pkg Domain Power Lim 1 (lower lim)\n"); 75 | dump_rapl_limit(&l1, stdout); 76 | fprintf(stdout, "\n"); 77 | fprintf(stdout, "Pkg Domain Power Lim 2 (upper lim)\n"); 78 | dump_rapl_limit(&l2, stdout); 79 | } 80 | if (get_dram_rapl_limit(i, &l3) == 0) 81 | { 82 | fprintf(stdout, "\nDRAM Domain\n"); 83 | dump_rapl_limit(&l3, stdout); 84 | } 85 | } 86 | } 87 | 88 | // TODO: test other parts of clocks 89 | void clocks_test(double *freq) 90 | { 91 | fprintf(stdout, "\n--- Read IA32_APERF, IA32_MPERF, and IA32_TIME_STAMP_COUNTER ---\n"); 92 | dump_clocks_data_readable(stdout); 93 | 94 | fprintf(stdout, "\n--- Reading IA32_PERF_STATUS ---\n"); 95 | dump_p_state(stdout); 96 | fprintf(stdout, "\n"); 97 | 98 | fprintf(stdout, "--- Set New CPU Frequencies ---\n"); 99 | fprintf(stdout, "- Setting socket 0 to %.1fGHz\n", freq[0]); 100 | unsigned long long speedstep = (freq[0]*10)*256; 101 | printf(" WRITING dec=%llu hex=0x%llx\n", speedstep, speedstep); 102 | set_p_state(0, (uint64_t)speedstep); 103 | 104 | fprintf(stdout, "- Setting socket 1 to %.1fGHz\n", freq[1]); 105 | speedstep = (freq[1]*10)*256; 106 | printf(" WRITING dec=%llu hex=0x%llx\n", speedstep, speedstep); 107 | set_p_state(1, (uint64_t)speedstep); 108 | 109 | fprintf(stdout, "\n--- Confirm New Settings ---\n"); 110 | dump_p_state(stdout); 111 | } 112 | 113 | void set_to_defaults() 114 | { 115 | int socket = 0; 116 | int numsockets = num_sockets(); 117 | struct rapl_power_info raplinfo; 118 | struct rapl_limit socketlim, socketlim2, dramlim; 119 | 120 | for (socket = 0; socket < numsockets; socket++) 121 | { 122 | if (socket != 0) 123 | { 124 | fprintf(stdout, "\n"); 125 | } 126 | fprintf(stdout, "Socket %d:\n", socket); 127 | get_rapl_power_info(socket, &raplinfo); 128 | socketlim.bits = 0; 129 | socketlim.watts = raplinfo.pkg_therm_power; 130 | socketlim.seconds = 1; 131 | socketlim2.bits = 0; 132 | socketlim2.watts = raplinfo.pkg_therm_power * 1.2; 133 | socketlim2.seconds = 3; 134 | dramlim.bits = 0; 135 | dramlim.watts = raplinfo.dram_max_power; 136 | dramlim.seconds = 1; 137 | fprintf(stdout, "Pkg Domain Power Lim 1 (lower lim)\n"); 138 | dump_rapl_limit(&socketlim, stdout); 139 | fprintf(stdout, "\n"); 140 | fprintf(stdout, "Pkg Domain Power Lim 2 (upper lim)\n"); 141 | dump_rapl_limit(&socketlim2, stdout); 142 | fprintf(stdout, "\nDRAM Domain\n"); 143 | dump_rapl_limit(&dramlim, stdout); 144 | set_pkg_rapl_limit(socket, &socketlim, &socketlim2); 145 | set_dram_rapl_limit(socket, &dramlim); 146 | } 147 | } 148 | 149 | // TODO: check if test for oversized bitfield is in place, change that warning 150 | // to an error 151 | int main(int argc, char **argv) 152 | { 153 | struct rapl_data *rd = NULL; 154 | uint64_t *rapl_flags = NULL; 155 | uint64_t cores = 0; 156 | uint64_t threads = 0; 157 | uint64_t sockets = 0; 158 | int ri_stat = 0; 159 | double *new_p_states_ghz; 160 | 161 | if (!sockets) 162 | { 163 | core_config(&cores, &threads, &sockets, NULL); 164 | } 165 | new_p_states_ghz = malloc(sockets * sizeof(double)); 166 | 167 | if (argc == 1) 168 | { 169 | /* Default p-states to write. */ 170 | new_p_states_ghz[0] = 1.8; 171 | new_p_states_ghz[1] = 1.2; 172 | } 173 | else if (argc-1 > sockets) 174 | { 175 | fprintf(stderr, "ERROR: Too many p-states (in GHz) specified.\n"); 176 | return -1; 177 | } 178 | else if (argc-1 == sockets) 179 | { 180 | new_p_states_ghz[0] = atof(argv[1]); 181 | new_p_states_ghz[1] = atof(argv[2]); 182 | } 183 | else 184 | { 185 | fprintf(stderr, "ERROR: Not enough p-states (in GHz) specified.\n"); 186 | return -1; 187 | } 188 | 189 | if (init_msr()) 190 | { 191 | libmsr_error_handler("Unable to initialize libmsr", LIBMSR_ERROR_MSR_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 192 | return -1; 193 | } 194 | fprintf(stdout, "\n===== MSR Init Done =====\n"); 195 | 196 | ri_stat = rapl_init(&rd, &rapl_flags); 197 | if (ri_stat < 0) 198 | { 199 | libmsr_error_handler("Unable to initialize rapl", LIBMSR_ERROR_RAPL_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 200 | return -1; 201 | } 202 | fprintf(stdout, "\n===== RAPL Init Done =====\n"); 203 | 204 | fprintf(stdout, "\n===== Get Initial RAPL Power Limits =====\n"); 205 | get_limits(); 206 | 207 | fprintf(stdout, "\n===== POWER INFO =====\n"); 208 | dump_rapl_power_info(stdout); 209 | 210 | fprintf(stdout, "\n===== Clocks Test =====\n"); 211 | clocks_test(new_p_states_ghz); 212 | 213 | fprintf(stdout, "\n===== Setting Defaults =====\n"); 214 | set_to_defaults(); 215 | 216 | finalize_msr(); 217 | fprintf(stdout, "===== MSR Finalized =====\n"); 218 | 219 | fprintf(stdout, "\n===== Test Finished Successfully =====\n"); 220 | 221 | return 0; 222 | } 223 | -------------------------------------------------------------------------------- /test/power_cap_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include "cpuid.h" 38 | #include "msr_core.h" 39 | #include "msr_rapl.h" 40 | #include "libmsr_error.h" 41 | 42 | struct rapl_limit l1, l2, l3; 43 | 44 | void get_limits() 45 | { 46 | int i; 47 | static uint64_t sockets = 0; 48 | 49 | if (!sockets) 50 | { 51 | core_config(NULL, NULL, &sockets, NULL); 52 | } 53 | for (i = 0; i < sockets; i++) 54 | { 55 | if (i != 0) 56 | { 57 | fprintf(stdout, "\n"); 58 | } 59 | fprintf(stdout, "Socket %d:\n", i); 60 | if (get_pkg_rapl_limit(i, &l1, &l2) == 0) 61 | { 62 | fprintf(stdout, "Pkg Domain Power Lim 1 (lower lim)\n"); 63 | dump_rapl_limit(&l1, stdout); 64 | fprintf(stdout, "\n"); 65 | fprintf(stdout, "Pkg Domain Power Lim 2 (upper lim)\n"); 66 | dump_rapl_limit(&l2, stdout); 67 | } 68 | if (get_dram_rapl_limit(i, &l3) == 0) 69 | { 70 | fprintf(stdout, "\nDRAM Domain\n"); 71 | dump_rapl_limit(&l3, stdout); 72 | } 73 | } 74 | } 75 | 76 | void test_pkg_lower_limit(unsigned s) 77 | { 78 | struct rapl_power_info raplinfo; 79 | double power_cap_percentage = 0.7; 80 | get_rapl_power_info(s, &raplinfo); 81 | 82 | double power_cap = raplinfo.pkg_therm_power * power_cap_percentage; 83 | printf("Setting socket %d PL1 to %.1fW (%.0f%%)\n", s, power_cap, power_cap_percentage*100); 84 | l1.watts = power_cap; 85 | l1.seconds = 1; 86 | l1.bits = 0; 87 | set_pkg_rapl_limit(s, &l1, NULL); 88 | get_limits(); 89 | } 90 | 91 | void test_pkg_upper_limit(unsigned s) 92 | { 93 | struct rapl_power_info raplinfo; 94 | double power_cap_percentage = 0.9; 95 | get_rapl_power_info(s, &raplinfo); 96 | 97 | double power_cap = raplinfo.pkg_therm_power * power_cap_percentage; 98 | printf("Setting socket %d PL2 to %.1fW (%.0f%%)\n", s, power_cap, power_cap_percentage*100); 99 | l2.watts = power_cap; 100 | l2.seconds = 1; 101 | l2.bits = 0; 102 | set_pkg_rapl_limit(s, NULL, &l2); 103 | get_limits(); 104 | } 105 | 106 | void test_all_limits() 107 | { 108 | static uint64_t sockets = 0; 109 | int i; 110 | if (!sockets) 111 | { 112 | core_config(NULL, NULL, &sockets, NULL); 113 | } 114 | struct rapl_power_info raplinfo; 115 | double power_cap_percentage = 0.8; 116 | 117 | for (i = 0; i < sockets; i++) 118 | { 119 | get_rapl_power_info(i, &raplinfo); 120 | l1.watts = raplinfo.pkg_therm_power * power_cap_percentage; 121 | l1.seconds = 1; 122 | l1.bits = 0; 123 | l2.watts = raplinfo.pkg_max_power * power_cap_percentage; 124 | l2.seconds = 3; 125 | l2.bits = 0; 126 | l3.watts = raplinfo.dram_max_power * power_cap_percentage; 127 | l3.seconds = 1; 128 | l3.bits = 0; 129 | printf("Applying %.0f%% power cap to socket %d --- PL1 = %.1fW, PL2 = %.1fW, DRAM = %.1fW.\n", power_cap_percentage*100, i, l1.watts, l2.watts, l3.watts); 130 | 131 | set_pkg_rapl_limit(i, &l1, &l2); 132 | set_dram_rapl_limit(i, &l3); 133 | } 134 | get_limits(); 135 | } 136 | 137 | void set_to_defaults() 138 | { 139 | int socket = 0; 140 | int numsockets = num_sockets(); 141 | struct rapl_power_info raplinfo; 142 | struct rapl_limit socketlim, socketlim2, dramlim; 143 | 144 | for (socket = 0; socket < numsockets; socket++) 145 | { 146 | if (socket != 0) 147 | { 148 | fprintf(stdout, "\n"); 149 | } 150 | fprintf(stdout, "Socket %d:\n", socket); 151 | get_rapl_power_info(socket, &raplinfo); 152 | socketlim.bits = 0; 153 | socketlim.watts = raplinfo.pkg_therm_power; 154 | socketlim.seconds = 1; 155 | socketlim2.bits = 0; 156 | socketlim2.watts = raplinfo.pkg_therm_power * 1.2; 157 | socketlim2.seconds = 3; 158 | dramlim.bits = 0; 159 | dramlim.watts = raplinfo.dram_max_power; 160 | dramlim.seconds = 1; 161 | fprintf(stdout, "Pkg Domain Power Lim 1 (lower lim)\n"); 162 | dump_rapl_limit(&socketlim, stdout); 163 | fprintf(stdout, "\n"); 164 | fprintf(stdout, "Pkg Domain Power Lim 2 (upper lim)\n"); 165 | dump_rapl_limit(&socketlim2, stdout); 166 | fprintf(stdout, "\nDRAM Domain\n"); 167 | dump_rapl_limit(&dramlim, stdout); 168 | set_pkg_rapl_limit(socket, &socketlim, &socketlim2); 169 | set_dram_rapl_limit(socket, &dramlim); 170 | } 171 | } 172 | 173 | int main(int argc, char **argv) 174 | { 175 | struct rapl_data *rd = NULL; 176 | uint64_t *rapl_flags = NULL; 177 | uint64_t cores = 0; 178 | uint64_t threads = 0; 179 | uint64_t sockets = 0; 180 | int ri_stat = 0; 181 | unsigned i; 182 | 183 | if (!sockets) 184 | { 185 | core_config(&cores, &threads, &sockets, NULL); 186 | } 187 | 188 | if (init_msr()) 189 | { 190 | libmsr_error_handler("Unable to initialize libmsr", LIBMSR_ERROR_MSR_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 191 | return -1; 192 | } 193 | fprintf(stdout, "\n===== MSR Init Done =====\n"); 194 | 195 | ri_stat = rapl_init(&rd, &rapl_flags); 196 | if (ri_stat < 0) 197 | { 198 | libmsr_error_handler("Unable to initialize rapl", LIBMSR_ERROR_RAPL_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 199 | return -1; 200 | } 201 | fprintf(stdout, "\n===== RAPL Init Done =====\n"); 202 | 203 | fprintf(stdout, "\n===== Get Initial RAPL Power Limits =====\n"); 204 | get_limits(); 205 | 206 | for (i = 0; i < sockets; i++) 207 | { 208 | fprintf(stdout, "\n===== Start Socket %u RAPL Power Limit Test =====\n", i); 209 | fprintf(stdout, "\n--- Testing Pkg Domain Lower Limit ---\n"); 210 | test_pkg_lower_limit(i); 211 | fprintf(stdout, "\n--- Testing Pkg Domain Upper Limit ---\n"); 212 | test_pkg_upper_limit(i); 213 | fprintf(stdout, "\n===== End Socket %u RAPL Power Limit Test =====\n", i); 214 | } 215 | 216 | fprintf(stdout, "\n===== Testing All RAPL Power Limits All Sockets =====\n"); 217 | test_all_limits(); 218 | fprintf(stdout, "===== End Testing All RAPL Power Limits All Sockets =====\n"); 219 | 220 | fprintf(stdout, "\n===== Setting Defaults =====\n"); 221 | set_to_defaults(); 222 | 223 | finalize_msr(); 224 | fprintf(stdout, "===== MSR Finalized =====\n"); 225 | 226 | fprintf(stdout, "\n===== Test Finished Successfully =====\n"); 227 | if (ri_stat) 228 | { 229 | fprintf(stdout, "\nFound %d locked rapl register(s)\n", ri_stat); 230 | } 231 | 232 | return 0; 233 | } 234 | -------------------------------------------------------------------------------- /src/msr_clocks.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #define __STDC_FORMAT_MACROS 32 | #include 33 | #include 34 | 35 | #include "msr_core.h" 36 | #include "msr_clocks.h" 37 | #include "memhdlr.h" 38 | #include "cpuid.h" 39 | #include "libmsr_debug.h" 40 | 41 | void clocks_storage(struct clocks_data **cd) 42 | { 43 | static int init = 0; 44 | static struct clocks_data d; 45 | static uint64_t totalThreads = 0; 46 | 47 | if (!init) 48 | { 49 | totalThreads = num_devs(); 50 | d.aperf = (uint64_t **) libmsr_malloc(totalThreads * sizeof(uint64_t *)); 51 | d.mperf = (uint64_t **) libmsr_malloc(totalThreads * sizeof(uint64_t *)); 52 | d.tsc = (uint64_t **) libmsr_malloc(totalThreads * sizeof(uint64_t *)); 53 | allocate_batch(CLOCKS_DATA, 3UL * num_devs()); 54 | load_thread_batch(IA32_APERF, d.aperf, CLOCKS_DATA); 55 | load_thread_batch(IA32_MPERF, d.mperf, CLOCKS_DATA); 56 | load_thread_batch(IA32_TIME_STAMP_COUNTER, d.tsc, CLOCKS_DATA); 57 | init = 1; 58 | } 59 | if (cd != NULL) 60 | { 61 | *cd = &d; 62 | } 63 | } 64 | 65 | void perf_storage(struct perf_data **pd) 66 | { 67 | static struct perf_data d; 68 | static uint64_t procs = 0; 69 | 70 | if (!procs) 71 | { 72 | procs = num_sockets(); 73 | d.perf_status = (uint64_t **) libmsr_malloc(procs * sizeof(uint64_t *)); 74 | d.perf_ctl = (uint64_t **) libmsr_malloc(procs * sizeof(uint64_t *)); 75 | allocate_batch(PERF_DATA, 2UL * num_sockets()); 76 | allocate_batch(PERF_CTL, 2UL * num_sockets()); 77 | load_socket_batch(IA32_PERF_STATUS, d.perf_status, PERF_DATA); 78 | load_socket_batch(IA32_PERF_CTL, d.perf_ctl, PERF_CTL); 79 | } 80 | if (pd != NULL) 81 | { 82 | *pd = &d; 83 | } 84 | } 85 | 86 | void dump_clocks_data_terse_label(FILE *writedest) 87 | { 88 | int thread_idx; 89 | static uint64_t totalThreads = 0; 90 | 91 | if (!totalThreads) 92 | { 93 | totalThreads = num_devs(); 94 | } 95 | for (thread_idx = 0; thread_idx < totalThreads; thread_idx++) 96 | { 97 | fprintf(writedest, "aperf%02d mperf%02d tsc%02d ", thread_idx, thread_idx, thread_idx); 98 | } 99 | } 100 | 101 | void dump_clocks_data_terse(FILE *writedest) 102 | { 103 | static uint64_t totalThreads = 0; 104 | static struct clocks_data *cd; 105 | int thread_idx; 106 | 107 | if (!totalThreads) 108 | { 109 | totalThreads = num_devs(); 110 | clocks_storage(&cd); 111 | } 112 | read_batch(CLOCKS_DATA); 113 | for (thread_idx = 0; thread_idx < totalThreads; thread_idx++) 114 | { 115 | fprintf(writedest, "%20lu %20lu %20lu ", *cd->aperf[thread_idx], *cd->mperf[thread_idx], *cd->tsc[thread_idx]); 116 | } 117 | } 118 | 119 | void dump_p_state(FILE *writedest) 120 | { 121 | static uint64_t procs = 0; 122 | static struct perf_data *cd; 123 | int sock_idx; 124 | 125 | if (!procs) 126 | { 127 | procs = num_sockets(); 128 | perf_storage(&cd); 129 | } 130 | read_batch(PERF_DATA); 131 | for (sock_idx = 0; sock_idx < procs; sock_idx++) 132 | { 133 | #ifdef LIBMSR_DEBUG 134 | printf("PERF_STATUS raw decimal %" PRIu64 "\n", *cd->perf_status[sock_idx]); 135 | #endif 136 | unsigned long long perf_state = *cd->perf_status[sock_idx] & 0xFFFF; 137 | double pstate_actual = perf_state/256; 138 | fprintf(writedest, "Socket %d:\n", sock_idx); 139 | fprintf(writedest, " bits = %lx\n", *cd->perf_status[sock_idx]); 140 | fprintf(writedest, " current p-state = %.0f MHz\n", pstate_actual*100); 141 | } 142 | } 143 | 144 | void set_p_state(unsigned socket, uint64_t pstate) 145 | { 146 | static uint64_t procs = 0; 147 | static struct perf_data *cd; 148 | 149 | if (!procs) 150 | { 151 | procs = num_sockets(); 152 | perf_storage(&cd); 153 | } 154 | *cd->perf_ctl[socket] = pstate; 155 | #ifdef LIBMSR_DEBUG 156 | printf("PERF_CTL raw decimal %" PRIu64 "\n", *cd->perf_ctl[socket]); 157 | #endif 158 | write_batch(PERF_CTL); 159 | 160 | #ifdef LIBMSR_DEBUG 161 | read_batch(PERF_CTL); 162 | printf("---reading PERF_CTL raw decimal %" PRIu64 "\n", *cd->perf_ctl[socket]); 163 | #endif 164 | } 165 | 166 | void dump_clocks_data_readable(FILE *writedest) 167 | { 168 | static uint64_t totalThreads = 0; 169 | static struct clocks_data *cd; 170 | int thread_idx; 171 | 172 | if (!totalThreads) 173 | { 174 | totalThreads = num_devs(); 175 | clocks_storage(&cd); 176 | } 177 | #ifdef LIBMSR_DEBUG 178 | fprintf(stderr, "DEBUG: (clocks_readable) totalThreads is %lu\n", totalThreads); 179 | #endif 180 | read_batch(CLOCKS_DATA); 181 | for (thread_idx = 0; thread_idx < totalThreads; thread_idx++) 182 | { 183 | fprintf(writedest, "aperf%02d:%20lu mperf%02d:%20lu tsc%02d:%20lu\n", thread_idx, *cd->aperf[thread_idx], thread_idx, *cd->mperf[thread_idx], thread_idx, *cd->tsc[thread_idx]); 184 | } 185 | } 186 | 187 | void dump_clock_mod(struct clock_mod *s, FILE *writedest) 188 | { 189 | double percent = 0.0; 190 | 191 | if (s->duty_cycle == 0) 192 | { 193 | percent = 6.25; 194 | } 195 | else if (s->duty_cycle == 1) 196 | { 197 | percent = 12.5; 198 | } 199 | else if (s->duty_cycle == 2) 200 | { 201 | percent = 25.0; 202 | } 203 | else if (s->duty_cycle == 3) 204 | { 205 | percent = 37.5; 206 | } 207 | else if (s->duty_cycle == 4) 208 | { 209 | percent = 50.0; 210 | } 211 | else if (s->duty_cycle == 5) 212 | { 213 | percent = 63.5; 214 | } 215 | else if (s->duty_cycle == 6) 216 | { 217 | percent = 75.0; 218 | } 219 | else if (s->duty_cycle == 7) 220 | { 221 | percent = 87.5; 222 | } 223 | fprintf(writedest, "duty_cycle = %d\n", s->duty_cycle); 224 | fprintf(writedest, "percentage = %.2f\n", percent); 225 | fprintf(writedest, "duty_cycle_enable = %d\n", s->duty_cycle_enable); 226 | } 227 | 228 | void get_clock_mod(int socket, int core, struct clock_mod *s) 229 | { 230 | read_msr_by_coord(socket, core, 0, IA32_CLOCK_MODULATION, &(s->raw)); 231 | /* Specific encoded values for target duty cycle. */ 232 | s->duty_cycle = MASK_VAL(s->raw, 3, 1); 233 | 234 | /* On-Demand Clock Modulation Enable */ 235 | /* 1 = enabled, 0 disabled */ 236 | s->duty_cycle_enable = MASK_VAL(s->raw, 4, 4); 237 | } 238 | 239 | int set_clock_mod(int socket, int core, struct clock_mod *s) 240 | { 241 | uint64_t msrVal; 242 | 243 | read_msr_by_coord(socket, core, 0, IA32_CLOCK_MODULATION, &msrVal); 244 | if (!(s->duty_cycle > 0 && s->duty_cycle < 8)) 245 | { 246 | return -1; 247 | } 248 | if (!(s->duty_cycle_enable == 0 || s->duty_cycle_enable == 1)) 249 | { 250 | return -1; 251 | } 252 | 253 | msrVal = (msrVal & (~(3<<1))) | (s->duty_cycle << 1); 254 | msrVal = (msrVal & (~(1<<4))) | (s->duty_cycle_enable << 4); 255 | 256 | write_msr_by_coord(socket, core, 0, IA32_CLOCK_MODULATION, msrVal); 257 | return 0; 258 | } 259 | -------------------------------------------------------------------------------- /include/csr_imc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #ifndef CSR_IMC_H_INCLUDE 32 | #define CSR_IMC_H_INCLUDE 33 | 34 | #include 35 | 36 | #include "master.h" 37 | 38 | /* Integrated Memory Controller (iMC) CSRs */ 39 | 40 | #define NUMCTRS 8 41 | 42 | /// @brief Structure containing data of per-component performance counters. 43 | struct pmonctrs_data 44 | { 45 | uint64_t **ctr0; 46 | uint64_t **ctr1; 47 | uint64_t **ctr2; 48 | uint64_t **ctr3; 49 | uint64_t **ctr4; 50 | // config 51 | uint64_t **ctrcfg0; 52 | uint64_t **ctrcfg1; 53 | uint64_t **ctrcfg2; 54 | uint64_t **ctrcfg3; 55 | uint64_t **ctrcfg4; 56 | }; 57 | 58 | /// @todo Document fixed_perfmon_data struct. 59 | struct fixed_perfmon_data 60 | { 61 | uint64_t **fctr; 62 | // config 63 | uint64_t **fctrcfg; 64 | }; 65 | 66 | /// @todo Document pmonctr_global struct. 67 | struct pmonctr_global 68 | { 69 | uint64_t **unitctrl; 70 | uint64_t **unitstatus; 71 | }; 72 | 73 | /// @brief Store the PMON counter data on the heap. 74 | /// 75 | /// @return Pointer to PMON counter data. 76 | struct pmonctrs_data *pmon_ctr_storage(void); 77 | 78 | /// @brief the PMON global counter data on the heap. 79 | /// 80 | /// @return Pointer to PMON global counter data. 81 | struct pmonctr_global *pmonctr_global_storage(void); 82 | 83 | /// @brief Initialize storage for PMON performance counter data. 84 | /// 85 | /// @return -1 if PMON counters have been initialized, else 86 | /// 10*NUMCTRS*num_sockets. 87 | int init_pmon_ctrs(void); 88 | 89 | /// @brief Initialize storage for PMON global performance counter data. 90 | /// 91 | /// @return -1 if PMON global counters have been initialized, else 92 | /// 2*NUMCTRS*num_sockets. 93 | int init_pmonctr_global(void); 94 | 95 | /// @brief Configure iMC performance counters. 96 | /// 97 | /// @param [in] threshold Threshold used in counter comparison. 98 | /// 99 | /// @param [in] ovf_en When set to 1 and the counter overflows, its overflow 100 | /// bit is set in the local status register and global status register. 101 | /// 102 | /// @param [in] edge_det When set to 1, increment counter when a 0 --> 1 103 | /// transition (i.e., rising edge) is detected. When 0, the counter will 104 | /// increment in each cycle that the event is asserted. 105 | /// 106 | /// @param [in] umask Select subevents to be counted within the selected event. 107 | /// 108 | /// @param [in] event Select event to be counted. 109 | /// 110 | /// @param [in] counter Unique counter identifier. 111 | /// 112 | /// @return 0 if set_pmon_config() and do_csr_batch_op() are successful, else 113 | /// -1 if counter does not exist. 114 | int pmon_config(uint32_t threshold, 115 | uint32_t ovf_en, 116 | uint32_t edge_det, 117 | uint32_t umask, 118 | uint8_t event, 119 | const unsigned counter); 120 | 121 | /// @brief Set PMON controls. 122 | /// 123 | /// @param [in] ovf_en When set to 1 and the counter overflows, its overflow 124 | /// bit is set in the local status register and global status register. 125 | /// 126 | /// @param [in] freeze_en Enable freezing of all uncore performance counters. 127 | /// 128 | /// @param [in] freeze Freeze all uncore performance monitors. 129 | /// 130 | /// @param [in] reset When set to 1, the corresponding counter will be cleared 131 | /// to 0. 132 | /// 133 | /// @param [in] reset_cf Reset to see a new freeze. 134 | /// 135 | /// @return 0 if do_csr_batch_op() was successful, else -1. 136 | int set_pmon_unit_ctrl(uint32_t ovf_en, 137 | uint16_t freeze_en, 138 | uint16_t freeze, 139 | uint16_t reset, 140 | uint8_t reset_cf); 141 | 142 | /// @brief iMC memory bandwidth performance counter. 143 | /// 144 | /// @param [in] counter Unique counter identifier. 145 | /// 146 | /// @param [in] type csr_data_type_e data type of event. 147 | /// 148 | /// @return 0 if pmon_config() was successful, else -1 if counter does not 149 | /// exist or if specified bandwidth measurement is invalid. 150 | int mem_bw_on_ctr(const unsigned counter, 151 | const int type); 152 | 153 | /// @todo Document mem_pct_rw_on_ctr(). 154 | /// 155 | /// @return 0 if pmon_config() was successful, else -1 if counter does not exist. 156 | int mem_pct_rw_on_ctr(const unsigned rcounter, 157 | const unsigned wcounter); 158 | 159 | /// @todo Document mem_page_empty_on_ctr(). 160 | /// 161 | /// @return 0 if pmon_config() was successful, else -1 if number of counters is 162 | /// larger than number of iMC performance counters. 163 | int mem_page_empty_on_ctr(const unsigned act_count, 164 | const unsigned pre_count, 165 | const unsigned cas_count); 166 | 167 | /// @todo Document mem_page_miss_on_ctr(). 168 | /// 169 | /// @return 0 if pmon_config() was successful, else -1 if counter does not 170 | /// exist. 171 | int mem_page_miss_on_ctr(const unsigned pre_count, 172 | const unsigned cas_count); 173 | 174 | /// @brief Read iMC counters. 175 | /// 176 | /// @param [in] counter Unique counter identifier. 177 | /// 178 | /// @return 0 if do_csr_batch_op() was successful, else -1 if counter does not 179 | /// exist. 180 | int read_imc_counter_batch(const unsigned counter); 181 | 182 | /// @brief Print memory bandwidth. 183 | /// 184 | /// @param [in] counter Unique counter identifier. 185 | /// 186 | /// @param [in] writedest File stream where output will be written to. 187 | /// 188 | /// @return 0 if successful. 189 | int print_mem_bw_from_ctr(const unsigned counter, 190 | FILE *writedest); 191 | 192 | /// @brief Print percentage of read/write requests. 193 | /// 194 | /// @param [in] rcounter Unique counter identifier for read requests. 195 | /// 196 | /// @param [in] wcounter Unique counter identifier for write requests. 197 | /// 198 | /// @param [in] type Indicates data is reporting read or write requests. 199 | /// 200 | /// @param [in] writedest File stream where output will be written to. 201 | /// 202 | /// @return 0 if successful. 203 | int print_mem_pct_rw_from_ctr(const unsigned rcounter, 204 | const unsigned wcounter, 205 | int type, 206 | FILE *writedest); 207 | 208 | /// @brief Print percentage of read/write requests that caused a page empty. 209 | /// 210 | /// @todo Document print_mem_page_empty_from_ctr() parameters. 211 | /// 212 | /// @return 0 if successful. 213 | int print_mem_page_empty_from_ctr(const unsigned act, 214 | const unsigned pre, 215 | const unsigned cas, 216 | FILE *writedest); 217 | 218 | /// @brief Print percentage of read/write requests that caused a page miss. 219 | /// 220 | /// @todo Document print_mem_page_miss_from_ctr() parameters. 221 | /// 222 | /// @return 0 if successful. 223 | int print_mem_page_miss_from_ctr(const unsigned pre, 224 | const unsigned cas, 225 | FILE *writedest); 226 | 227 | /// @brief Print contents of iMC performance monitoring counters. 228 | /// 229 | /// @return 0 if successful, else -1 if init_pmon_ctrs() fails. 230 | int print_pmon_ctrs(void); 231 | 232 | #endif 233 | -------------------------------------------------------------------------------- /src/msr_misc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "msr_core.h" 37 | #include "msr_misc.h" 38 | #include "memhdlr.h" 39 | #include "cpuid.h" 40 | 41 | /// @brief Allocate data structures to store package-level C-state 42 | /// residencies. 43 | /// 44 | /// @param [out] pcr Pointer to package-level C-state residency data. 45 | static void init_pkg_cres(struct pkg_cres *pcr) 46 | { 47 | int sockets = num_sockets(); 48 | pcr->pkg_c2 = (uint64_t **) libmsr_calloc(sockets, sizeof(uint64_t *)); 49 | pcr->pkg_c3 = (uint64_t **) libmsr_calloc(sockets, sizeof(uint64_t *)); 50 | pcr->pkg_c6 = (uint64_t **) libmsr_calloc(sockets, sizeof(uint64_t *)); 51 | pcr->pkg_c7 = (uint64_t **) libmsr_calloc(sockets, sizeof(uint64_t *)); 52 | allocate_batch(PKG_CRES, 4 * sockets); 53 | load_socket_batch(MSR_PKG_C2_RESIDENCY, pcr->pkg_c2, PKG_CRES); 54 | load_socket_batch(MSR_PKG_C3_RESIDENCY, pcr->pkg_c3, PKG_CRES); 55 | load_socket_batch(MSR_PKG_C6_RESIDENCY, pcr->pkg_c6, PKG_CRES); 56 | load_socket_batch(MSR_PKG_C7_RESIDENCY, pcr->pkg_c7, PKG_CRES); 57 | } 58 | 59 | /// @brief Allocate data structures to store core-level C-state residencies. 60 | /// 61 | /// @param [out] ccr Pointer to core-level C-state residency data. 62 | static void init_core_cres(struct core_cres *ccr) 63 | { 64 | int cores = num_cores(); 65 | ccr->core_c3 = (uint64_t **) libmsr_calloc(cores, sizeof(uint64_t *)); 66 | ccr->core_c6 = (uint64_t **) libmsr_calloc(cores, sizeof(uint64_t *)); 67 | ccr->core_c7 = (uint64_t **) libmsr_calloc(cores, sizeof(uint64_t *)); 68 | allocate_batch(CORE_CRES, 3 * cores); 69 | load_core_batch(MSR_CORE_C3_RESIDENCY, ccr->core_c3, CORE_CRES); 70 | load_core_batch(MSR_CORE_C6_RESIDENCY, ccr->core_c6, CORE_CRES); 71 | load_core_batch(MSR_CORE_C7_RESIDENCY, ccr->core_c7, CORE_CRES); 72 | } 73 | 74 | void dump_misc_enable(struct misc_enable *s) 75 | { 76 | fprintf(stdout, "fast_string_enable = %u\n", s->fast_string_enable); 77 | fprintf(stdout, "auto_TCC_enable = %u\n", s->auto_TCC_enable); 78 | fprintf(stdout, "performance_monitoring = %u\n", s->performance_monitoring); 79 | fprintf(stdout, "branch_trace_storage_unavail = %u\n", s->branch_trace_storage_unavail); 80 | fprintf(stdout, "precise_event_based_sampling_unavail = %u\n", s->precise_event_based_sampling_unavail); 81 | fprintf(stdout, "TM2_enable = %u\n", s->TM2_enable); 82 | fprintf(stdout, "enhanced_Intel_SpeedStep_Tech_enable = %u\n", s->enhanced_Intel_SpeedStep_Tech_enable); 83 | fprintf(stdout, "enable_monitor_fsm = %u\n", s->enable_monitor_fsm); 84 | fprintf(stdout, "limit_CPUID_maxval = %u\n", s->limit_CPUID_maxval); 85 | fprintf(stdout, "xTPR_message_disable = %u\n", s->xTPR_message_disable); 86 | fprintf(stdout, "XD_bit_disable = %u\n", s->XD_bit_disable); 87 | fprintf(stdout, "turbo_mode_disable = %u\n", s->turbo_mode_disable); 88 | } 89 | 90 | void get_misc_enable(unsigned socket, struct misc_enable *s) 91 | { 92 | sockets_assert(&socket, __LINE__, __FILE__); 93 | read_msr_by_coord(socket, 0, 0, IA32_MISC_ENABLE, &(s->raw)); 94 | 95 | s->fast_string_enable = MASK_VAL(s->raw, 0, 0); 96 | s->auto_TCC_enable = MASK_VAL(s->raw, 3, 3); 97 | s->performance_monitoring = MASK_VAL(s->raw, 7, 7); 98 | s->branch_trace_storage_unavail = MASK_VAL(s->raw, 11, 11); 99 | s->precise_event_based_sampling_unavail = MASK_VAL(s->raw, 12, 12); 100 | s->TM2_enable = MASK_VAL(s->raw, 13, 13); 101 | s->enhanced_Intel_SpeedStep_Tech_enable = MASK_VAL(s->raw, 16, 16); 102 | s->enable_monitor_fsm = MASK_VAL(s->raw, 18, 18); 103 | s->limit_CPUID_maxval = MASK_VAL(s->raw, 22, 22); 104 | s->xTPR_message_disable = MASK_VAL(s->raw, 23, 23); 105 | s->XD_bit_disable = MASK_VAL(s->raw, 34, 34); 106 | s->turbo_mode_disable = MASK_VAL(s->raw, 38, 38); 107 | } 108 | 109 | void set_misc_enable(unsigned socket, struct misc_enable *s) 110 | { 111 | uint64_t msrVal; 112 | sockets_assert(&socket, __LINE__, __FILE__); 113 | read_msr_by_coord(socket, 0, 0, IA32_MISC_ENABLE, &msrVal); 114 | #if 0 /* For testing purposes. */ 115 | assert(s->fast_string_enable == 0 || s->fast_string_enable == 1); 116 | assert(s->auto_TCC_enable == 0 || s->auto_TCC_enable == 1); 117 | assert(s->TM2_enable == 0 || s->TM2_enable == 1); 118 | assert(s->enhanced_Intel_SpeedStep_Tech_enable == 0 || s->enhanced_Intel_SpeedStep_Tech_enable == 1); 119 | assert(s->limit_CPUID_maxval == 0 || s->limit_CPUID_maxval == 1); 120 | assert(s->xTPR_message_disable == 0 || s->xTPR_message_disable == 1); 121 | assert(s->XD_bit_disable == 0 || s->XD_bit_disable == 1); 122 | assert(s->turbo_mode_disable == 0 || s->turbo_mode_disable == 1); 123 | #endif 124 | 125 | msrVal = (msrVal & (~(1<< 0))) | (s->fast_string_enable << 0); 126 | msrVal = (msrVal & (~(1<< 3))) | (s->auto_TCC_enable << 3); 127 | msrVal = (msrVal & (~(1<< 13))) | (s->TM2_enable << 13); 128 | msrVal = (msrVal & (~(1<< 16))) | (s->enhanced_Intel_SpeedStep_Tech_enable << 16); 129 | msrVal = (msrVal & (~(1<< 22))) | (s->limit_CPUID_maxval << 22); 130 | msrVal = (msrVal & (~(1<< 23))) | (s->xTPR_message_disable << 23); 131 | msrVal = (msrVal & (~((uint64_t)1<< (uint64_t)34))) | ((uint64_t)s->XD_bit_disable << (uint64_t)34); 132 | msrVal = (msrVal & (~((uint64_t)1<< (uint64_t)38))) | ((uint64_t)s->turbo_mode_disable << (uint64_t)38); 133 | 134 | write_msr_by_coord(socket, 0, 0, IA32_MISC_ENABLE, msrVal); 135 | } 136 | 137 | void pkg_cres_storage(struct pkg_cres **pcr) 138 | { 139 | static struct pkg_cres pkg_cres_data; 140 | static int init = 0; 141 | if (!init) 142 | { 143 | init = 1; 144 | init_pkg_cres(&pkg_cres_data); 145 | } 146 | if (pcr != NULL) 147 | { 148 | *pcr = &pkg_cres_data; 149 | } 150 | } 151 | 152 | void core_cres_storage(struct core_cres **ccr) 153 | { 154 | static struct core_cres core_cres_data; 155 | static int init = 0; 156 | if (!init) 157 | { 158 | init = 1; 159 | init_core_cres(&core_cres_data); 160 | } 161 | if (ccr != NULL) 162 | { 163 | *ccr = &core_cres_data; 164 | } 165 | } 166 | 167 | void dump_pkg_cres_label(FILE *writedest) 168 | { 169 | fprintf(writedest, "PKG:c2\tc3\tc6\tc7\n"); 170 | } 171 | 172 | void dump_pkg_cres(FILE *writedest) 173 | { 174 | struct pkg_cres *pcr; 175 | int i; 176 | 177 | pkg_cres_storage(&pcr); 178 | read_batch(PKG_CRES); 179 | for (i = 0; i < num_sockets(); i++) 180 | { 181 | fprintf(writedest, "%lx\t", *pcr->pkg_c2[i]); 182 | fprintf(writedest, "%lx\t", *pcr->pkg_c3[i]); 183 | fprintf(writedest, "%lx\t", *pcr->pkg_c6[i]); 184 | fprintf(writedest, "%lx\t", *pcr->pkg_c7[i]); 185 | fprintf(writedest, "\n"); 186 | } 187 | } 188 | 189 | void dump_core_cres_label(FILE *writedest) 190 | { 191 | fprintf(writedest, "CORE:c3\tc6\tc7\n"); 192 | } 193 | 194 | void dump_core_cres(FILE *writedest) 195 | { 196 | struct core_cres *ccr; 197 | int i = 0; 198 | 199 | core_cres_storage(&ccr); 200 | read_batch(CORE_CRES); 201 | for (i = 0; i < num_cores(); i++) 202 | { 203 | fprintf(writedest, "%lx\t", *ccr->core_c3[i]); 204 | fprintf(writedest, "%lx\t", *ccr->core_c6[i]); 205 | fprintf(writedest, "%lx\t", *ccr->core_c7[i]); 206 | fprintf(writedest, "\n"); 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /src/csr_core.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "csr_core.h" 41 | #include "memhdlr.h" 42 | #include "cpuid.h" 43 | #include "libmsr_debug.h" 44 | #include "libmsr_error.h" 45 | 46 | /// @brief Retrieve file descriptor for uncore register. 47 | /// 48 | /// @return Unique file descriptor, else NULL. 49 | static int *csr_fd(void) 50 | { 51 | static int csrsafe = 0; 52 | return &csrsafe; 53 | } 54 | 55 | int init_csr(void) 56 | { 57 | int *fileDescriptor = csr_fd(); 58 | char filename[CSR_FILENAME_SIZE]; 59 | struct stat statbuf; 60 | static int init = 0; 61 | 62 | snprintf(filename, CSR_FILENAME_SIZE, CSR_MODULE); 63 | if (!init) 64 | { 65 | init = 1; 66 | if (stat(filename, &statbuf)) 67 | { 68 | fprintf(stderr, "Warning: Could not stat %s: init_csr(): %s: %s:%s::%d\n", CSR_MODULE, strerror(errno), getenv("HOSTNAME"), __FILE__, __LINE__); 69 | } 70 | if (!(statbuf.st_mode & S_IRUSR) || !(statbuf.st_mode & S_IWUSR)) 71 | { 72 | fprintf(stderr, "Warning: Incorrect permissions on csr_safe: init_csr(): %s:%s::%d\n", getenv("HOSTNAME"), __FILE__, __LINE__); 73 | } 74 | *fileDescriptor = open(filename, O_RDWR); 75 | } 76 | else 77 | { 78 | libmsr_error_handler("init_csr(): Unable to find csr_safe module", LIBMSR_ERROR_MSR_MODULE, getenv("HOSTNAME"), __FILE__, __LINE__); 79 | return -1; 80 | } 81 | return 0; 82 | } 83 | 84 | int finalize_csr(void) 85 | { 86 | int *fileDescriptor = csr_fd(); 87 | int err = 0; 88 | 89 | if (fileDescriptor) 90 | { 91 | err = close(*fileDescriptor); 92 | } 93 | if (err) 94 | { 95 | libmsr_error_handler("finalize_csr(): Could not close csr_fd", LIBMSR_ERROR_MSR_CLOSE, getenv("HOSTNAME"), __FILE__, __LINE__); 96 | return -1; 97 | } 98 | else 99 | { 100 | *fileDescriptor = 0; 101 | } 102 | return 0; 103 | } 104 | 105 | // CSRs have their own batch functions so that they can be used independently 106 | // of the rest of libmsr 107 | int csr_batch_storage(struct csr_batch_array **batchsel, const int batchnum, unsigned **opssize) 108 | { 109 | static struct csr_batch_array *batch = NULL; 110 | static unsigned arrsize = 1; 111 | static unsigned *size = NULL; 112 | 113 | if (batch == NULL) 114 | { 115 | #ifdef CSRDEBUG 116 | fprintf(stderr, "CSRBATCH: initializing batch ops\n"); 117 | #endif 118 | arrsize = (batchnum + 1 > arrsize ? batchnum + 1 : arrsize); 119 | size = (unsigned *) libmsr_calloc(arrsize, sizeof(unsigned)); 120 | batch = (struct csr_batch_array *) libmsr_calloc(arrsize, sizeof(struct csr_batch_array)); 121 | int i; 122 | for (i = 0; i < arrsize; i++) 123 | { 124 | size[i] = 8; 125 | batch[i].ops = NULL; 126 | batch[i].numops = 0; 127 | } 128 | } 129 | if (batchnum + 1 > arrsize) 130 | { 131 | unsigned oldsize = arrsize; 132 | #ifdef CSRDEBUG 133 | fprintf(stderr, "CSRBATCH: reallocating CSR batch for number %d\n", batchnum); 134 | #endif 135 | arrsize = batchnum + 1; 136 | batch = (struct csr_batch_array *) libmsr_realloc(batch, arrsize * sizeof(struct csr_batch_array)); 137 | size = (unsigned *) libmsr_realloc(size, arrsize * sizeof(unsigned)); 138 | for (; oldsize < arrsize; oldsize++) 139 | { 140 | batch[oldsize].ops = NULL; 141 | batch[oldsize].numops = 0; 142 | size[oldsize] = 8; 143 | } 144 | } 145 | if (batchsel == NULL) 146 | { 147 | libmsr_error_handler("csr_batch_storage(): Loading uninitialized batch", LIBMSR_ERROR_MSR_BATCH, getenv("HOSTNAME"), __FILE__, __LINE__); 148 | } 149 | *batchsel = &batch[batchnum]; 150 | if (opssize) 151 | { 152 | *opssize = &size[batchnum]; 153 | } 154 | return 0; 155 | } 156 | 157 | int allocate_csr_batch(const int batchnum, size_t bsize) 158 | { 159 | unsigned *size = NULL; 160 | struct csr_batch_array *batch = NULL; 161 | struct csr_batch_op *op; 162 | #ifdef CSRDEBUG 163 | fprintf(stderr, "CSRBATCH: allocating batch %d\n", batchnum); 164 | #endif 165 | if (csr_batch_storage(&batch, batchnum, &size)) 166 | { 167 | return -1; 168 | } 169 | *size = bsize; 170 | if (batch->ops != NULL) 171 | { 172 | libmsr_error_handler("allocate_csr_batch(): Conflicting batch pointers", LIBMSR_ERROR_MSR_BATCH, getenv("HOSTNAME"), __FILE__, __LINE__); 173 | } 174 | batch->ops = (struct csr_batch_op *) libmsr_calloc(*size, sizeof(struct csr_batch_op)); 175 | for (op = batch->ops; op < op + batch->numops; op++) 176 | { 177 | op->err = 0; 178 | } 179 | return 0; 180 | } 181 | 182 | int free_csr_batch(const int batchnum) 183 | { 184 | struct csr_batch_array *batch = NULL; 185 | static unsigned *size = NULL; 186 | 187 | if (batch == NULL) 188 | { 189 | if (csr_batch_storage(&batch, batchnum, &size)) 190 | { 191 | return -1; 192 | } 193 | } 194 | size[batchnum] = 0; 195 | libmsr_free(batch[batchnum].ops); 196 | batch[batchnum].ops = NULL; 197 | return 0; 198 | } 199 | 200 | int create_csr_batch_op(off_t csr, uint8_t bus, uint8_t device, uint8_t function, uint8_t socket, uint8_t isread, size_t opsize, uint64_t **dest, const int batchnum) 201 | { 202 | struct csr_batch_array *batch = NULL; 203 | unsigned *size = NULL; 204 | 205 | #ifdef CSRDEBUG 206 | fprintf(stderr, "CSRBATCH: batch %d is at %p\n", batchnum, batch); 207 | #endif 208 | if (csr_batch_storage(&batch, batchnum, &size)) 209 | { 210 | return -1; 211 | } 212 | #ifdef CSRDEBUG 213 | fprintf(stderr, "CSRBATCH: batch %d is at %p\n", batchnum, batch); 214 | #endif 215 | if (batch->numops >= *size) 216 | { 217 | libmsr_error_handler("create_csr_batch_op(): Batch is full, you likely used the wrong size", LIBMSR_ERROR_MSR_BATCH, getenv("HOSTNAME"), __FILE__, __LINE__); 218 | return -1; 219 | } 220 | 221 | batch->numops++; 222 | struct csr_batch_op *op = &batch->ops[batch->numops - 1]; 223 | op->offset = csr; 224 | op->bus = bus; 225 | op->device = device; 226 | op->function = function; 227 | op->socket = socket; 228 | op->isread = isread; 229 | op->err = 0; 230 | op->size = opsize; 231 | *dest = (uint64_t *) &op->csrdata; 232 | #ifdef CSRDEBUG 233 | fprintf(stderr, "CSRBATCH: op %d: destination of csr %x on b%dd%df%ds%d is %p\n", batch->numops, op->offset, op->bus, op->device, op->function, op->socket, &op->csrdata); 234 | #endif 235 | return 0; 236 | } 237 | 238 | int do_csr_batch_op(const int batchnum) 239 | { 240 | static int batchfd = 0; 241 | struct csr_batch_array *batch = NULL; 242 | int res; 243 | 244 | if (!batchfd) 245 | { 246 | batchfd = *csr_fd(); 247 | } 248 | if (csr_batch_storage(&batch, batchnum, NULL)) 249 | { 250 | return -1; 251 | } 252 | #ifdef CSRDEBUG 253 | fprintf(stderr, "CSRBATCH %d: numops %u\n", batchnum, batch->numops); 254 | #endif 255 | if (batch->numops <= 0) 256 | { 257 | libmsr_error_handler("do_csr_batch_op(): Using empty batch", LIBMSR_ERROR_MSR_BATCH, getenv("HOSTNAME"), __FILE__, __LINE__); 258 | return -1; 259 | } 260 | 261 | res = ioctl(batchfd, CSRSAFE_8086_BATCH, batch); 262 | if (res < 0) 263 | { 264 | libmsr_error_handler("do_csr_batch_op(): IOctl failed, does /dev/cpu/csr_batch exist?", LIBMSR_ERROR_MSR_BATCH, getenv("HOSTNAME"), __FILE__, __LINE__); 265 | fprintf(stderr, "ioctl returned %d\n", res); 266 | struct csr_batch_op *op; 267 | int i = 0; 268 | for (op = batch->ops; op < op + batch->numops; op++) 269 | { 270 | i++; 271 | if (i >= batch->numops) 272 | { 273 | break; 274 | } 275 | if (op->err) 276 | { 277 | fprintf(stderr, "CSR %x, b%dd%df%ds%d, ERR %d\n", op->offset, op->bus, op->device, op->function, op->socket, op->err); 278 | } 279 | } 280 | } 281 | /// @todo Debug stuff here. 282 | return 0; 283 | } 284 | -------------------------------------------------------------------------------- /src/msr_turbo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | #include "msr_core.h" 35 | #include "msr_turbo.h" 36 | #include "msr_rapl.h" 37 | #include "memhdlr.h" 38 | #include "libmsr_error.h" 39 | #include "cpuid.h" 40 | #include "libmsr_debug.h" 41 | 42 | /* IA32_MISC_ENABLE (0x1A0) 43 | * Setting bit 38 high disables Turbo Boost. To be done in the BIOS. 44 | * 45 | * IA32_PERF_CTL (0x199) 46 | * Setting bit 32 high disables Turbo Boost. This is the software control. 47 | */ 48 | 49 | void turbo_storage(uint64_t ***val) 50 | { 51 | static uint64_t **perf_ctl = NULL; 52 | static int init = 0; 53 | static uint64_t numDevs = 0; 54 | if (!init) 55 | { 56 | numDevs = num_devs(); 57 | perf_ctl = (uint64_t **) libmsr_malloc(numDevs * sizeof(uint64_t *)); 58 | init = 1; 59 | } 60 | if (val != NULL) 61 | { 62 | *val = perf_ctl; 63 | } 64 | } 65 | 66 | void enable_turbo(void) 67 | { 68 | int j; 69 | static uint64_t numDevs = 0; 70 | static uint64_t **val = NULL; 71 | if (!numDevs) 72 | { 73 | numDevs = num_devs(); 74 | val = (uint64_t **) libmsr_malloc(numDevs * sizeof(uint64_t *)); 75 | turbo_storage(&val); 76 | } 77 | /* Set bit 32 "IDA/Turbo DISENGAGE" of IA32_PERF_CTL to 1. */ 78 | read_batch(PERF_CTL); 79 | for (j = 0; j < numDevs; j++) 80 | { 81 | *val[j] &= ~(((uint64_t)1) << 32); 82 | fprintf(stderr, "0x%016lx\t", *val[j] & (((uint64_t)1)<<32)); 83 | } 84 | write_batch(PERF_CTL); 85 | } 86 | 87 | void disable_turbo(void) 88 | { 89 | int j; 90 | static uint64_t numDevs = 0; 91 | static uint64_t **val = NULL; 92 | if (!numDevs) 93 | { 94 | numDevs = num_devs(); 95 | val = (uint64_t **) libmsr_malloc(numDevs * sizeof(uint64_t *)); 96 | turbo_storage(&val); 97 | } 98 | /* Set IDA/Turbo DISENGAGE (bit 32) of IA32_PERF_CTL to 0. */ 99 | read_batch(PERF_CTL); 100 | for (j = 0; j < numDevs; j++) 101 | { 102 | *val[j] |= ((uint64_t)1) << 32; 103 | } 104 | write_batch(PERF_CTL); 105 | } 106 | 107 | void dump_turbo(FILE *writedest) 108 | { 109 | int core; 110 | static uint64_t numDevs = 0; 111 | uint64_t val; 112 | if (!numDevs) 113 | { 114 | numDevs = num_devs(); 115 | } 116 | for (core = 0; core < numDevs; core++) 117 | { 118 | read_msr_by_idx(core, IA32_MISC_ENABLE, &val); 119 | fprintf(writedest, "Core: %d\n", core); 120 | fprintf(writedest, "0x%016lx\t", val & (((uint64_t)1)<<38)); 121 | fprintf(writedest, "| IA32_MISC_ENABLE | 38 (0 = Turbo Available) \n"); 122 | read_msr_by_idx(core, IA32_PERF_CTL, &val); 123 | fprintf(writedest, "0x%016lx \t", val & (((uint64_t)1)<<32)); 124 | fprintf(writedest, "| IA32_PERF_CTL | 32 (0 = Turbo Engaged) \n"); 125 | } 126 | } 127 | 128 | #ifndef IS_ARCH_2D 129 | void calc_max_non_turbo(const unsigned socket, struct turbo_activation_ratio_data *info) 130 | { 131 | sockets_assert(&socket, __LINE__, __FILE__); 132 | #ifdef LIBMSR_DEBUG 133 | fprintf(stderr, "%s %s::%d DEBUG: (calc_max_non_turbo)\n", getenv("HOSTNAME"), __FILE__, __LINE__); 134 | #endif 135 | printf(" bits = %lx\n", info->bits); 136 | info->max_non_turbo_ratio = ((double)(MASK_VAL(info->bits, 7, 0))) * 100; 137 | printf(" max non turbo ratio = %.0f\n", info->max_non_turbo_ratio); 138 | } 139 | 140 | int get_max_turbo_activation_ratio(const unsigned socket, struct turbo_activation_ratio_data *info) 141 | { 142 | static uint64_t *rapl_flags = NULL; 143 | sockets_assert(&socket, __LINE__, __FILE__); 144 | 145 | if (rapl_flags == NULL) 146 | { 147 | if (rapl_storage(NULL, &rapl_flags)) 148 | { 149 | return -1; 150 | } 151 | } 152 | 153 | /* Check if MSR_TURBO_ACTIVATION_RATIO exists on this platform. */ 154 | if (*rapl_flags & TURBO_ACTIVATION_RATIO) 155 | { 156 | read_msr_by_coord(socket, 0, 0, MSR_TURBO_ACTIVATION_RATIO, &(info->bits)); 157 | calc_max_non_turbo(socket, info); 158 | } 159 | else 160 | { 161 | libmsr_error_handler("get_max_turbo_activation_ratio(): MSR_TURBO_ACTIVATION_RATIO not supported", LIBMSR_ERROR_PLATFORM_NOT_SUPPORTED, getenv("HOSTNAME"), __FILE__, __LINE__); 162 | return -1; 163 | } 164 | return 0; 165 | } 166 | 167 | void calc_max_turbo_ratio(const unsigned socket, struct turbo_limit_data *info, struct turbo_limit_data *info2) 168 | { 169 | sockets_assert(&socket, __LINE__, __FILE__); 170 | #ifdef LIBMSR_DEBUG 171 | fprintf(stderr, "%s %s::%d DEBUG: (calc_max_non_turbo)\n", getenv("HOSTNAME"), __FILE__, __LINE__); 172 | #endif 173 | 174 | if (info != NULL) 175 | { 176 | printf(" bits = %lx\n", info->bits); 177 | info->max_1c = ((double)(MASK_VAL(info->bits, 7, 0))) * 100; 178 | info->max_2c = ((double)(MASK_VAL(info->bits, 15, 8))) * 100; 179 | info->max_3c = ((double)(MASK_VAL(info->bits, 23, 16))) * 100; 180 | info->max_4c = ((double)(MASK_VAL(info->bits, 31, 24))) * 100; 181 | info->max_5c = ((double)(MASK_VAL(info->bits, 39, 32))) * 100; 182 | info->max_6c = ((double)(MASK_VAL(info->bits, 47, 40))) * 100; 183 | info->max_7c = ((double)(MASK_VAL(info->bits, 55, 48))) * 100; 184 | info->max_8c = ((double)(MASK_VAL(info->bits, 63, 56))) * 100; 185 | printf(" max ratio 1C = %.0f MHz\n", info->max_1c); 186 | printf(" max ratio 2C = %.0f MHz\n", info->max_2c); 187 | printf(" max ratio 3C = %.0f MHz\n", info->max_3c); 188 | printf(" max ratio 4C = %.0f MHz\n", info->max_4c); 189 | printf(" max ratio 5C = %.0f MHz\n", info->max_5c); 190 | printf(" max ratio 6C = %.0f MHz\n", info->max_6c); 191 | printf(" max ratio 7C = %.0f MHz\n", info->max_7c); 192 | printf(" max ratio 8C = %.0f MHz\n", info->max_8c); 193 | printf("\n"); 194 | } 195 | else if (info2 != NULL) 196 | { 197 | printf(" bits = %lx\n", info2->bits); 198 | info2->max_1c = ((double)(MASK_VAL(info2->bits, 7, 0))) * 100; 199 | info2->max_2c = ((double)(MASK_VAL(info2->bits, 15, 8))) * 100; 200 | info2->max_3c = ((double)(MASK_VAL(info2->bits, 23, 16))) * 100; 201 | info2->max_4c = ((double)(MASK_VAL(info2->bits, 31, 24))) * 100; 202 | info2->max_5c = ((double)(MASK_VAL(info2->bits, 39, 32))) * 100; 203 | info2->max_6c = ((double)(MASK_VAL(info2->bits, 47, 40))) * 100; 204 | info2->max_7c = ((double)(MASK_VAL(info2->bits, 55, 48))) * 100; 205 | info2->max_8c = ((double)(MASK_VAL(info2->bits, 63, 56))) * 100; 206 | printf(" max ratio 9C = %.0f MHz\n", info2->max_1c); 207 | printf(" max ratio 10C = %.0f MHz\n", info2->max_2c); 208 | printf(" max ratio 11C = %.0f MHz\n", info2->max_3c); 209 | printf(" max ratio 12C = %.0f MHz\n", info2->max_4c); 210 | printf(" max ratio 13C = %.0f MHz\n", info2->max_5c); 211 | printf(" max ratio 14C = %.0f MHz\n", info2->max_6c); 212 | printf(" max ratio 15C = %.0f MHz\n", info2->max_7c); 213 | printf(" max ratio 16C = %.0f MHz\n", info2->max_8c); 214 | } 215 | } 216 | 217 | int get_turbo_ratio_limit(const unsigned socket, struct turbo_limit_data *info, struct turbo_limit_data *info2) 218 | { 219 | static uint64_t *rapl_flags = NULL; 220 | sockets_assert(&socket, __LINE__, __FILE__); 221 | if (rapl_flags == NULL) 222 | { 223 | if (rapl_storage(NULL, &rapl_flags)) 224 | { 225 | return -1; 226 | } 227 | } 228 | 229 | /* Check if MSR_TURBO_RATIO_LIMIT exists on this platform. */ 230 | if (*rapl_flags & TURBO_RATIO_LIMIT) 231 | { 232 | read_msr_by_coord(socket, 0, 0, MSR_TURBO_RATIO_LIMIT, &(info->bits)); 233 | calc_max_turbo_ratio(socket, info, NULL); 234 | } 235 | else 236 | { 237 | libmsr_error_handler("get_turbo_ratio_limit(): MSR_TURBO_RATIO_LIMIT not supported", LIBMSR_ERROR_PLATFORM_NOT_SUPPORTED, getenv("HOSTNAME"), __FILE__, __LINE__); 238 | return -1; 239 | } 240 | 241 | /* Check if MSR_TURBO_RATIO_LIMIT1 exists on this platform. */ 242 | if (*rapl_flags & TURBO_RATIO_LIMIT1) 243 | { 244 | read_msr_by_coord(socket, 0, 0, MSR_TURBO_RATIO_LIMIT1, &(info2->bits)); 245 | calc_max_turbo_ratio(socket, NULL, info2); 246 | } 247 | else 248 | { 249 | libmsr_error_handler("get_turbo_ratio_limit(): MSR_TURBO_RATIO_LIMIT1 not supported", LIBMSR_ERROR_PLATFORM_NOT_SUPPORTED, getenv("HOSTNAME"), __FILE__, __LINE__); 250 | return -1; 251 | } 252 | return 0; 253 | } 254 | #endif 255 | -------------------------------------------------------------------------------- /test/libmsr_dump_data.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include "cpuid.h" 38 | #include "msr_core.h" 39 | #include "msr_rapl.h" 40 | #include "msr_thermal.h" 41 | #include "msr_counters.h" 42 | #include "msr_clocks.h" 43 | #include "msr_misc.h" 44 | #include "msr_turbo.h" 45 | #include "csr_core.h" 46 | #include "csr_imc.h" 47 | #include "libmsr_error.h" 48 | 49 | struct rapl_limit l1, l2, l3; 50 | 51 | void get_limits() 52 | { 53 | int i; 54 | static uint64_t sockets = 0; 55 | 56 | if (!sockets) 57 | { 58 | core_config(NULL, NULL, &sockets, NULL); 59 | } 60 | for (i = 0; i < sockets; i++) 61 | { 62 | if (i != 0) 63 | { 64 | fprintf(stdout, "\n"); 65 | } 66 | fprintf(stdout, "Socket %d:\n", i); 67 | if (get_pkg_rapl_limit(i, &l1, &l2) == 0) 68 | { 69 | fprintf(stdout, "Pkg Domain Power Lim 1 (lower lim)\n"); 70 | dump_rapl_limit(&l1, stdout); 71 | fprintf(stdout, "\n"); 72 | fprintf(stdout, "Pkg Domain Power Lim 2 (upper lim)\n"); 73 | dump_rapl_limit(&l2, stdout); 74 | } 75 | if (get_dram_rapl_limit(i, &l3) == 0) 76 | { 77 | fprintf(stdout, "\nDRAM Domain\n"); 78 | dump_rapl_limit(&l3, stdout); 79 | } 80 | } 81 | } 82 | 83 | // TODO: test other parts of thermal 84 | void thermal_test() 85 | { 86 | dump_therm_temp_reading(stdout); 87 | fprintf(stdout, "\n* Thermal Terse Printout *\n"); 88 | dump_therm_data_verbose_label(stdout); 89 | dump_therm_data_verbose(stdout); 90 | fprintf(stdout, "\n"); 91 | } 92 | 93 | void counters_test() 94 | { 95 | fprintf(stdout, "\n--- Fixed Performance Counters (Instr Ret, Unhalt Core Cyc, Unhalt Ref Cyc) ---\n"); 96 | dump_fixed_counter_data_readable(stdout); 97 | 98 | fprintf(stdout, "\n* Fixed Perf Counters Terse Printout *\n"); 99 | dump_fixed_counter_data_terse_label(stdout); 100 | dump_fixed_counter_data_terse(stdout); 101 | fprintf(stdout, "\n"); 102 | 103 | fprintf(stdout, "\n--- Performance Counters ---\n"); 104 | dump_pmc_data_readable(stdout); 105 | } 106 | 107 | // TODO: test other parts of clocks 108 | void clocks_test() 109 | { 110 | uint64_t sockets = 0; 111 | int i, j; 112 | struct clock_mod t; 113 | uint64_t coresPerSocket; 114 | 115 | sockets = num_sockets(); 116 | coresPerSocket = cores_per_socket(); 117 | 118 | fprintf(stdout, "\n--- Read IA32_APERF, IA32_MPERF, and IA32_TIME_STAMP_COUNTER ---\n"); 119 | dump_clocks_data_readable(stdout); 120 | 121 | fprintf(stdout, "\n* Clocks Terse Printout *\n"); 122 | dump_clocks_data_terse_label(stdout); 123 | dump_clocks_data_terse(stdout); 124 | fprintf(stdout, "\n"); 125 | 126 | fprintf(stdout, "\n--- Reading IA32_PERF_STATUS ---\n"); 127 | dump_p_state(stdout); 128 | 129 | fprintf(stdout, "\n--- Reading IA32_CLOCK_MODULATION ---\n"); 130 | for (i = 0; i < sockets; i++) 131 | { 132 | for (j = 0; j < coresPerSocket; j++) 133 | { 134 | get_clock_mod(i, j, &t); 135 | fprintf(stdout, "Socket %d, Core %2d\n", i, j); 136 | dump_clock_mod(&t, stdout); 137 | fprintf(stdout, "\n"); 138 | } 139 | } 140 | } 141 | 142 | void misc_test() 143 | { 144 | struct misc_enable s; 145 | uint64_t sockets = 0; 146 | int i; 147 | core_config(NULL, NULL, &sockets, NULL); 148 | for (i = 0; i < sockets; i++) 149 | { 150 | get_misc_enable(i, &s); 151 | dump_misc_enable(&s); 152 | } 153 | } 154 | 155 | void turbo_test() 156 | { 157 | dump_turbo(stdout); 158 | } 159 | 160 | #define PT_INC 100000 161 | 162 | void rapl_r_test(struct rapl_data **rd) 163 | { 164 | //r1 = &((*rd)[0]); 165 | //r2 = &((*rd)[1]); 166 | poll_rapl_data(); 167 | //poll_rapl_data(0, NULL); 168 | //poll_rapl_data(1, NULL); 169 | fprintf(stdout, "Sample #1\n"); 170 | dump_rapl_data(stdout); 171 | 172 | usleep(PT_INC); 173 | 174 | poll_rapl_data(); 175 | fprintf(stdout, "\nSample #2\n"); 176 | dump_rapl_data(stdout); 177 | } 178 | 179 | int repeated_poll_test() 180 | { 181 | usleep(PT_INC); 182 | poll_rapl_data(); 183 | fprintf(stdout, "Sample #1\n"); 184 | dump_rapl_data(stdout); 185 | usleep(PT_INC); 186 | poll_rapl_data(); 187 | fprintf(stdout, "\nSample #2\n"); 188 | dump_rapl_data(stdout); 189 | usleep(PT_INC); 190 | poll_rapl_data(); 191 | fprintf(stdout, "\nSample #3\n"); 192 | dump_rapl_data(stdout); 193 | usleep(PT_INC); 194 | poll_rapl_data(); 195 | fprintf(stdout, "\nSample #4\n"); 196 | dump_rapl_data(stdout); 197 | usleep(PT_INC); 198 | poll_rapl_data(); 199 | fprintf(stdout, "\nSample #5\n"); 200 | dump_rapl_data(stdout); 201 | usleep(PT_INC); 202 | poll_rapl_data(); 203 | fprintf(stdout, "\nSample #6\n"); 204 | dump_rapl_data(stdout); 205 | return 0; 206 | } 207 | 208 | void set_to_defaults() 209 | { 210 | int socket = 0; 211 | int numsockets = num_sockets(); 212 | struct rapl_power_info raplinfo; 213 | struct rapl_limit socketlim, socketlim2, dramlim; 214 | 215 | for (socket = 0; socket < numsockets; socket++) 216 | { 217 | if (socket != 0) 218 | { 219 | fprintf(stdout, "\n"); 220 | } 221 | fprintf(stdout, "Socket %d:\n", socket); 222 | get_rapl_power_info(socket, &raplinfo); 223 | socketlim.bits = 0; 224 | socketlim.watts = raplinfo.pkg_therm_power; 225 | socketlim.seconds = 1; 226 | socketlim2.bits = 0; 227 | socketlim2.watts = raplinfo.pkg_therm_power * 1.2; 228 | socketlim2.seconds = 3; 229 | dramlim.bits = 0; 230 | dramlim.watts = raplinfo.dram_max_power; 231 | dramlim.seconds = 1; 232 | fprintf(stdout, "Pkg Domain Power Lim 1 (lower lim)\n"); 233 | dump_rapl_limit(&socketlim, stdout); 234 | fprintf(stdout, "\n"); 235 | fprintf(stdout, "Pkg Domain Power Lim 2 (upper lim)\n"); 236 | dump_rapl_limit(&socketlim2, stdout); 237 | fprintf(stdout, "\nDRAM Domain\n"); 238 | dump_rapl_limit(&dramlim, stdout); 239 | set_pkg_rapl_limit(socket, &socketlim, &socketlim2); 240 | set_dram_rapl_limit(socket, &dramlim); 241 | } 242 | } 243 | 244 | // TODO: check if test for oversized bitfield is in place, change that warning 245 | // to an error 246 | int main(int argc, char **argv) 247 | { 248 | struct rapl_data *rd = NULL; 249 | uint64_t *rapl_flags = NULL; 250 | uint64_t cores = 0; 251 | uint64_t threads = 0; 252 | uint64_t sockets = 0; 253 | int ri_stat = 0; 254 | 255 | if (!sockets) 256 | { 257 | core_config(&cores, &threads, &sockets, NULL); 258 | } 259 | 260 | if (init_msr()) 261 | { 262 | libmsr_error_handler("Unable to initialize libmsr", LIBMSR_ERROR_MSR_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 263 | return -1; 264 | } 265 | fprintf(stdout, "\n===== MSR Init Done =====\n"); 266 | 267 | ri_stat = rapl_init(&rd, &rapl_flags); 268 | if (ri_stat < 0) 269 | { 270 | libmsr_error_handler("Unable to initialize rapl", LIBMSR_ERROR_RAPL_INIT, getenv("HOSTNAME"), __FILE__, __LINE__); 271 | return -1; 272 | } 273 | fprintf(stdout, "\n===== RAPL Init Done =====\n"); 274 | 275 | fprintf(stdout, "\n===== Available RAPL Registers =====\n"); 276 | print_available_rapl(); 277 | 278 | fprintf(stdout, "\n===== Get Initial RAPL Power Limits =====\n"); 279 | get_limits(); 280 | 281 | fprintf(stdout, "\n===== Thermal Test =====\n"); 282 | thermal_test(); 283 | 284 | fprintf(stdout, "\n===== Clocks Test =====\n"); 285 | clocks_test(); 286 | 287 | fprintf(stdout, "===== Read IA32_MISC_ENABLE =====\n"); 288 | misc_test(); 289 | 290 | fprintf(stdout, "\n===== Available Performance Counters =====\n"); 291 | print_available_counters(); 292 | 293 | fprintf(stdout, "\n===== Counters Test =====\n"); 294 | counters_test(); 295 | 296 | fprintf(stdout, "\n===== Poll RAPL Data 2X =====\n"); 297 | rapl_r_test(&rd); 298 | 299 | fprintf(stdout, "\n===== Repeated RAPL Polling Test =====\n"); 300 | repeated_poll_test(); 301 | 302 | fprintf(stdout, "\n===== Setting Defaults =====\n"); 303 | set_to_defaults(); 304 | 305 | finalize_msr(); 306 | fprintf(stdout, "\n===== MSR Finalized =====\n"); 307 | 308 | fprintf(stdout, "\n===== Test Finished Successfully =====\n"); 309 | if (ri_stat) 310 | { 311 | fprintf(stdout, "\nFound %d locked rapl register(s)\n", ri_stat); 312 | } 313 | 314 | return 0; 315 | } 316 | -------------------------------------------------------------------------------- /include/cpuid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #ifndef CPUID_H_INCLUDE 32 | #define CPUID_H_INCLUDE 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | /// @brief Create a mask from bit m to n (63 >= m >= n >= 0). 43 | /// 44 | /// Example: MASK_RANGE(4,2) --> (((1<<((4)-(2)+1))-1)<<(2)) 45 | /// (((1<< 3)-1)<<(2)) 46 | /// (( 4-1)<<(2)) 47 | /// ( 3)<<(2)) 48 | /// ( 24) = b11000 49 | #define MASK_RANGE(m,n) ((((uint64_t)1<<((m)-(n)+1))-1)<<(n)) 50 | 51 | /// @brief Return the value of x after applying bitmask (m,n) (63 >= m >= n >= 0). 52 | /// 53 | /// Example: MASK_RANGE(17,4,2) --> 17&24 = b10001 & b11000 = b10000 54 | #define MASK_VAL(x,m,n) (((uint64_t)(x)&MASK_RANGE((m),(n)))>>(n)) 55 | 56 | /// @brief Get processor identification and feature information to the 32-bit 57 | /// EAX, EBX, ECX, and EDX registers. 58 | /// 59 | /// @param [in] leaf Level of basic processor information to be returned. 60 | /// 61 | /// @param [out] rax EAX register contents. 62 | /// 63 | /// @param [out] rbx EBX register contents. 64 | /// 65 | /// @param [out] rcx ECX register contents. 66 | /// 67 | /// @param [out] rdx EDX register contents. 68 | void cpuid(uint64_t leaf, 69 | uint64_t *rax, 70 | uint64_t *rbx, 71 | uint64_t *rcx, 72 | uint64_t *rdx); 73 | 74 | /// @brief Determine platform configuration (i.e. number of sockets, number of 75 | /// cores/socket, number of logical processors, etc.). 76 | /// 77 | /// @param [out] coresPerSocket Number of cores per socket (including 78 | /// hyperthreads, if enabled). 79 | /// 80 | /// @param [out] hyperThreads Number of threads including hyperthreads. 81 | /// 82 | /// @param [out] sockets Number of sockets. 83 | /// 84 | /// @param [out] HTenabled Hyperthreading enabled/disabled. 85 | void cpuid_detect_core_conf(uint64_t *coresPerSocket, 86 | uint64_t *hyperThreads, 87 | uint64_t *sockets, 88 | int *HTenabled); 89 | 90 | /// @brief Retrieve the CPU model number. 91 | /// 92 | /// @param [out] model CPU model number. 93 | void cpuid_get_model(uint64_t *model); 94 | 95 | /// @brief Get max number of physical processor cores on the platform. 96 | /// 97 | /// @param [in] leafa Initial value for EAX. 98 | /// 99 | /// @param [in] leafc Initial value for ECX. 100 | /// 101 | /// @param [out] rax EAX register contents. 102 | /// 103 | /// @param [out] rbx EBX register contents. 104 | /// 105 | /// @param [out] rcx ECX register contents. 106 | /// 107 | /// @param [out] rdx EDX register contents. 108 | void cpuidInput_rax_rcx(uint64_t leafa, 109 | uint64_t leafc, 110 | uint64_t *rax, 111 | uint64_t *rbx, 112 | uint64_t *rcx, 113 | uint64_t *rdx); 114 | 115 | /// @brief Check availability of p-state hardware coordination feedback, 116 | /// indicating presence of IA32_APERF and IA32_MPERF. 117 | /// 118 | /// @return True if IA32_APERF and IA32_MPERF are available, else false. 119 | bool cpuid_mperf_and_aperf_avail(void); 120 | 121 | /// @brief Check availability of the time-stamp counter. 122 | /// 123 | /// @return True if the time-stamp counter is available, else false. 124 | bool cpuid_timestamp_counter_avail(void); 125 | 126 | /*****************************************/ 127 | /* Performance Monitoring Counters (PMC) */ 128 | /*****************************************/ 129 | 130 | /// @brief Determine which performance monitoring counters (PMCs) are available. 131 | /// 132 | /// If greater than 3, then up to PMC3 is usable. If greater than 2, then up to 133 | /// PMC2 is usable. If greater than 1, then up to PMC1 is usable. If greater than 134 | /// 0, then only PMC0 is usable. If equal to 0, then no PMCs are usable. 135 | /// 136 | /// @return Number of PMCs are available. 137 | int cpuid_num_pmc(void); 138 | 139 | /*****************************************/ 140 | /* Performance Event Select (PerfEvtSel) */ 141 | /* (0x186, 0x187, 0x188, 0x189) */ 142 | /*****************************************/ 143 | 144 | /// @brief Determine which performance event select MSRs (PerfEvtSelX) are 145 | /// available. 146 | /// 147 | /// If greater than 3, then up to PerfEvtSel3 is usable. If greater than 2, 148 | /// then up to PerfEvtSel2 is usable. If greater than 1, then up to PerfEvtSel1 149 | /// is usable. If greater than 0, then only PerfEvtSel0 is usable. If equal to 150 | /// 0, then no PerfEvtSel MSRs are usable. 151 | /// 152 | /// @return Number of PerfEvtSel MSRs are available. 153 | int cpuid_num_perfevtsel(void); 154 | 155 | /***************************/ 156 | /* PERF_GLOBAL_CTL (0x38f) */ 157 | /***************************/ 158 | 159 | /// @brief Determine if performance monitoring capabilities are available. 160 | /// 161 | /// @return True if architectural performance monitoring capabilities are 162 | /// supported, else false. 163 | bool cpuid_perf_global_ctrl_EN_PMC(void); 164 | 165 | /// @brief Check availability of the three fixed-function performance counters: 166 | /// Instr_Retired.Any, CPU_CLK_Unhalted.Core, and CPU_CLK_Unhalted.Ref. 167 | /// 168 | /// @return True if IA32_FIXED_CTR0, IA32_FIXED_CTR1, and IA32_FIXED_CTR2 169 | /// exist, else false. 170 | bool cpuid_perf_global_ctrl_EN_FIXED_CTRnum(void); 171 | 172 | /***************/ 173 | /* MISC_ENABLE */ 174 | /***************/ 175 | 176 | /// @brief Check if Turbo mode is disabled 177 | /// 178 | /// @return True if Turbo mode is disabled, else false. 179 | bool cpuid_misc_enable_TurboModeDisable(void); 180 | 181 | /// @brief Check if xTPR messages are disabled. 182 | /// 183 | /// @return True if xTPR messages are disabled, else false. 184 | bool cpuid_misc_enable_xTPRMessageDisable(void); 185 | 186 | /// @brief Check if XD bit is disabled. 187 | /// 188 | /// @return True if XD bit is disabled, else false. 189 | bool cpuid_misc_enable_XDbitDisable(void); 190 | 191 | /*************/ 192 | /* CLOCK_MOD */ 193 | /*************/ 194 | 195 | /// @brief Check if extended on-demand clock modulation is enabled. 196 | /// 197 | /// @return True if extended on-demand clock modulation is enabled, else false. 198 | bool cpuid_enable_ExtendedClockMod(void); 199 | 200 | /*********************/ 201 | /* THERMAL Functions */ 202 | /*********************/ 203 | 204 | /// @brief Check if Thermal Threshold #1 status and log and Thermal Threshold 205 | /// #2 status and log are enabled in IA32_THERM_STATUS. 206 | /// 207 | /// @return True if TT#1 and TT#2 status and log are enabled, else false. 208 | bool cpuid_therm_status_enable_ThermalThresholds(void); 209 | 210 | /// @brief Check if power limitation status and log are enabled in 211 | /// IA32_THERM_STATUS. 212 | /// 213 | /// @return True if power limitation status and log are enabled, else false. 214 | bool cpuid_therm_status_enable_PowerLimitNotify(void); 215 | 216 | /// @brief Check if digital readout is enabled in IA32_THERM_STATUS. 217 | /// 218 | /// @return True if digital readout is enabled, else false. 219 | bool cpuid_therm_status_enable_DigitalReadout(void); 220 | 221 | /// @brief Check if power limit notification enable is enabled in 222 | /// IA32_THERM_INTERRUPT. 223 | /// 224 | /// @return True if power limitation status and log are enabled, else false. 225 | bool cpuid_therm_interrupt_enable_PowerLimitNotify(void); 226 | 227 | /// @brief Check if IA32_PACKAGE_THERM_STATUS and IA32_PACKAGE_THERM_INTERRUPT 228 | /// are enabled on the platform. 229 | /// 230 | /// @return True if package-level thermal status and interrupt register are 231 | /// enabled, else false. 232 | bool cpuid_pkg_therm_enable_status_and_interrupt(void); 233 | 234 | /************************/ 235 | /* General Machine Info */ 236 | /************************/ 237 | 238 | /// @brief Get highest EAX value (i.e., leaf) supported by the platform. 239 | /// 240 | /// @return Highest EAX leaf supported by the platform. 241 | uint64_t cpuid_MaxLeaf(void); 242 | 243 | /// @brief Print platform vendor ID. 244 | void cpuid_printVendorID(void); 245 | 246 | /// @brief Get max number of addressable IDs attributable to processor cores 247 | /// in the physical package. 248 | /// 249 | /// @return Max number of processor cores in the package. 250 | int cpuid_pkg_MaxPhysicalProcessorCores(void); 251 | 252 | /// @brief Get max number of addressable IDs for logical processors in a 253 | /// physical package. 254 | /// 255 | /// @return Max number of logical processors in the package. 256 | int cpuid_pkg_MaxLogicalProcessors(void); 257 | 258 | /// @brief Get number of fixed-function performance counters on the platform. 259 | /// 260 | /// @return Number of available fixed-function performance counters. 261 | int cpuid_num_fixed_counters(void); 262 | 263 | /// @brief Get bit width of fixed-function performance counters on the platform. 264 | /// 265 | /// @return Bit width of fixed-function performance counters. 266 | int cpuid_width_fixed_counters(void); 267 | 268 | #ifdef __cplusplus 269 | } 270 | #endif 271 | #endif 272 | -------------------------------------------------------------------------------- /platform_headers/Intel2D.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC. 3 | * 4 | * Produced at the Lawrence Livermore National Laboratory. Written by: 5 | * Barry Rountree , 6 | * Scott Walker , and 7 | * Kathleen Shoga . 8 | * 9 | * LLNL-CODE-645430 10 | * 11 | * All rights reserved. 12 | * 13 | * This file is part of libmsr. For details, see https://github.com/LLNL/libmsr.git. 14 | * 15 | * Please also read libmsr/LICENSE for our notice and the LGPL. 16 | * 17 | * libmsr is free software: you can redistribute it and/or modify it under the 18 | * terms of the GNU Lesser General Public License (as published by the Free 19 | * Software Foundation) version 2.1 dated February 1999. 20 | * 21 | * libmsr is distributed in the hope that it will be useful, but WITHOUT ANY 22 | * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS 23 | * FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU Lesser 24 | * General Public License for more details. 25 | * 26 | * You should have received a copy of the GNU Lesser General Public License 27 | * along with libmsr; if not, write to the Free Software Foundation, Inc., 59 28 | * Temple Place, Suite 330, Boston, MA 02111-1307 USA. 29 | */ 30 | 31 | #define COMPILED_VEND 0x8086 // Intel 32 | #define COMPILED_ARCH 0x2D // Sandy Bridge 33 | #define IS_ARCH_2D 1 34 | 35 | /**********/ 36 | /* CLOCKS */ 37 | /**********/ 38 | #define IA32_MPERF 0xE7 39 | #define IA32_APERF 0xE8 40 | #define IA32_TIME_STAMP_COUNTER 0x10 41 | #define IA32_CLOCK_MODULATION 0x19A 42 | #define IA32_PERF_STATUS 0x198 43 | #define IA32_PERF_CTL 0x199 44 | 45 | /************/ 46 | /* COUNTERS */ 47 | /************/ 48 | #define IA32_FIXED_CTR_CTRL 0x38D // Controls for fixed ctr0, 1, and 2 49 | #define IA32_PERF_GLOBAL_CTRL 0x38F // Enables for fixed ctr0,1,and2 here 50 | #define IA32_PERF_GLOBAL_STATUS 0x38E // Overflow condition can be found 51 | // here 52 | #define IA32_PERF_GLOBAL_OVF_CTRL 0x390 // Can clear the overflow here 53 | #define IA32_FIXED_CTR0 0x309 // (R/W) Counts Instr_Retired.Any 54 | #define IA32_FIXED_CTR1 0x30A // (R/W) Counts CPU_CLK_Unhalted.Core 55 | #define IA32_FIXED_CTR2 0x30B // (R/W) Counts CPU_CLK_Unhalted.Ref 56 | 57 | #define IA32_PMC0 0xC1 58 | #define IA32_PMC1 0xC2 59 | #define IA32_PMC2 0xC3 60 | #define IA32_PMC3 0xC4 61 | #define IA32_PMC4 0xC5 62 | #define IA32_PMC5 0xC6 63 | #define IA32_PMC6 0xC7 64 | #define IA32_PMC7 0xC8 65 | 66 | #define IA32_PERFEVTSEL0 0x186 67 | #define IA32_PERFEVTSEL1 0x187 68 | #define IA32_PERFEVTSEL2 0x188 69 | #define IA32_PERFEVTSEL3 0x189 70 | #define IA32_PERFEVTSEL4 0x18A 71 | #define IA32_PERFEVTSEL5 0x18B 72 | #define IA32_PERFEVTSEL6 0x18C 73 | #define IA32_PERFEVTSEL7 0x18D 74 | 75 | #define MSR_PCU_PMON_EVNTSEL0 0xC30 76 | #define MSR_PCU_PMON_EVNTSEL1 0xC31 77 | #define MSR_PCU_PMON_EVNTSEL2 0xC32 78 | #define MSR_PCU_PMON_EVNTSEL3 0xC33 79 | #define MSR_PCU_PMON_CTR0 0xC36 80 | #define MSR_PCU_PMON_CTR1 0xC37 81 | #define MSR_PCU_PMON_CTR2 0xC38 82 | #define MSR_PCU_PMON_CTR3 0xC39 83 | 84 | #define MSR_C0_PMON_BOX_CTL 0xD04 85 | #define MSR_C0_PMON_EVNTSEL0 0xD10 86 | #define MSR_C0_PMON_EVNTSEL1 0xD11 87 | #define MSR_C0_PMON_EVNTSEL2 0xD12 88 | #define MSR_C0_PMON_EVNTSEL3 0xD13 89 | #define MSR_C0_BOX_FILTER 0xD14 90 | #define MSR_C0_PMON_CTR0 0xD16 91 | #define MSR_C0_PMON_CTR1 0xD17 92 | #define MSR_C0_PMON_CTR2 0xD18 93 | #define MSR_C0_PMON_CTR3 0xD19 94 | 95 | #define MSR_C1_PMON_BOX_CTL 0xD24 96 | #define MSR_C1_PMON_EVNTSEL0 0xD30 97 | #define MSR_C1_PMON_EVNTSEL1 0xD31 98 | #define MSR_C1_PMON_EVNTSEL2 0xD32 99 | #define MSR_C1_PMON_EVNTSEL3 0xD33 100 | #define MSR_C1_BOX_FILTER 0xD34 101 | #define MSR_C1_PMON_CTR0 0xD36 102 | #define MSR_C1_PMON_CTR1 0xD37 103 | #define MSR_C1_PMON_CTR2 0xD38 104 | #define MSR_C1_PMON_CTR3 0xD39 105 | 106 | #define MSR_C2_PMON_BOX_CTL 0xD44 107 | #define MSR_C2_PMON_EVNTSEL0 0xD50 108 | #define MSR_C2_PMON_EVNTSEL1 0xD51 109 | #define MSR_C2_PMON_EVNTSEL2 0xD52 110 | #define MSR_C2_PMON_EVNTSEL3 0xD53 111 | #define MSR_C2_BOX_FILTER 0xD54 112 | #define MSR_C2_PMON_CTR0 0xD56 113 | #define MSR_C2_PMON_CTR1 0xD57 114 | #define MSR_C2_PMON_CTR2 0xD58 115 | #define MSR_C2_PMON_CTR3 0xD59 116 | 117 | #define MSR_C3_PMON_BOX_CTL 0xD64 118 | #define MSR_C3_PMON_EVNTSEL0 0xD70 119 | #define MSR_C3_PMON_EVNTSEL1 0xD71 120 | #define MSR_C3_PMON_EVNTSEL2 0xD72 121 | #define MSR_C3_PMON_EVNTSEL3 0xD73 122 | #define MSR_C3_BOX_FILTER 0xD74 123 | #define MSR_C3_PMON_CTR0 0xD76 124 | #define MSR_C3_PMON_CTR1 0xD77 125 | #define MSR_C3_PMON_CTR2 0xD78 126 | #define MSR_C3_PMON_CTR3 0xD79 127 | 128 | #define MSR_C4_PMON_BOX_CTL 0xD84 129 | #define MSR_C4_PMON_EVNTSEL0 0xD90 130 | #define MSR_C4_PMON_EVNTSEL1 0xD91 131 | #define MSR_C4_PMON_EVNTSEL2 0xD92 132 | #define MSR_C4_PMON_EVNTSEL3 0xD93 133 | #define MSR_C4_BOX_FILTER 0xD94 134 | #define MSR_C4_PMON_CTR0 0xD96 135 | #define MSR_C4_PMON_CTR1 0xD97 136 | #define MSR_C4_PMON_CTR2 0xD98 137 | #define MSR_C4_PMON_CTR3 0xD99 138 | 139 | #define MSR_C5_PMON_BOX_CTL 0xDA4 140 | #define MSR_C5_PMON_EVNTSEL0 0xDB0 141 | #define MSR_C5_PMON_EVNTSEL1 0xDB1 142 | #define MSR_C5_PMON_EVNTSEL2 0xDB2 143 | #define MSR_C5_PMON_EVNTSEL3 0xDB3 144 | #define MSR_C5_BOX_FILTER 0xDB4 145 | #define MSR_C5_PMON_CTR0 0xDB6 146 | #define MSR_C5_PMON_CTR1 0xDB7 147 | #define MSR_C5_PMON_CTR2 0xDB8 148 | #define MSR_C5_PMON_CTR3 0xDB9 149 | 150 | #define MSR_C6_PMON_BOX_CTL 0xDC4 151 | #define MSR_C6_PMON_EVNTSEL0 0xDD0 152 | #define MSR_C6_PMON_EVNTSEL1 0xDD1 153 | #define MSR_C6_PMON_EVNTSEL2 0xDD2 154 | #define MSR_C6_PMON_EVNTSEL3 0xDD3 155 | #define MSR_C6_BOX_FILTER 0xDD4 156 | #define MSR_C6_PMON_CTR0 0xDD6 157 | #define MSR_C6_PMON_CTR1 0xDD7 158 | #define MSR_C6_PMON_CTR2 0xDD8 159 | #define MSR_C6_PMON_CTR3 0xDD9 160 | 161 | #define MSR_C7_PMON_BOX_CTL 0xDE4 162 | #define MSR_C7_PMON_EVNTSEL0 0xDF0 163 | #define MSR_C7_PMON_EVNTSEL1 0xDF1 164 | #define MSR_C7_PMON_EVNTSEL2 0xDF2 165 | #define MSR_C7_PMON_EVNTSEL3 0xDF3 166 | #define MSR_C7_BOX_FILTER 0xDF4 167 | #define MSR_C7_PMON_CTR0 0xDF6 168 | #define MSR_C7_PMON_CTR1 0xDF7 169 | #define MSR_C7_PMON_CTR2 0xDF8 170 | #define MSR_C7_PMON_CTR3 0xDF9 171 | 172 | /********/ 173 | /* MISC */ 174 | /********/ 175 | #define IA32_MISC_ENABLE 0x1A0 176 | #define MSR_PKG_C2_RESIDENCY 0x60D 177 | #define MSR_PKG_C3_RESIDENCY 0x3F8 178 | #define MSR_PKG_C6_RESIDENCY 0x3F9 179 | #define MSR_PKG_C7_RESIDENCY 0x3FA 180 | #define MSR_CORE_C3_RESIDENCY 0x3FC 181 | #define MSR_CORE_C6_RESIDENCY 0x3FD 182 | #define MSR_CORE_C7_RESIDENCY 0x3FE 183 | 184 | /********/ 185 | /* RAPL */ 186 | /********/ 187 | #define MSR_RAPL_POWER_UNIT 0x606 // ro 188 | #define MSR_PKG_POWER_LIMIT 0x610 // rw 189 | #define MSR_PKG_ENERGY_STATUS 0x611 // ro sic 190 | #define MSR_PKG_POWER_INFO 0x614 // rw text states ro 191 | 192 | #define MSR_PKG_PERF_STATUS 0x613 // ro 193 | #define MSR_DRAM_POWER_LIMIT 0x618 // rw 194 | #define MSR_DRAM_ENERGY_STATUS 0x619 // ro. sic 195 | #define MSR_DRAM_PERF_STATUS 0x61B // ro 196 | #define MSR_DRAM_POWER_INFO 0x61C // rw text states ro 197 | 198 | /***********/ 199 | /* THERMAL */ 200 | /***********/ 201 | #define IA32_THERM_STATUS 0x19C 202 | #define MSR_THERM2_CTL 0x19D 203 | #define IA32_THERM_INTERRUPT 0x19B 204 | #define IA32_PACKAGE_THERM_STATUS 0x1B1 205 | #define IA32_PACKAGE_THERM_INTERRUPT 0x1B2 206 | #define MSR_TEMPERATURE_TARGET 0x1A2 207 | 208 | /*********/ 209 | /* TURBO */ 210 | /*********/ 211 | #define IA32_MISC_ENABLE 0x1A0 212 | #define IA32_PERF_CTL 0x199 213 | 214 | /***********/ 215 | /* CSR iMC */ 216 | /***********/ 217 | #define IMC0_DEV 16 218 | #define IMC1_DEV 0 219 | #define IMC_CH0_FUNC 0 220 | #define IMC_CH1_FUNC 1 221 | #define IMC_CH2_FUNC 4 222 | #define IMC_CH3_FUNC 5 223 | 224 | #define CSR_PMONCTRCFG0 0xD8 225 | #define CSR_PMONCTRCFG1 0xDC 226 | #define CSR_PMONCTRCFG2 0xE0 227 | #define CSR_PMONCTRCFG3 0xE4 228 | 229 | #define CSR_PMONCTR0 0xA0 230 | #define CSR_PMONCTR1 0xA8 231 | #define CSR_PMONCTR2 0xB0 232 | #define CSR_PMONCTR3 0xB8 233 | 234 | #define CSR_PMONUNITCTRL 0xF4 235 | #define CSR_PMONUNITSTAT 0xF8 236 | 237 | /******************/ 238 | /* CSR iMC EVENTS */ 239 | /******************/ 240 | #define EVT_DCLOCKTICKS 0x00 241 | #define EVT_ACT_COUNT 0x01 242 | #define EVT_PRE_COUNT 0x02 243 | #define EVT_CAS_COUNT 0x04 244 | #define EVT_DRAM_REFRESH 0x05 245 | #define EVT_DRAM_PRE_ALL 0x06 246 | #define EVT_MAJOR_MODES 0x07 247 | #define EVT_PREEMPTION 0x08 248 | #define EVT_ECC_CORRECTABLE_ERRORS 0x09 249 | #define EVT_RPQ_INSERTS 0x10 250 | #define EVT_RPQ_CYCLES_NE 0x11 251 | #define EVT_WPQ_INSERTS 0x20 252 | #define EVT_WPQ_CYCLES_NE 0x21 253 | #define EVT_WPQ_CYCLES_FULL 0x22 254 | #define EVT_WPQ_READ_HIT 0x23 255 | #define EVT_WPQ_WRITE_HIT 0x24 256 | #define EVT_POWER_THROTTLE_CYCLES 0x41 257 | #define EVT_POWER_PCU_THROTTLING 0x42 258 | #define EVT_POWER_SELF_REFRESH 0x43 259 | #define EVT_POWER_CKE_CYCLES 0x83 260 | #define EVT_POWER_CHANNEL_DLLOFF 0x84 261 | #define EVT_POWER_CHANNEL_PD 0x85 262 | #define EVT_POWER_CRITICAL_THROTTLE_CYCLES 0x86 263 | 264 | #define UMASK_CAS_RD_REG 0x1 265 | #define UMASK_CAS_RD_UNDERFILL 0x2 266 | #define UMASK_CAS_RD 0x3 267 | #define UMASK_CAS_WR_WMM 0x4 268 | #define UMASK_CAS_WR_RMM 0x8 269 | #define UMASK_CAS_WR 0xC 270 | #define UMASK_CAS_ALL 0xF 271 | 272 | /*******************************/ 273 | /* Missing from documentation? */ 274 | /*******************************/ 275 | #define UMASK_ACT_COUNT_RD 0x1 276 | #define UMASK_ACT_COUNT_WR 0x2 277 | #define UMASK_ACT_COUNT_BYP 0x8 278 | #define UMASK_BYP_CMDS_ACT 0x1 279 | #define UMASK_BYP_CMDS_CAS 0x2 280 | #define UMASK_BYP_CMDS_PRE 0x4 281 | /* ?? */ 282 | 283 | #define UMASK_PRE_PAGE_MISS 0x1 284 | #define UMASK_PRE_PAGE_CLOSE 0x2 285 | 286 | /*******************************/ 287 | /* Missing from documentation? */ 288 | /*******************************/ 289 | #define UMASK_PRE_RD 0x4 290 | #define UMASK_PRE_WR 0x8 291 | #define UMASK_PRE_BYP 0x16 292 | --------------------------------------------------------------------------------