Commit deab85c3 authored by Carla Guillen Carias's avatar Carla Guillen Carias
Browse files

Changes to handle conflict with monitoring: 1. we check if counters are...

Changes to handle conflict with monitoring: 1. we check if counters are already running, and just read them if this is the case. 2. we program them if they are not running. 3. When dcdb stops, they are left running for other agents like EAR.
parent 4e310f25
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <bitset>
#include <atomic> #include <atomic>
#include <exception> #include <exception>
#include <utility> #include <utility>
...@@ -43,10 +42,7 @@ void MSRSensorGroup::start() { ...@@ -43,10 +42,7 @@ void MSRSensorGroup::start() {
return; return;
} }
if (!program_fixed()) { program_fixed()
LOG(error) << "MSR fixed counters already in use! Can not start counters";
return;
}
for (auto &kv : cpuToFd) { for (auto &kv : cpuToFd) {
int cpu = kv.first; int cpu = kv.first;
...@@ -73,28 +69,10 @@ void MSRSensorGroup::start() { ...@@ -73,28 +69,10 @@ void MSRSensorGroup::start() {
} }
void MSRSensorGroup::stop() { void MSRSensorGroup::stop() {
int temp = _keepRunning; //close file descriptors and leave counters running freely
for (auto &kv: cpuToFd) {
_keepRunning = 0; 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."; LOG(info) << "Sensorgroup " << _groupName << " stopped.";
...@@ -142,8 +120,7 @@ int32_t MSRSensorGroup::msr_write(uint64_t msr_number, uint64_t value, unsigned ...@@ -142,8 +120,7 @@ int32_t MSRSensorGroup::msr_write(uint64_t msr_number, uint64_t value, unsigned
* @return True if counters programmed successfully, false otherwise, e.g. * @return True if counters programmed successfully, false otherwise, e.g.
* because the counters are already in use. * because the counters are already in use.
*/ */
bool MSRSensorGroup::program_fixed(){ void MSRSensorGroup::program_fixed(){
unsigned failedCpu = 9999;
for (auto &kv : cpuToFd) { for (auto &kv : cpuToFd) {
// program core counters // program core counters
...@@ -151,16 +128,16 @@ bool MSRSensorGroup::program_fixed(){ ...@@ -151,16 +128,16 @@ bool MSRSensorGroup::program_fixed(){
//we do not want to interrupt other services already doing measurements with MSRs //we do not want to interrupt other services already doing measurements with MSRs
//therefore check if any fixed counter is currently enabled //therefore check if any fixed counter is currently enabled
struct FixedEventControlRegister ctrl_reg; struct FixedEventControlRegister ctrl_reg;
std::bitset<64> cur_reg(ctrl_reg.value);
msr_read(IA32_CR_FIXED_CTR_CTRL, &ctrl_reg.value, kv.first); msr_read(IA32_CR_FIXED_CTR_CTRL, &ctrl_reg.value, kv.first);
//are they all enabled?
if (cur_reg[0] || cur_reg[1] || cur_reg[4] || cur_reg[5] || cur_reg[8] || cur_reg[9]) { if (ctrl_reg.fields.os0 && ctrl_reg.fields.usr0 && ctrl_reg.fields.os1
//at least one is enabled. Do not overwrite them. && ctrl_reg.fields.usr1 && ctrl_reg.fields.os2
//Instead we revert the already programmed counters and return && ctrl_reg.fields.usr2) {
failedCpu = kv.first; //yes! Free running counters were set by someone else => we don't need to program them, just read them.
break; continue;
} }
//not all of them (or none) are enabled => we program them again
// disable counters while programming // disable counters while programming
msr_write(IA32_CR_PERF_GLOBAL_CTRL, 0, kv.first); msr_write(IA32_CR_PERF_GLOBAL_CTRL, 0, kv.first);
...@@ -182,32 +159,14 @@ bool MSRSensorGroup::program_fixed(){ ...@@ -182,32 +159,14 @@ bool MSRSensorGroup::program_fixed(){
ctrl_reg.fields.reserved1 = 0; ctrl_reg.fields.reserved1 = 0;
// program them
msr_write(IA32_CR_FIXED_CTR_CTRL, ctrl_reg.value, kv.first); msr_write(IA32_CR_FIXED_CTR_CTRL, ctrl_reg.value, kv.first);
// start counting, enable 3 fixed counters // start counting, enable 3 fixed counters (enable also the programmables counters)
//uint64 value = (1ULL << 0) + (1ULL << 1) + (1ULL << 2) + (1ULL << 3) + (1ULL << 32) + (1ULL << 33) + (1ULL << 34); uint64 value = (1ULL << 0) + (1ULL << 1) + (1ULL << 2) + (1ULL << 3) + (1ULL << 32) + (1ULL << 33) + (1ULL << 34);
uint64_t value = (1ULL << 32) + (1ULL << 33) + (1ULL << 34); //uint64_t value = (1ULL << 32) + (1ULL << 33) + (1ULL << 34);
msr_write(IA32_CR_PERF_GLOBAL_CTRL, value, kv.first); 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; return true;
} }
......
...@@ -35,7 +35,7 @@ private: ...@@ -35,7 +35,7 @@ private:
void read() override; void read() override;
void readAsync() override; void readAsync() override;
bool program_fixed(); void program_fixed();
std::map<unsigned int,int> cpuToFd; std::map<unsigned int,int> cpuToFd;
int32_t msr_read(uint64_t msr_number, uint64_t * value, unsigned int cpu); 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); int32_t msr_write(uint64_t msr_number, uint64_t value, unsigned int cpu);
......
Supports Markdown
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