blob: 16141f1175228e9d21493cdac75579f62c387e97 [file] [log] [blame]
/*
* SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION &
* AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
#include "NvidiaGpuThresholds.hpp"
#include <MctpRequester.hpp>
#include <NvidiaGpuMctpVdm.hpp>
#include <OcpMctpVdm.hpp>
#include <phosphor-logging/lg2.hpp>
#include <array>
#include <cerrno>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <span>
#include <vector>
void processReadThermalParameterResponse(
const std::function<void(uint8_t, int32_t)>& callback,
const std::span<const uint8_t> respMsg, int sendRecvMsgResult)
{
if (sendRecvMsgResult != 0)
{
lg2::error(
"Error reading thermal parameter: sending message over MCTP failed, rc={RC}",
"RC", sendRecvMsgResult);
callback(EPROTO, 0);
return;
}
ocp::accelerator_management::CompletionCode cc{};
uint16_t reasonCode = 0;
int32_t threshold = 0;
auto rc = gpu::decodeReadThermalParametersResponse(respMsg, cc, reasonCode,
threshold);
if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
{
lg2::error(
"Error reading thermal parameter: decode failed, rc={RC}, cc={CC}, reasonCode={RESC}",
"RC", rc, "CC", cc, "RESC", reasonCode);
callback(EPROTO, 0);
return;
}
callback(0, threshold);
};
void readThermalParameter(uint8_t eid, uint8_t id,
mctp::MctpRequester& mctpRequester,
const std::function<void(uint8_t, int32_t)>& callback)
{
auto reqMsg = std::make_shared<
std::array<uint8_t, sizeof(gpu::ReadThermalParametersRequest)>>();
auto respMsg = std::make_shared<
std::array<uint8_t, sizeof(gpu::ReadThermalParametersResponse)>>();
auto rc = gpu::encodeReadThermalParametersRequest(0, id, *reqMsg);
if (rc != 0)
{
lg2::error(
"Error reading thermal parameter for eid {EID} and parameter id {PID} : encode failed. rc={RC}",
"EID", eid, "PID", id, "RC", rc);
callback(rc, 0);
return;
}
mctpRequester.sendRecvMsg(
eid, *reqMsg, *respMsg,
[reqMsg, respMsg, callback](int sendRecvMsgResult) {
processReadThermalParameterResponse(callback, *respMsg,
sendRecvMsgResult);
});
}
void readThermalParameterCallback(
uint8_t eid, const std::shared_ptr<std::vector<uint8_t>>& ids,
mctp::MctpRequester& mctpRequester,
const std::function<void(uint8_t, std::vector<int32_t>)>& callback,
size_t index, const std::shared_ptr<std::vector<int32_t>>& thresholds,
uint8_t rc, int32_t threshold)
{
if (rc != 0)
{
lg2::error(
"Error reading thermal parameter for eid {EID} and parameter id {PID}. rc={RC}",
"EID", eid, "PID", (*ids)[index], "RC", rc);
callback(rc, *thresholds);
return;
}
thresholds->push_back(threshold);
++index;
if (index == ids->size())
{
callback(rc, *thresholds);
}
else
{
readThermalParameter(eid, (*ids)[index], mctpRequester,
std::bind_front(readThermalParameterCallback, eid,
ids, std::ref(mctpRequester),
callback, index, thresholds));
}
}
void readThermalParameters(
uint8_t eid, const std::vector<uint8_t>& ids,
mctp::MctpRequester& mctpRequester,
const std::function<void(uint8_t, std::vector<int32_t>)>& callback)
{
auto thresholds = std::make_shared<std::vector<int32_t>>();
size_t index = 0;
readThermalParameter(
eid, ids[index], mctpRequester,
std::bind_front(readThermalParameterCallback, eid,
std::make_shared<std::vector<uint8_t>>(ids),
std::ref(mctpRequester), callback, index, thresholds));
}