Commit 4e310f25 authored by Micha Müller's avatar Micha Müller

MSR plugin update:

-check if counters already enabled before programming them
-reset counters if stopped
parent 0418db48
......@@ -16,6 +16,7 @@
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <bitset>
#include <atomic>
#include <exception>
#include <utility>
......@@ -42,6 +43,11 @@ void MSRSensorGroup::start() {
return;
}
if (!program_fixed()) {
LOG(error) << "MSR fixed counters already in use! Can not start counters";
return;
}
for (auto &kv : cpuToFd) {
int cpu = kv.first;
char * path = new char[200];
......@@ -60,8 +66,6 @@ void MSRSensorGroup::start() {
cpuToFd[cpu] = handle;
}
program_fixed();
_keepRunning = 1;
_pendingTasks++;
_timer->async_wait(std::bind(&MSRSensorGroup::readAsync, this));
......@@ -69,13 +73,30 @@ void MSRSensorGroup::start() {
}
void MSRSensorGroup::stop() {
int temp = _keepRunning;
_keepRunning = 0;
for (auto &kv: cpuToFd) {
close(kv.second);
kv.second = -1;
}
//only close this stuff if we have been properly started before
if (temp) {
//close file descriptors
for (auto &kv: cpuToFd) {
close(kv.second);
kv.second = -1;
}
//reset counters
for (auto& kv : cpuToFd) {
//disable counters before writing anything else
msr_write(IA32_CR_PERF_GLOBAL_CTRL, 0, kv.first);
//reset all bits to 0
msr_write(IA32_CR_FIXED_CTR_CTRL, 0, kv.first);
//set all global enable bits to 1
uint64_t value = (1ULL << 0) + (1ULL << 1) + (1ULL << 2) + (1ULL << 3) + (1ULL << 32) + (1ULL << 33) + (1ULL << 34);
msr_write(IA32_CR_PERF_GLOBAL_CTRL, value, kv.first);
}
}
LOG(info) << "Sensorgroup " << _groupName << " stopped.";
}
......@@ -115,15 +136,35 @@ int32_t MSRSensorGroup::msr_write(uint64_t msr_number, uint64_t value, unsigned
return pwrite(cpuToFd[cpu], (const void *) &value, sizeof(uint64_t), msr_number);
}
void MSRSensorGroup::program_fixed(){
/**
* Program the fixed MSR as required for this plugin.
*
* @return True if counters programmed successfully, false otherwise, e.g.
* because the counters are already in use.
*/
bool MSRSensorGroup::program_fixed(){
unsigned failedCpu = 9999;
for (auto &kv : cpuToFd) {
// program core counters
//we do not want to interrupt other services already doing measurements with MSRs
//therefore check if any fixed counter is currently enabled
struct FixedEventControlRegister ctrl_reg;
// disable counters while programming
msr_write(IA32_CR_PERF_GLOBAL_CTRL, 0, kv.first);
std::bitset<64> cur_reg(ctrl_reg.value);
msr_read(IA32_CR_FIXED_CTR_CTRL, &ctrl_reg.value, kv.first);
if (cur_reg[0] || cur_reg[1] || cur_reg[4] || cur_reg[5] || cur_reg[8] || cur_reg[9]) {
//at least one is enabled. Do not overwrite them.
//Instead we revert the already programmed counters and return
failedCpu = kv.first;
break;
}
// disable counters while programming
msr_write(IA32_CR_PERF_GLOBAL_CTRL, 0, kv.first);
ctrl_reg.fields.os0 = 1;
ctrl_reg.fields.usr0 = 1;
ctrl_reg.fields.any_thread0 = 0;
......@@ -149,6 +190,25 @@ void MSRSensorGroup::program_fixed(){
msr_write(IA32_CR_PERF_GLOBAL_CTRL, value, kv.first);
}
//One of the fixed counters was already enabled.
//Reset all counters which were already programmed before returning.
if (failedCpu != 9999) {
for (auto& kv : cpuToFd) {
if (kv.first != failedCpu) {
//disable counters before writing anything else
msr_write(IA32_CR_PERF_GLOBAL_CTRL, 0, kv.first);
//reset all bits to 0
msr_write(IA32_CR_FIXED_CTR_CTRL, 0, kv.first);
//set all global enable bits to 1
uint64_t value = (1ULL << 0) + (1ULL << 1) + (1ULL << 2) + (1ULL << 3) + (1ULL << 32) + (1ULL << 33) + (1ULL << 34);
msr_write(IA32_CR_PERF_GLOBAL_CTRL, value, kv.first);
} else {
return false;
}
}
}
return true;
}
void MSRSensorGroup::addCpu(unsigned int cpu){
......
......@@ -35,7 +35,7 @@ private:
void read() override;
void readAsync() override;
void program_fixed();
bool program_fixed();
std::map<unsigned int,int> cpuToFd;
int32_t msr_read(uint64_t msr_number, uint64_t * value, unsigned int cpu);
int32_t msr_write(uint64_t msr_number, uint64_t value, unsigned int cpu);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment