blob: f6b4bc84bc4469cf1ca9587688c53d8ebdaeff0e [file] [log] [blame]
#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_COLLECTOR_PECI_SCANNER_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_COLLECTOR_PECI_SCANNER_H_
#include <cstddef>
#include <cstdint>
#include <fstream>
#include <memory>
#include <string>
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/functional/any_invocable.h"
#include "absl/synchronization/mutex.h"
#include "absl/types/span.h"
#include "boost/asio.hpp" //NOLINT: boost::asio is commonly used in BMC
#include "fan_controller_config.pb.h"
#include "fan_pwm_config.pb.h"
#include "fan_tach_config.pb.h"
#include "hwmon_temp_sensor_config.pb.h"
#include "intel_cpu_sensor_config.pb.h"
#include "psu_sensor_config.pb.h"
#include "shared_mem_sensor_config.pb.h"
#include "virtual_sensor_config.pb.h"
#include "tlbmc/hal/peci/peci_access_interface.h"
#include "tlbmc/hal/sysfs/peci.h"
#include "sensor.pb.h"
#include "tlbmc/scheduler/scheduler.h"
#include "tlbmc/sensors/intel_cpu_sensor.h"
namespace milotic_tlbmc {
class PeciScanner {
public:
struct PeciScanContext {
int32_t rescan_delay_seconds = 0;
IntelCpuSensor::CpuState cpu_state;
};
static std::unique_ptr<PeciScanner> Create(
absl::Span<const IntelCpuSensorConfig> intel_cpu_sensor_configs,
const PeciSysfs& peci_sysfs, const PeciAccessInterface& peci_access,
TaskScheduler* task_scheduler,
absl::AnyInvocable<void(const std::string&, const std::string&) const>
callback);
void StartScan();
void AttemptPeciDeviceScan(const IntelCpuSensorConfig& config,
size_t scan_context_idx);
void ReschedulePeciDeviceScan(const IntelCpuSensorConfig& config,
size_t scan_context_idx);
PeciScanContext GetPeciScanContext(size_t cpu_index)
ABSL_LOCKS_EXCLUDED(peci_scan_contexts_mutex_) {
absl::MutexLock lock(&peci_scan_contexts_mutex_);
return peci_scan_contexts_[cpu_index];
}
size_t GetPeciScanContextsSize()
ABSL_LOCKS_EXCLUDED(peci_scan_contexts_mutex_) {
absl::MutexLock lock(&peci_scan_contexts_mutex_);
return peci_scan_contexts_.size();
}
protected:
void AddPeciScanContext(PeciScanContext scan_context)
ABSL_LOCKS_EXCLUDED(peci_scan_contexts_mutex_) {
absl::MutexLock lock(&peci_scan_contexts_mutex_);
peci_scan_contexts_.push_back(scan_context);
}
void UpdatePeciScanContext(size_t cpu_index, PeciScanContext scan_context)
ABSL_LOCKS_EXCLUDED(peci_scan_contexts_mutex_) {
absl::MutexLock lock(&peci_scan_contexts_mutex_);
peci_scan_contexts_[cpu_index] = scan_context;
}
private:
PeciScanner(
absl::Span<const IntelCpuSensorConfig> intel_cpu_sensor_configs,
const PeciSysfs& peci_sysfs, const PeciAccessInterface& peci_access,
TaskScheduler* task_scheduler,
absl::AnyInvocable<void(const std::string&, const std::string&) const>
callback);
// Helper functions for simplifying logic within AttemptPeciDeviceScan.
void UpdateCpuStateFromSysfs(const IntelCpuSensorConfig& config,
PeciScanContext& scan_context,
std::fstream& rescan);
bool CheckDimmsReady(const IntelCpuSensorConfig& config);
bool EnsurePeciDeviceExists(const IntelCpuSensorConfig& config);
void UpdateCpuStateFromPeciInterface(const IntelCpuSensorConfig& config,
PeciScanContext& scan_context);
absl::Span<const IntelCpuSensorConfig> intel_cpu_sensor_configs_;
// One PeciScanContext is stored for each CPU. Since PeciScanContext is
// managed separately for each CPU, we store them in a vector.
std::vector<PeciScanContext> peci_scan_contexts_
ABSL_GUARDED_BY(peci_scan_contexts_mutex_);
mutable absl::Mutex peci_scan_contexts_mutex_;
const PeciSysfs& peci_sysfs_;
const PeciAccessInterface& peci_access_;
TaskScheduler* task_scheduler_;
absl::AnyInvocable<void(const std::string&, const std::string&) const>
reinitialize_callback_;
};
} // namespace milotic_tlbmc
#endif // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_COLLECTOR_PECI_SCANNER_H_