xref: /openbmc/dbus-sensors/src/nvidia-gpu/NvidiaDeviceDiscovery.cpp (revision 4ecdfaaaf39039bd6d73ee67aa44830672675a81)
1*4ecdfaaaSHarshit Aghera /*
2*4ecdfaaaSHarshit Aghera  * SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION &
3*4ecdfaaaSHarshit Aghera  * AFFILIATES. All rights reserved.
4*4ecdfaaaSHarshit Aghera  * SPDX-License-Identifier: Apache-2.0
5*4ecdfaaaSHarshit Aghera  */
6*4ecdfaaaSHarshit Aghera 
7*4ecdfaaaSHarshit Aghera #include "NvidiaDeviceDiscovery.hpp"
8*4ecdfaaaSHarshit Aghera 
9*4ecdfaaaSHarshit Aghera #include "NvidiaGpuDevice.hpp"
10*4ecdfaaaSHarshit Aghera #include "Utils.hpp"
11*4ecdfaaaSHarshit Aghera 
12*4ecdfaaaSHarshit Aghera #include <bits/basic_string.h>
13*4ecdfaaaSHarshit Aghera 
14*4ecdfaaaSHarshit Aghera #include <MctpRequester.hpp>
15*4ecdfaaaSHarshit Aghera #include <NvidiaGpuMctpVdm.hpp>
16*4ecdfaaaSHarshit Aghera #include <OcpMctpVdm.hpp>
17*4ecdfaaaSHarshit Aghera #include <boost/asio/io_context.hpp>
18*4ecdfaaaSHarshit Aghera #include <boost/container/flat_map.hpp>
19*4ecdfaaaSHarshit Aghera #include <phosphor-logging/lg2.hpp>
20*4ecdfaaaSHarshit Aghera #include <sdbusplus/asio/connection.hpp>
21*4ecdfaaaSHarshit Aghera #include <sdbusplus/asio/object_server.hpp>
22*4ecdfaaaSHarshit Aghera #include <sdbusplus/message.hpp>
23*4ecdfaaaSHarshit Aghera #include <sdbusplus/message/native_types.hpp>
24*4ecdfaaaSHarshit Aghera 
25*4ecdfaaaSHarshit Aghera #include <algorithm>
26*4ecdfaaaSHarshit Aghera #include <array>
27*4ecdfaaaSHarshit Aghera #include <cstdint>
28*4ecdfaaaSHarshit Aghera #include <memory>
29*4ecdfaaaSHarshit Aghera #include <span>
30*4ecdfaaaSHarshit Aghera #include <string>
31*4ecdfaaaSHarshit Aghera #include <utility>
32*4ecdfaaaSHarshit Aghera #include <variant>
33*4ecdfaaaSHarshit Aghera #include <vector>
34*4ecdfaaaSHarshit Aghera 
35*4ecdfaaaSHarshit Aghera void processQueryDeviceIdResponse(
36*4ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
37*4ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
38*4ecdfaaaSHarshit Aghera         gpuDevices,
39*4ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& conn,
40*4ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester, const SensorConfigs& configs,
41*4ecdfaaaSHarshit Aghera     const std::string& path, uint8_t eid, int sendRecvMsgResult,
42*4ecdfaaaSHarshit Aghera     std::span<uint8_t> queryDeviceIdentificationResponse)
43*4ecdfaaaSHarshit Aghera {
44*4ecdfaaaSHarshit Aghera     if (sendRecvMsgResult != 0)
45*4ecdfaaaSHarshit Aghera     {
46*4ecdfaaaSHarshit Aghera         lg2::error(
47*4ecdfaaaSHarshit Aghera             "Error processing MCTP endpoint with eid {EID} : sending message over MCTP failed, rc={RC}",
48*4ecdfaaaSHarshit Aghera             "EID", eid, "RC", sendRecvMsgResult);
49*4ecdfaaaSHarshit Aghera         return;
50*4ecdfaaaSHarshit Aghera     }
51*4ecdfaaaSHarshit Aghera 
52*4ecdfaaaSHarshit Aghera     ocp::accelerator_management::CompletionCode cc{};
53*4ecdfaaaSHarshit Aghera     uint16_t reasonCode = 0;
54*4ecdfaaaSHarshit Aghera     uint8_t responseDeviceType = 0;
55*4ecdfaaaSHarshit Aghera     uint8_t responseInstanceId = 0;
56*4ecdfaaaSHarshit Aghera 
57*4ecdfaaaSHarshit Aghera     auto rc = gpu::decodeQueryDeviceIdentificationResponse(
58*4ecdfaaaSHarshit Aghera         queryDeviceIdentificationResponse, cc, reasonCode, responseDeviceType,
59*4ecdfaaaSHarshit Aghera         responseInstanceId);
60*4ecdfaaaSHarshit Aghera 
61*4ecdfaaaSHarshit Aghera     if (rc != 0 || cc != ocp::accelerator_management::CompletionCode::SUCCESS)
62*4ecdfaaaSHarshit Aghera     {
63*4ecdfaaaSHarshit Aghera         lg2::error(
64*4ecdfaaaSHarshit Aghera             "Error processing MCTP endpoint with eid {EID} : decode failed, rc={RC}, cc={CC}, reasonCode={RESC}",
65*4ecdfaaaSHarshit Aghera             "EID", eid, "RC", rc, "CC", cc, "RESC", reasonCode);
66*4ecdfaaaSHarshit Aghera         return;
67*4ecdfaaaSHarshit Aghera     }
68*4ecdfaaaSHarshit Aghera 
69*4ecdfaaaSHarshit Aghera     if (responseDeviceType ==
70*4ecdfaaaSHarshit Aghera         static_cast<uint8_t>(gpu::DeviceIdentification::DEVICE_GPU))
71*4ecdfaaaSHarshit Aghera     {
72*4ecdfaaaSHarshit Aghera         lg2::info(
73*4ecdfaaaSHarshit Aghera             "Found the GPU with EID {EID}, DeviceType {DEVTYPE}, InstanceId {IID}.",
74*4ecdfaaaSHarshit Aghera             "EID", eid, "DEVTYPE", responseDeviceType, "IID",
75*4ecdfaaaSHarshit Aghera             responseInstanceId);
76*4ecdfaaaSHarshit Aghera 
77*4ecdfaaaSHarshit Aghera         auto gpuName = configs.name + '_' + std::to_string(responseInstanceId);
78*4ecdfaaaSHarshit Aghera 
79*4ecdfaaaSHarshit Aghera         gpuDevices[gpuName] = std::make_shared<GpuDevice>(
80*4ecdfaaaSHarshit Aghera             configs, gpuName, path, conn, eid, io, mctpRequester, objectServer);
81*4ecdfaaaSHarshit Aghera     }
82*4ecdfaaaSHarshit Aghera }
83*4ecdfaaaSHarshit Aghera 
84*4ecdfaaaSHarshit Aghera void queryDeviceIdentification(
85*4ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
86*4ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
87*4ecdfaaaSHarshit Aghera         gpuDevices,
88*4ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& conn,
89*4ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester, const SensorConfigs& configs,
90*4ecdfaaaSHarshit Aghera     const std::string& path, uint8_t eid)
91*4ecdfaaaSHarshit Aghera {
92*4ecdfaaaSHarshit Aghera     auto queryDeviceIdentificationRequest = std::make_shared<
93*4ecdfaaaSHarshit Aghera         std::array<uint8_t, sizeof(gpu::QueryDeviceIdentificationRequest)>>();
94*4ecdfaaaSHarshit Aghera 
95*4ecdfaaaSHarshit Aghera     auto queryDeviceIdentificationResponse = std::make_shared<
96*4ecdfaaaSHarshit Aghera         std::array<uint8_t, sizeof(gpu::QueryDeviceIdentificationResponse)>>();
97*4ecdfaaaSHarshit Aghera 
98*4ecdfaaaSHarshit Aghera     auto rc = gpu::encodeQueryDeviceIdentificationRequest(
99*4ecdfaaaSHarshit Aghera         0, *queryDeviceIdentificationRequest);
100*4ecdfaaaSHarshit Aghera     if (rc != 0)
101*4ecdfaaaSHarshit Aghera     {
102*4ecdfaaaSHarshit Aghera         lg2::error(
103*4ecdfaaaSHarshit Aghera             "Error processing MCTP endpoint with eid {EID} : encode failed, rc={RC}",
104*4ecdfaaaSHarshit Aghera             "EID", eid, "RC", rc);
105*4ecdfaaaSHarshit Aghera         return;
106*4ecdfaaaSHarshit Aghera     }
107*4ecdfaaaSHarshit Aghera 
108*4ecdfaaaSHarshit Aghera     mctpRequester.sendRecvMsg(
109*4ecdfaaaSHarshit Aghera         eid, *queryDeviceIdentificationRequest,
110*4ecdfaaaSHarshit Aghera         *queryDeviceIdentificationResponse,
111*4ecdfaaaSHarshit Aghera         [&io, &objectServer, &gpuDevices, conn, &mctpRequester, configs, path,
112*4ecdfaaaSHarshit Aghera          eid, queryDeviceIdentificationRequest,
113*4ecdfaaaSHarshit Aghera          queryDeviceIdentificationResponse](int sendRecvMsgResult) {
114*4ecdfaaaSHarshit Aghera             processQueryDeviceIdResponse(
115*4ecdfaaaSHarshit Aghera                 io, objectServer, gpuDevices, conn, mctpRequester, configs,
116*4ecdfaaaSHarshit Aghera                 path, eid, sendRecvMsgResult,
117*4ecdfaaaSHarshit Aghera                 *queryDeviceIdentificationResponse);
118*4ecdfaaaSHarshit Aghera         });
119*4ecdfaaaSHarshit Aghera }
120*4ecdfaaaSHarshit Aghera 
121*4ecdfaaaSHarshit Aghera void processEndpoint(
122*4ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
123*4ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
124*4ecdfaaaSHarshit Aghera         gpuDevices,
125*4ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& conn,
126*4ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester, const SensorConfigs& configs,
127*4ecdfaaaSHarshit Aghera     const std::string& path, const boost::system::error_code& ec,
128*4ecdfaaaSHarshit Aghera     const SensorBaseConfigMap& endpoint)
129*4ecdfaaaSHarshit Aghera {
130*4ecdfaaaSHarshit Aghera     if (ec)
131*4ecdfaaaSHarshit Aghera     {
132*4ecdfaaaSHarshit Aghera         lg2::error("Error processing MCTP endpoint: Error:{ERROR}", "ERROR",
133*4ecdfaaaSHarshit Aghera                    ec.message());
134*4ecdfaaaSHarshit Aghera         return;
135*4ecdfaaaSHarshit Aghera     }
136*4ecdfaaaSHarshit Aghera 
137*4ecdfaaaSHarshit Aghera     auto hasEid = endpoint.find("EID");
138*4ecdfaaaSHarshit Aghera     uint8_t eid{};
139*4ecdfaaaSHarshit Aghera 
140*4ecdfaaaSHarshit Aghera     if (hasEid != endpoint.end())
141*4ecdfaaaSHarshit Aghera     {
142*4ecdfaaaSHarshit Aghera         const auto* eidPtr = std::get_if<uint8_t>(&hasEid->second);
143*4ecdfaaaSHarshit Aghera         if (eidPtr != nullptr)
144*4ecdfaaaSHarshit Aghera         {
145*4ecdfaaaSHarshit Aghera             eid = *eidPtr;
146*4ecdfaaaSHarshit Aghera         }
147*4ecdfaaaSHarshit Aghera         else
148*4ecdfaaaSHarshit Aghera         {
149*4ecdfaaaSHarshit Aghera             lg2::error(
150*4ecdfaaaSHarshit Aghera                 "Error processing MCTP endpoint: Property EID does not have valid type.");
151*4ecdfaaaSHarshit Aghera             return;
152*4ecdfaaaSHarshit Aghera         }
153*4ecdfaaaSHarshit Aghera     }
154*4ecdfaaaSHarshit Aghera     else
155*4ecdfaaaSHarshit Aghera     {
156*4ecdfaaaSHarshit Aghera         lg2::error(
157*4ecdfaaaSHarshit Aghera             "Error processing MCTP endpoint: Property EID not found in the configuration.");
158*4ecdfaaaSHarshit Aghera         return;
159*4ecdfaaaSHarshit Aghera     }
160*4ecdfaaaSHarshit Aghera 
161*4ecdfaaaSHarshit Aghera     auto hasMctpTypes = endpoint.find("SupportedMessageTypes");
162*4ecdfaaaSHarshit Aghera     std::vector<uint8_t> mctpTypes{};
163*4ecdfaaaSHarshit Aghera 
164*4ecdfaaaSHarshit Aghera     if (hasMctpTypes != endpoint.end())
165*4ecdfaaaSHarshit Aghera     {
166*4ecdfaaaSHarshit Aghera         const auto* mctpTypePtr =
167*4ecdfaaaSHarshit Aghera             std::get_if<std::vector<uint8_t>>(&hasMctpTypes->second);
168*4ecdfaaaSHarshit Aghera         if (mctpTypePtr != nullptr)
169*4ecdfaaaSHarshit Aghera         {
170*4ecdfaaaSHarshit Aghera             mctpTypes = *mctpTypePtr;
171*4ecdfaaaSHarshit Aghera         }
172*4ecdfaaaSHarshit Aghera         else
173*4ecdfaaaSHarshit Aghera         {
174*4ecdfaaaSHarshit Aghera             lg2::error(
175*4ecdfaaaSHarshit Aghera                 "Error processing MCTP endpoint with eid {EID} : Property SupportedMessageTypes does not have valid type.",
176*4ecdfaaaSHarshit Aghera                 "EID", eid);
177*4ecdfaaaSHarshit Aghera             return;
178*4ecdfaaaSHarshit Aghera         }
179*4ecdfaaaSHarshit Aghera     }
180*4ecdfaaaSHarshit Aghera     else
181*4ecdfaaaSHarshit Aghera     {
182*4ecdfaaaSHarshit Aghera         lg2::error(
183*4ecdfaaaSHarshit Aghera             "Error processing MCTP endpoint with eid {EID} : Property SupportedMessageTypes not found in the configuration.",
184*4ecdfaaaSHarshit Aghera             "EID", eid);
185*4ecdfaaaSHarshit Aghera         return;
186*4ecdfaaaSHarshit Aghera     }
187*4ecdfaaaSHarshit Aghera 
188*4ecdfaaaSHarshit Aghera     if (std::find(mctpTypes.begin(), mctpTypes.end(),
189*4ecdfaaaSHarshit Aghera                   ocp::accelerator_management::messageType) != mctpTypes.end())
190*4ecdfaaaSHarshit Aghera     {
191*4ecdfaaaSHarshit Aghera         lg2::info("Found OCP MCTP VDM Endpoint with ID {EID}", "EID", eid);
192*4ecdfaaaSHarshit Aghera         queryDeviceIdentification(io, objectServer, gpuDevices, conn,
193*4ecdfaaaSHarshit Aghera                                   mctpRequester, configs, path, eid);
194*4ecdfaaaSHarshit Aghera     }
195*4ecdfaaaSHarshit Aghera }
196*4ecdfaaaSHarshit Aghera 
197*4ecdfaaaSHarshit Aghera void queryEndpoints(
198*4ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
199*4ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
200*4ecdfaaaSHarshit Aghera         gpuDevices,
201*4ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& conn,
202*4ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester, const SensorConfigs& configs,
203*4ecdfaaaSHarshit Aghera     const std::string& path, const boost::system::error_code& ec,
204*4ecdfaaaSHarshit Aghera     const GetSubTreeType& ret)
205*4ecdfaaaSHarshit Aghera {
206*4ecdfaaaSHarshit Aghera     if (ec)
207*4ecdfaaaSHarshit Aghera     {
208*4ecdfaaaSHarshit Aghera         lg2::error("Error processing MCTP endpoints: {ERROR}", "ERROR",
209*4ecdfaaaSHarshit Aghera                    ec.message());
210*4ecdfaaaSHarshit Aghera         return;
211*4ecdfaaaSHarshit Aghera     }
212*4ecdfaaaSHarshit Aghera 
213*4ecdfaaaSHarshit Aghera     if (ret.empty())
214*4ecdfaaaSHarshit Aghera     {
215*4ecdfaaaSHarshit Aghera         return;
216*4ecdfaaaSHarshit Aghera     }
217*4ecdfaaaSHarshit Aghera 
218*4ecdfaaaSHarshit Aghera     for (const auto& [objPath, services] : ret)
219*4ecdfaaaSHarshit Aghera     {
220*4ecdfaaaSHarshit Aghera         for (const auto& [service, ifaces] : services)
221*4ecdfaaaSHarshit Aghera         {
222*4ecdfaaaSHarshit Aghera             for (const auto& iface : ifaces)
223*4ecdfaaaSHarshit Aghera             {
224*4ecdfaaaSHarshit Aghera                 if (iface == "xyz.openbmc_project.MCTP.Endpoint")
225*4ecdfaaaSHarshit Aghera                 {
226*4ecdfaaaSHarshit Aghera                     conn->async_method_call(
227*4ecdfaaaSHarshit Aghera                         [&io, &objectServer, &gpuDevices, conn, &mctpRequester,
228*4ecdfaaaSHarshit Aghera                          configs, path](const boost::system::error_code& ec,
229*4ecdfaaaSHarshit Aghera                                         const SensorBaseConfigMap& endpoint) {
230*4ecdfaaaSHarshit Aghera                             processEndpoint(io, objectServer, gpuDevices, conn,
231*4ecdfaaaSHarshit Aghera                                             mctpRequester, configs, path, ec,
232*4ecdfaaaSHarshit Aghera                                             endpoint);
233*4ecdfaaaSHarshit Aghera                         },
234*4ecdfaaaSHarshit Aghera                         service, objPath, "org.freedesktop.DBus.Properties",
235*4ecdfaaaSHarshit Aghera                         "GetAll", iface);
236*4ecdfaaaSHarshit Aghera                 }
237*4ecdfaaaSHarshit Aghera             }
238*4ecdfaaaSHarshit Aghera         }
239*4ecdfaaaSHarshit Aghera     }
240*4ecdfaaaSHarshit Aghera }
241*4ecdfaaaSHarshit Aghera 
242*4ecdfaaaSHarshit Aghera void discoverDevices(
243*4ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
244*4ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
245*4ecdfaaaSHarshit Aghera         gpuDevices,
246*4ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& conn,
247*4ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester, const SensorConfigs& configs,
248*4ecdfaaaSHarshit Aghera     const std::string& path)
249*4ecdfaaaSHarshit Aghera {
250*4ecdfaaaSHarshit Aghera     std::string searchPath{"/au/com/codeconstruct/"};
251*4ecdfaaaSHarshit Aghera     std::vector<std::string> ifaceList{{"xyz.openbmc_project.MCTP.Endpoint"}};
252*4ecdfaaaSHarshit Aghera 
253*4ecdfaaaSHarshit Aghera     conn->async_method_call(
254*4ecdfaaaSHarshit Aghera         [&io, &objectServer, &gpuDevices, conn, &mctpRequester, configs,
255*4ecdfaaaSHarshit Aghera          path](const boost::system::error_code& ec, const GetSubTreeType& ret) {
256*4ecdfaaaSHarshit Aghera             queryEndpoints(io, objectServer, gpuDevices, conn, mctpRequester,
257*4ecdfaaaSHarshit Aghera                            configs, path, ec, ret);
258*4ecdfaaaSHarshit Aghera         },
259*4ecdfaaaSHarshit Aghera         "xyz.openbmc_project.ObjectMapper",
260*4ecdfaaaSHarshit Aghera         "/xyz/openbmc_project/object_mapper",
261*4ecdfaaaSHarshit Aghera         "xyz.openbmc_project.ObjectMapper", "GetSubTree", searchPath, 0,
262*4ecdfaaaSHarshit Aghera         ifaceList);
263*4ecdfaaaSHarshit Aghera }
264*4ecdfaaaSHarshit Aghera 
265*4ecdfaaaSHarshit Aghera void processSensorConfigs(
266*4ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
267*4ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
268*4ecdfaaaSHarshit Aghera         gpuDevices,
269*4ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
270*4ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester, const ManagedObjectType& resp)
271*4ecdfaaaSHarshit Aghera {
272*4ecdfaaaSHarshit Aghera     for (const auto& [path, interfaces] : resp)
273*4ecdfaaaSHarshit Aghera     {
274*4ecdfaaaSHarshit Aghera         for (const auto& [intf, cfg] : interfaces)
275*4ecdfaaaSHarshit Aghera         {
276*4ecdfaaaSHarshit Aghera             if (intf != configInterfaceName(deviceType))
277*4ecdfaaaSHarshit Aghera             {
278*4ecdfaaaSHarshit Aghera                 continue;
279*4ecdfaaaSHarshit Aghera             }
280*4ecdfaaaSHarshit Aghera 
281*4ecdfaaaSHarshit Aghera             SensorConfigs configs;
282*4ecdfaaaSHarshit Aghera 
283*4ecdfaaaSHarshit Aghera             configs.name = loadVariant<std::string>(cfg, "Name");
284*4ecdfaaaSHarshit Aghera 
285*4ecdfaaaSHarshit Aghera             configs.pollRate = loadVariant<uint64_t>(cfg, "PollRate");
286*4ecdfaaaSHarshit Aghera 
287*4ecdfaaaSHarshit Aghera             discoverDevices(io, objectServer, gpuDevices, dbusConnection,
288*4ecdfaaaSHarshit Aghera                             mctpRequester, configs, path);
289*4ecdfaaaSHarshit Aghera 
290*4ecdfaaaSHarshit Aghera             lg2::info(
291*4ecdfaaaSHarshit Aghera                 "Detected configuration {NAME} of type {TYPE} at path: {PATH}.",
292*4ecdfaaaSHarshit Aghera                 "NAME", configs.name, "TYPE", deviceType, "PATH", path);
293*4ecdfaaaSHarshit Aghera         }
294*4ecdfaaaSHarshit Aghera     }
295*4ecdfaaaSHarshit Aghera }
296*4ecdfaaaSHarshit Aghera 
297*4ecdfaaaSHarshit Aghera void createSensors(
298*4ecdfaaaSHarshit Aghera     boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
299*4ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
300*4ecdfaaaSHarshit Aghera         gpuDevices,
301*4ecdfaaaSHarshit Aghera     const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
302*4ecdfaaaSHarshit Aghera     mctp::MctpRequester& mctpRequester)
303*4ecdfaaaSHarshit Aghera {
304*4ecdfaaaSHarshit Aghera     if (!dbusConnection)
305*4ecdfaaaSHarshit Aghera     {
306*4ecdfaaaSHarshit Aghera         lg2::error("Connection not created");
307*4ecdfaaaSHarshit Aghera         return;
308*4ecdfaaaSHarshit Aghera     }
309*4ecdfaaaSHarshit Aghera     dbusConnection->async_method_call(
310*4ecdfaaaSHarshit Aghera         [&gpuDevices, &mctpRequester, dbusConnection, &io, &objectServer](
311*4ecdfaaaSHarshit Aghera             boost::system::error_code ec, const ManagedObjectType& resp) {
312*4ecdfaaaSHarshit Aghera             if (ec)
313*4ecdfaaaSHarshit Aghera             {
314*4ecdfaaaSHarshit Aghera                 lg2::error("Error contacting entity manager");
315*4ecdfaaaSHarshit Aghera                 return;
316*4ecdfaaaSHarshit Aghera             }
317*4ecdfaaaSHarshit Aghera 
318*4ecdfaaaSHarshit Aghera             processSensorConfigs(io, objectServer, gpuDevices, dbusConnection,
319*4ecdfaaaSHarshit Aghera                                  mctpRequester, resp);
320*4ecdfaaaSHarshit Aghera         },
321*4ecdfaaaSHarshit Aghera         entityManagerName, "/xyz/openbmc_project/inventory",
322*4ecdfaaaSHarshit Aghera         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
323*4ecdfaaaSHarshit Aghera }
324*4ecdfaaaSHarshit Aghera 
325*4ecdfaaaSHarshit Aghera void interfaceRemoved(
326*4ecdfaaaSHarshit Aghera     sdbusplus::message_t& message,
327*4ecdfaaaSHarshit Aghera     boost::container::flat_map<std::string, std::shared_ptr<GpuDevice>>&
328*4ecdfaaaSHarshit Aghera         gpuDevices)
329*4ecdfaaaSHarshit Aghera {
330*4ecdfaaaSHarshit Aghera     if (message.is_method_error())
331*4ecdfaaaSHarshit Aghera     {
332*4ecdfaaaSHarshit Aghera         lg2::error("interfacesRemoved callback method error");
333*4ecdfaaaSHarshit Aghera         return;
334*4ecdfaaaSHarshit Aghera     }
335*4ecdfaaaSHarshit Aghera 
336*4ecdfaaaSHarshit Aghera     sdbusplus::message::object_path removedPath;
337*4ecdfaaaSHarshit Aghera     std::vector<std::string> interfaces;
338*4ecdfaaaSHarshit Aghera 
339*4ecdfaaaSHarshit Aghera     message.read(removedPath, interfaces);
340*4ecdfaaaSHarshit Aghera 
341*4ecdfaaaSHarshit Aghera     // If the xyz.openbmc_project.Confguration.X interface was removed
342*4ecdfaaaSHarshit Aghera     // for one or more sensors, delete those sensor objects.
343*4ecdfaaaSHarshit Aghera     auto sensorIt = gpuDevices.begin();
344*4ecdfaaaSHarshit Aghera     while (sensorIt != gpuDevices.end())
345*4ecdfaaaSHarshit Aghera     {
346*4ecdfaaaSHarshit Aghera         if ((sensorIt->second->getPath() == removedPath) &&
347*4ecdfaaaSHarshit Aghera             (std::find(interfaces.begin(), interfaces.end(),
348*4ecdfaaaSHarshit Aghera                        configInterfaceName(deviceType)) != interfaces.end()))
349*4ecdfaaaSHarshit Aghera         {
350*4ecdfaaaSHarshit Aghera             sensorIt = gpuDevices.erase(sensorIt);
351*4ecdfaaaSHarshit Aghera         }
352*4ecdfaaaSHarshit Aghera         else
353*4ecdfaaaSHarshit Aghera         {
354*4ecdfaaaSHarshit Aghera             sensorIt++;
355*4ecdfaaaSHarshit Aghera         }
356*4ecdfaaaSHarshit Aghera     }
357*4ecdfaaaSHarshit Aghera }
358