xref: /openbmc/dbus-sensors/src/nvidia-gpu/NvidiaGpuSensor.cpp (revision 560e6af7b1f74e9c020a0f82817f9d926e0c4f72)
1d837b56cSHarshit Aghera /*
2d837b56cSHarshit Aghera  * SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION &
3*560e6af7SHarshit Aghera  * AFFILIATES. All rights reserved.
4*560e6af7SHarshit Aghera  * SPDX-License-Identifier: Apache-2.0
5d837b56cSHarshit Aghera  */
6d837b56cSHarshit Aghera 
7d837b56cSHarshit Aghera #include "NvidiaGpuSensor.hpp"
8d837b56cSHarshit Aghera 
9*560e6af7SHarshit Aghera #include "SensorPaths.hpp"
10d837b56cSHarshit Aghera #include "Thresholds.hpp"
11d837b56cSHarshit Aghera #include "Utils.hpp"
12d837b56cSHarshit Aghera #include "sensor.hpp"
13d837b56cSHarshit Aghera 
14d837b56cSHarshit Aghera #include <bits/basic_string.h>
15d837b56cSHarshit Aghera 
16*560e6af7SHarshit Aghera #include <MctpRequester.hpp>
17*560e6af7SHarshit Aghera #include <NvidiaGpuMctpVdm.hpp>
18*560e6af7SHarshit Aghera #include <OcpMctpVdm.hpp>
19d837b56cSHarshit Aghera #include <boost/asio/io_context.hpp>
20d837b56cSHarshit Aghera #include <boost/container/flat_map.hpp>
21d837b56cSHarshit Aghera #include <phosphor-logging/lg2.hpp>
22d837b56cSHarshit Aghera #include <sdbusplus/asio/connection.hpp>
23d837b56cSHarshit Aghera #include <sdbusplus/asio/object_server.hpp>
24d837b56cSHarshit Aghera #include <sdbusplus/message.hpp>
25d837b56cSHarshit Aghera #include <sdbusplus/message/native_types.hpp>
26d837b56cSHarshit Aghera 
27d837b56cSHarshit Aghera #include <algorithm>
28d837b56cSHarshit Aghera #include <chrono>
29d837b56cSHarshit Aghera #include <cstddef>
30d837b56cSHarshit Aghera #include <cstdint>
31*560e6af7SHarshit Aghera #include <functional>
32d837b56cSHarshit Aghera #include <memory>
33d837b56cSHarshit Aghera #include <string>
34d837b56cSHarshit Aghera #include <utility>
35d837b56cSHarshit Aghera #include <variant>
36d837b56cSHarshit Aghera #include <vector>
37d837b56cSHarshit Aghera 
38d837b56cSHarshit Aghera using namespace std::literals;
39d837b56cSHarshit Aghera 
40*560e6af7SHarshit Aghera constexpr uint8_t gpuTempSensorId{0};
41d837b56cSHarshit Aghera static constexpr double gpuTempSensorMaxReading = 127;
42d837b56cSHarshit Aghera static constexpr double gpuTempSensorMinReading = -128;
43d837b56cSHarshit Aghera 
GpuTempSensor(std::shared_ptr<sdbusplus::asio::connection> & conn,boost::asio::io_context & io,mctp::MctpRequester & mctpRequester,const std::string & name,const std::string & sensorConfiguration,sdbusplus::asio::object_server & objectServer,std::vector<thresholds::Threshold> && thresholdData,std::chrono::milliseconds pollRate)44d837b56cSHarshit Aghera GpuTempSensor::GpuTempSensor(
45d837b56cSHarshit Aghera     std::shared_ptr<sdbusplus::asio::connection>& conn,
46*560e6af7SHarshit Aghera     boost::asio::io_context& io, mctp::MctpRequester& mctpRequester,
47*560e6af7SHarshit Aghera     const std::string& name, const std::string& sensorConfiguration,
48d837b56cSHarshit Aghera     sdbusplus::asio::object_server& objectServer,
49*560e6af7SHarshit Aghera     std::vector<thresholds::Threshold>&& thresholdData,
50*560e6af7SHarshit Aghera     std::chrono::milliseconds pollRate) :
51d837b56cSHarshit Aghera     Sensor(escapeName(name), std::move(thresholdData), sensorConfiguration,
52d837b56cSHarshit Aghera            "temperature", false, true, gpuTempSensorMaxReading,
53d837b56cSHarshit Aghera            gpuTempSensorMinReading, conn),
54*560e6af7SHarshit Aghera     sensorId{gpuTempSensorId}, sensorPollMs(pollRate),
55*560e6af7SHarshit Aghera     waitTimer(io, std::chrono::steady_clock::duration(0)),
56*560e6af7SHarshit Aghera     mctpRequester(mctpRequester), conn(conn), objectServer(objectServer)
57d837b56cSHarshit Aghera {
58d837b56cSHarshit Aghera     std::string dbusPath =
59d837b56cSHarshit Aghera         sensorPathPrefix + "temperature/"s + escapeName(name);
60d837b56cSHarshit Aghera 
61d837b56cSHarshit Aghera     sensorInterface = objectServer.add_interface(
62d837b56cSHarshit Aghera         dbusPath, "xyz.openbmc_project.Sensor.Value");
63d837b56cSHarshit Aghera 
64d837b56cSHarshit Aghera     for (const auto& threshold : thresholds)
65d837b56cSHarshit Aghera     {
66d837b56cSHarshit Aghera         std::string interface = thresholds::getInterface(threshold.level);
67d837b56cSHarshit Aghera         thresholdInterfaces[static_cast<size_t>(threshold.level)] =
68d837b56cSHarshit Aghera             objectServer.add_interface(dbusPath, interface);
69d837b56cSHarshit Aghera     }
70d837b56cSHarshit Aghera 
71d837b56cSHarshit Aghera     association = objectServer.add_interface(dbusPath, association::interface);
72d837b56cSHarshit Aghera 
73d837b56cSHarshit Aghera     discoverGpus();
74d837b56cSHarshit Aghera }
75d837b56cSHarshit Aghera 
~GpuTempSensor()76d837b56cSHarshit Aghera GpuTempSensor::~GpuTempSensor()
77d837b56cSHarshit Aghera {
78d837b56cSHarshit Aghera     waitTimer.cancel();
79d837b56cSHarshit Aghera     for (const auto& iface : thresholdInterfaces)
80d837b56cSHarshit Aghera     {
81d837b56cSHarshit Aghera         objectServer.remove_interface(iface);
82d837b56cSHarshit Aghera     }
83d837b56cSHarshit Aghera     objectServer.remove_interface(association);
84d837b56cSHarshit Aghera     objectServer.remove_interface(sensorInterface);
85d837b56cSHarshit Aghera }
86d837b56cSHarshit Aghera 
checkThresholds()87d837b56cSHarshit Aghera void GpuTempSensor::checkThresholds()
88d837b56cSHarshit Aghera {
89d837b56cSHarshit Aghera     thresholds::checkThresholds(this);
90d837b56cSHarshit Aghera }
91d837b56cSHarshit Aghera 
queryEndpoints(const boost::system::error_code & ec,const GetSubTreeType & ret)92d837b56cSHarshit Aghera void GpuTempSensor::queryEndpoints(const boost::system::error_code& ec,
93d837b56cSHarshit Aghera                                    const GetSubTreeType& ret)
94d837b56cSHarshit Aghera {
95d837b56cSHarshit Aghera     if (ec)
96d837b56cSHarshit Aghera     {
97d837b56cSHarshit Aghera         lg2::error("Error querying endoints :{ERROR}", "ERROR", ec.message());
98d837b56cSHarshit Aghera         return;
99d837b56cSHarshit Aghera     }
100d837b56cSHarshit Aghera 
101d837b56cSHarshit Aghera     if (ret.empty())
102d837b56cSHarshit Aghera     {
103d837b56cSHarshit Aghera         return;
104d837b56cSHarshit Aghera     }
105d837b56cSHarshit Aghera 
106d837b56cSHarshit Aghera     for (const auto& [objPath, services] : ret)
107d837b56cSHarshit Aghera     {
108d837b56cSHarshit Aghera         for (const auto& [service, ifaces] : services)
109d837b56cSHarshit Aghera         {
110d837b56cSHarshit Aghera             for (const auto& iface : ifaces)
111d837b56cSHarshit Aghera             {
112d837b56cSHarshit Aghera                 if (iface == "xyz.openbmc_project.MCTP.Endpoint")
113d837b56cSHarshit Aghera                 {
114d837b56cSHarshit Aghera                     conn->async_method_call(
115d837b56cSHarshit Aghera                         [this](const boost::system::error_code& ec,
116d837b56cSHarshit Aghera                                const SensorBaseConfigMap& configs) {
117d837b56cSHarshit Aghera                             this->processEndpoint(ec, configs);
118d837b56cSHarshit Aghera                         },
119d837b56cSHarshit Aghera                         service, objPath, "org.freedesktop.DBus.Properties",
120d837b56cSHarshit Aghera                         "GetAll", iface);
121d837b56cSHarshit Aghera                 }
122d837b56cSHarshit Aghera             }
123d837b56cSHarshit Aghera         }
124d837b56cSHarshit Aghera     }
125d837b56cSHarshit Aghera }
126d837b56cSHarshit Aghera 
read()127*560e6af7SHarshit Aghera void GpuTempSensor::read()
128*560e6af7SHarshit Aghera {
129*560e6af7SHarshit Aghera     update();
130*560e6af7SHarshit Aghera 
131*560e6af7SHarshit Aghera     waitTimer.expires_after(std::chrono::milliseconds(sensorPollMs));
132*560e6af7SHarshit Aghera     waitTimer.async_wait(
133*560e6af7SHarshit Aghera         [weakPtrToThis = std::weak_ptr<GpuTempSensor>{shared_from_this()}](
134*560e6af7SHarshit Aghera             const boost::system::error_code& ec) {
135*560e6af7SHarshit Aghera             if (ec)
136*560e6af7SHarshit Aghera             {
137*560e6af7SHarshit Aghera                 return;
138*560e6af7SHarshit Aghera             }
139*560e6af7SHarshit Aghera             if (auto ptr = weakPtrToThis.lock())
140*560e6af7SHarshit Aghera             {
141*560e6af7SHarshit Aghera                 ptr->read();
142*560e6af7SHarshit Aghera             }
143*560e6af7SHarshit Aghera         });
144*560e6af7SHarshit Aghera }
145*560e6af7SHarshit Aghera 
processResponse(int sendRecvMsgResult)146*560e6af7SHarshit Aghera void GpuTempSensor::processResponse(int sendRecvMsgResult)
147*560e6af7SHarshit Aghera {
148*560e6af7SHarshit Aghera     if (sendRecvMsgResult != 0)
149*560e6af7SHarshit Aghera     {
150*560e6af7SHarshit Aghera         lg2::error(
151*560e6af7SHarshit Aghera             "Error updating Temperature Sensor: sending message over MCTP failed, rc={RC}",
152*560e6af7SHarshit Aghera             "RC", sendRecvMsgResult);
153*560e6af7SHarshit Aghera         return;
154*560e6af7SHarshit Aghera     }
155*560e6af7SHarshit Aghera 
156*560e6af7SHarshit Aghera     ocp::accelerator_management::CompletionCode cc{};
157*560e6af7SHarshit Aghera     uint16_t reasonCode = 0;
158*560e6af7SHarshit Aghera     double tempValue = 0;
159*560e6af7SHarshit Aghera 
160*560e6af7SHarshit Aghera     auto rc = gpu::decodeGetTemperatureReadingResponse(
161*560e6af7SHarshit Aghera         getTemperatureReadingResponse, cc, reasonCode, tempValue);
162*560e6af7SHarshit Aghera 
163*560e6af7SHarshit Aghera     if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
164*560e6af7SHarshit Aghera     {
165*560e6af7SHarshit Aghera         lg2::error(
166*560e6af7SHarshit Aghera             "Error updating Temperature Sensor: decode failed, rc={RC}, cc={CC}, reasonCode={RESC}",
167*560e6af7SHarshit Aghera             "RC", rc, "CC", cc, "RESC", reasonCode);
168*560e6af7SHarshit Aghera         return;
169*560e6af7SHarshit Aghera     }
170*560e6af7SHarshit Aghera 
171*560e6af7SHarshit Aghera     updateValue(tempValue);
172*560e6af7SHarshit Aghera }
173*560e6af7SHarshit Aghera 
update()174*560e6af7SHarshit Aghera void GpuTempSensor::update()
175*560e6af7SHarshit Aghera {
176*560e6af7SHarshit Aghera     auto rc = gpu::encodeGetTemperatureReadingRequest(
177*560e6af7SHarshit Aghera         0, sensorId, getTemperatureReadingRequest);
178*560e6af7SHarshit Aghera     if (rc != 0)
179*560e6af7SHarshit Aghera     {
180*560e6af7SHarshit Aghera         lg2::error("Error updating Temperature Sensor: encode failed, rc={RC}",
181*560e6af7SHarshit Aghera                    "RC", rc);
182*560e6af7SHarshit Aghera         return;
183*560e6af7SHarshit Aghera     }
184*560e6af7SHarshit Aghera 
185*560e6af7SHarshit Aghera     mctpRequester.sendRecvMsg(
186*560e6af7SHarshit Aghera         eid, getTemperatureReadingRequest, getTemperatureReadingResponse,
187*560e6af7SHarshit Aghera         [this](int sendRecvMsgResult) { processResponse(sendRecvMsgResult); });
188*560e6af7SHarshit Aghera }
189*560e6af7SHarshit Aghera 
processQueryDeviceIdResponse(uint8_t eid,int sendRecvMsgResult)190*560e6af7SHarshit Aghera void GpuTempSensor::processQueryDeviceIdResponse(uint8_t eid,
191*560e6af7SHarshit Aghera                                                  int sendRecvMsgResult)
192*560e6af7SHarshit Aghera {
193*560e6af7SHarshit Aghera     if (sendRecvMsgResult != 0)
194*560e6af7SHarshit Aghera     {
195*560e6af7SHarshit Aghera         lg2::error(
196*560e6af7SHarshit Aghera             "Error processing GPU endpoint: sending message over MCTP failed, rc={RC}",
197*560e6af7SHarshit Aghera             "RC", sendRecvMsgResult);
198*560e6af7SHarshit Aghera         return;
199*560e6af7SHarshit Aghera     }
200*560e6af7SHarshit Aghera 
201*560e6af7SHarshit Aghera     ocp::accelerator_management::CompletionCode cc{};
202*560e6af7SHarshit Aghera     uint16_t reasonCode = 0;
203*560e6af7SHarshit Aghera     uint8_t responseDeviceType = 0;
204*560e6af7SHarshit Aghera     uint8_t responseInstanceId = 0;
205*560e6af7SHarshit Aghera 
206*560e6af7SHarshit Aghera     auto rc = gpu::decodeQueryDeviceIdentificationResponse(
207*560e6af7SHarshit Aghera         queryDeviceIdentificationResponse, cc, reasonCode, responseDeviceType,
208*560e6af7SHarshit Aghera         responseInstanceId);
209*560e6af7SHarshit Aghera 
210*560e6af7SHarshit Aghera     if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
211*560e6af7SHarshit Aghera     {
212*560e6af7SHarshit Aghera         lg2::error(
213*560e6af7SHarshit Aghera             "Error processing GPU endpoint: decode failed, rc={RC}, cc={CC}, reasonCode={RESC}",
214*560e6af7SHarshit Aghera             "RC", rc, "CC", cc, "RESC", reasonCode);
215*560e6af7SHarshit Aghera         return;
216*560e6af7SHarshit Aghera     }
217*560e6af7SHarshit Aghera 
218*560e6af7SHarshit Aghera     if (responseDeviceType ==
219*560e6af7SHarshit Aghera         static_cast<uint8_t>(gpu::DeviceIdentification::DEVICE_GPU))
220*560e6af7SHarshit Aghera     {
221*560e6af7SHarshit Aghera         lg2::info(
222*560e6af7SHarshit Aghera             "Found the GPU with EID {EID}, DeviceType {DEVTYPE}, InstanceId {IID}.",
223*560e6af7SHarshit Aghera             "EID", eid, "DEVTYPE", responseDeviceType, "IID",
224*560e6af7SHarshit Aghera             responseInstanceId);
225*560e6af7SHarshit Aghera 
226*560e6af7SHarshit Aghera         this->eid = eid;
227*560e6af7SHarshit Aghera         setInitialProperties(sensor_paths::unitDegreesC);
228*560e6af7SHarshit Aghera         read();
229*560e6af7SHarshit Aghera     }
230*560e6af7SHarshit Aghera }
231*560e6af7SHarshit Aghera 
processGpuEndpoint(uint8_t eid)232*560e6af7SHarshit Aghera void GpuTempSensor::processGpuEndpoint(uint8_t eid)
233*560e6af7SHarshit Aghera {
234*560e6af7SHarshit Aghera     auto rc = gpu::encodeQueryDeviceIdentificationRequest(
235*560e6af7SHarshit Aghera         0, queryDeviceIdentificationRequest);
236*560e6af7SHarshit Aghera     if (rc != 0)
237*560e6af7SHarshit Aghera     {
238*560e6af7SHarshit Aghera         lg2::error("Error processing GPU endpoint: encode failed, rc={RC}",
239*560e6af7SHarshit Aghera                    "RC", rc);
240*560e6af7SHarshit Aghera         return;
241*560e6af7SHarshit Aghera     }
242*560e6af7SHarshit Aghera 
243*560e6af7SHarshit Aghera     mctpRequester.sendRecvMsg(
244*560e6af7SHarshit Aghera         eid, queryDeviceIdentificationRequest,
245*560e6af7SHarshit Aghera         queryDeviceIdentificationResponse, [this, eid](int sendRecvMsgResult) {
246*560e6af7SHarshit Aghera             processQueryDeviceIdResponse(eid, sendRecvMsgResult);
247*560e6af7SHarshit Aghera         });
248*560e6af7SHarshit Aghera }
249*560e6af7SHarshit Aghera 
processEndpoint(const boost::system::error_code & ec,const SensorBaseConfigMap & endpoint)250d837b56cSHarshit Aghera void GpuTempSensor::processEndpoint(const boost::system::error_code& ec,
251d837b56cSHarshit Aghera                                     const SensorBaseConfigMap& endpoint)
252d837b56cSHarshit Aghera {
253d837b56cSHarshit Aghera     if (ec)
254d837b56cSHarshit Aghera     {
255d837b56cSHarshit Aghera         lg2::error("Error processing MCTP endpoint: {ERROR}", "ERROR",
256d837b56cSHarshit Aghera                    ec.message());
257d837b56cSHarshit Aghera         return;
258d837b56cSHarshit Aghera     }
259d837b56cSHarshit Aghera 
260*560e6af7SHarshit Aghera     uint8_t eid{};
261d837b56cSHarshit Aghera     std::vector<uint8_t> mctpTypes{};
262d837b56cSHarshit Aghera 
263d837b56cSHarshit Aghera     auto hasEid = endpoint.find("EID");
264d837b56cSHarshit Aghera     if (hasEid != endpoint.end())
265d837b56cSHarshit Aghera     {
266d837b56cSHarshit Aghera         const auto* eidPtr = std::get_if<uint8_t>(&hasEid->second);
267d837b56cSHarshit Aghera         if (eidPtr != nullptr)
268d837b56cSHarshit Aghera         {
269d837b56cSHarshit Aghera             eid = *eidPtr;
270d837b56cSHarshit Aghera         }
271d837b56cSHarshit Aghera         else
272d837b56cSHarshit Aghera         {
273d837b56cSHarshit Aghera             lg2::error(
274d837b56cSHarshit Aghera                 "Error processing MCTP endpoint: Property EID does not have valid type.");
275d837b56cSHarshit Aghera             return;
276d837b56cSHarshit Aghera         }
277d837b56cSHarshit Aghera     }
278d837b56cSHarshit Aghera     else
279d837b56cSHarshit Aghera     {
280d837b56cSHarshit Aghera         lg2::error(
281d837b56cSHarshit Aghera             "Error processing MCTP endpoint: Property EID not found in the configuration.");
282d837b56cSHarshit Aghera         return;
283d837b56cSHarshit Aghera     }
284d837b56cSHarshit Aghera 
285d837b56cSHarshit Aghera     auto hasMctpTypes = endpoint.find("SupportedMessageTypes");
286d837b56cSHarshit Aghera     if (hasMctpTypes != endpoint.end())
287d837b56cSHarshit Aghera     {
288d837b56cSHarshit Aghera         const auto* mctpTypePtr =
289d837b56cSHarshit Aghera             std::get_if<std::vector<uint8_t>>(&hasMctpTypes->second);
290d837b56cSHarshit Aghera         if (mctpTypePtr != nullptr)
291d837b56cSHarshit Aghera         {
292d837b56cSHarshit Aghera             mctpTypes = *mctpTypePtr;
293d837b56cSHarshit Aghera         }
294d837b56cSHarshit Aghera         else
295d837b56cSHarshit Aghera         {
296d837b56cSHarshit Aghera             lg2::error(
297d837b56cSHarshit Aghera                 "Error processing MCTP endpoint: Property SupportedMessageTypes does not have valid type.");
298d837b56cSHarshit Aghera             return;
299d837b56cSHarshit Aghera         }
300d837b56cSHarshit Aghera     }
301d837b56cSHarshit Aghera     else
302d837b56cSHarshit Aghera     {
303d837b56cSHarshit Aghera         lg2::error(
304d837b56cSHarshit Aghera             "Error processing MCTP endpoint: Property SupportedMessageTypes not found in the configuration.");
305d837b56cSHarshit Aghera         return;
306d837b56cSHarshit Aghera     }
307d837b56cSHarshit Aghera 
308*560e6af7SHarshit Aghera     if (std::find(mctpTypes.begin(), mctpTypes.end(),
309*560e6af7SHarshit Aghera                   ocp::accelerator_management::messageType) != mctpTypes.end())
310*560e6af7SHarshit Aghera     {
311*560e6af7SHarshit Aghera         lg2::info(
312*560e6af7SHarshit Aghera             "GpuTempSensor::discoverGpus(): Found OCP MCTP VDM Endpoint with ID {EID}",
313*560e6af7SHarshit Aghera             "EID", eid);
314*560e6af7SHarshit Aghera         this->processGpuEndpoint(eid);
315*560e6af7SHarshit Aghera     }
316d837b56cSHarshit Aghera }
317d837b56cSHarshit Aghera 
discoverGpus()318d837b56cSHarshit Aghera void GpuTempSensor::discoverGpus()
319d837b56cSHarshit Aghera {
320d837b56cSHarshit Aghera     std::string searchPath{"/au/com/codeconstruct/"};
321d837b56cSHarshit Aghera     std::vector<std::string> ifaceList{{"xyz.openbmc_project.MCTP.Endpoint"}};
322d837b56cSHarshit Aghera 
323d837b56cSHarshit Aghera     conn->async_method_call(
324d837b56cSHarshit Aghera         [this](const boost::system::error_code& ec, const GetSubTreeType& ret) {
325d837b56cSHarshit Aghera             queryEndpoints(ec, ret);
326d837b56cSHarshit Aghera         },
327d837b56cSHarshit Aghera         "xyz.openbmc_project.ObjectMapper",
328d837b56cSHarshit Aghera         "/xyz/openbmc_project/object_mapper",
329d837b56cSHarshit Aghera         "xyz.openbmc_project.ObjectMapper", "GetSubTree", searchPath, 0,
330d837b56cSHarshit Aghera         ifaceList);
331d837b56cSHarshit Aghera }
332d837b56cSHarshit Aghera 
processSensorConfigs(boost::asio::io_context & io,sdbusplus::asio::object_server & objectServer,boost::container::flat_map<std::string,std::shared_ptr<GpuTempSensor>> & sensors,std::shared_ptr<sdbusplus::asio::connection> & dbusConnection,mctp::MctpRequester & mctpRequester,const ManagedObjectType & resp)333d837b56cSHarshit Aghera void processSensorConfigs(
334d837b56cSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
335d837b56cSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuTempSensor>>&
336d837b56cSHarshit Aghera         sensors,
337d837b56cSHarshit Aghera     std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
338*560e6af7SHarshit Aghera     mctp::MctpRequester& mctpRequester, const ManagedObjectType& resp)
339d837b56cSHarshit Aghera {
340d837b56cSHarshit Aghera     for (const auto& [path, interfaces] : resp)
341d837b56cSHarshit Aghera     {
342d837b56cSHarshit Aghera         for (const auto& [intf, cfg] : interfaces)
343d837b56cSHarshit Aghera         {
344d837b56cSHarshit Aghera             if (intf != configInterfaceName(sensorType))
345d837b56cSHarshit Aghera             {
346d837b56cSHarshit Aghera                 continue;
347d837b56cSHarshit Aghera             }
348d837b56cSHarshit Aghera 
349d837b56cSHarshit Aghera             std::string name = loadVariant<std::string>(cfg, "Name");
350d837b56cSHarshit Aghera 
351*560e6af7SHarshit Aghera             uint64_t pollRate = loadVariant<uint64_t>(cfg, "PollRate");
352*560e6af7SHarshit Aghera 
353d837b56cSHarshit Aghera             sensors[name] = std::make_shared<GpuTempSensor>(
354*560e6af7SHarshit Aghera                 dbusConnection, io, mctpRequester, name, path, objectServer,
355*560e6af7SHarshit Aghera                 std::vector<thresholds::Threshold>{},
356*560e6af7SHarshit Aghera                 std::chrono::milliseconds{pollRate});
357d837b56cSHarshit Aghera 
358d837b56cSHarshit Aghera             lg2::info(
359d837b56cSHarshit Aghera                 "Added GPU Temperature Sensor {NAME} with chassis path: {PATH}.",
360d837b56cSHarshit Aghera                 "NAME", name, "PATH", path);
361d837b56cSHarshit Aghera         }
362d837b56cSHarshit Aghera     }
363d837b56cSHarshit Aghera }
364d837b56cSHarshit Aghera 
createSensors(boost::asio::io_context & io,sdbusplus::asio::object_server & objectServer,boost::container::flat_map<std::string,std::shared_ptr<GpuTempSensor>> & sensors,std::shared_ptr<sdbusplus::asio::connection> & dbusConnection,mctp::MctpRequester & mctpRequester)365d837b56cSHarshit Aghera void createSensors(
366d837b56cSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
367d837b56cSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuTempSensor>>&
368d837b56cSHarshit Aghera         sensors,
369*560e6af7SHarshit Aghera     std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
370*560e6af7SHarshit Aghera     mctp::MctpRequester& mctpRequester)
371d837b56cSHarshit Aghera {
372d837b56cSHarshit Aghera     if (!dbusConnection)
373d837b56cSHarshit Aghera     {
374d837b56cSHarshit Aghera         lg2::error("Connection not created");
375d837b56cSHarshit Aghera         return;
376d837b56cSHarshit Aghera     }
377d837b56cSHarshit Aghera     dbusConnection->async_method_call(
378*560e6af7SHarshit Aghera         [&sensors, &mctpRequester, &dbusConnection, &io,
379d837b56cSHarshit Aghera          &objectServer](const boost::system::error_code& ec,
380d837b56cSHarshit Aghera                         const ManagedObjectType& resp) {
381d837b56cSHarshit Aghera             if (ec)
382d837b56cSHarshit Aghera             {
383d837b56cSHarshit Aghera                 lg2::error("Error contacting entity manager");
384d837b56cSHarshit Aghera                 return;
385d837b56cSHarshit Aghera             }
386d837b56cSHarshit Aghera 
387d837b56cSHarshit Aghera             processSensorConfigs(io, objectServer, sensors, dbusConnection,
388*560e6af7SHarshit Aghera                                  mctpRequester, resp);
389d837b56cSHarshit Aghera         },
390d837b56cSHarshit Aghera         entityManagerName, "/xyz/openbmc_project/inventory",
391d837b56cSHarshit Aghera         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
392d837b56cSHarshit Aghera }
393d837b56cSHarshit Aghera 
interfaceRemoved(sdbusplus::message_t & message,boost::container::flat_map<std::string,std::shared_ptr<GpuTempSensor>> & sensors)394d837b56cSHarshit Aghera void interfaceRemoved(
395d837b56cSHarshit Aghera     sdbusplus::message_t& message,
396d837b56cSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuTempSensor>>&
397d837b56cSHarshit Aghera         sensors)
398d837b56cSHarshit Aghera {
399d837b56cSHarshit Aghera     if (message.is_method_error())
400d837b56cSHarshit Aghera     {
401d837b56cSHarshit Aghera         lg2::error("interfacesRemoved callback method error");
402d837b56cSHarshit Aghera         return;
403d837b56cSHarshit Aghera     }
404d837b56cSHarshit Aghera 
405d837b56cSHarshit Aghera     sdbusplus::message::object_path removedPath;
406d837b56cSHarshit Aghera     std::vector<std::string> interfaces;
407d837b56cSHarshit Aghera 
408d837b56cSHarshit Aghera     message.read(removedPath, interfaces);
409d837b56cSHarshit Aghera 
410d837b56cSHarshit Aghera     // If the xyz.openbmc_project.Confguration.X interface was removed
411d837b56cSHarshit Aghera     // for one or more sensors, delete those sensor objects.
412d837b56cSHarshit Aghera     auto sensorIt = sensors.begin();
413d837b56cSHarshit Aghera     while (sensorIt != sensors.end())
414d837b56cSHarshit Aghera     {
415d837b56cSHarshit Aghera         if ((sensorIt->second->configurationPath == removedPath) &&
416d837b56cSHarshit Aghera             (std::find(interfaces.begin(), interfaces.end(),
417d837b56cSHarshit Aghera                        configInterfaceName(sensorType)) != interfaces.end()))
418d837b56cSHarshit Aghera         {
419d837b56cSHarshit Aghera             sensorIt = sensors.erase(sensorIt);
420d837b56cSHarshit Aghera         }
421d837b56cSHarshit Aghera         else
422d837b56cSHarshit Aghera         {
423d837b56cSHarshit Aghera             sensorIt++;
424d837b56cSHarshit Aghera         }
425d837b56cSHarshit Aghera     }
426d837b56cSHarshit Aghera }
427