| /* |
| * SPDX-FileCopyrightText: Copyright OpenBMC Authors |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #pragma once |
| |
| #include <MctpRequester.hpp> |
| #include <MessagePackUnpackUtils.hpp> |
| #include <NvidiaGpuMctpVdm.hpp> |
| #include <NvidiaLongRunningHandler.hpp> |
| #include <OcpMctpVdm.hpp> |
| #include <SerialQueue.hpp> |
| #include <boost/system/error_code.hpp> |
| |
| #include <cstdint> |
| #include <functional> |
| #include <memory> |
| #include <span> |
| #include <string> |
| #include <system_error> |
| #include <vector> |
| |
| // Helper that consolidates the long-running NSM command pipeline: |
| // queue submission, MCTP request/response, common-header decode, |
| // SUCCESS vs ACCEPTED branching, long-running response event handling. |
| // |
| // Per-command specifics (encode, payload decode) are supplied through |
| // Config callables. The helper has no knowledge of D-Bus, inventory, |
| // or which metric is calling it. |
| class NvidiaGpuLongRunningCommand : |
| public std::enable_shared_from_this<NvidiaGpuLongRunningCommand> |
| { |
| public: |
| struct Config |
| { |
| // Identifies the metric in log messages (e.g. "GPU Current |
| // Utilization"). |
| std::string metricName; |
| |
| gpu::MessageType messageType; |
| gpu::PlatformEnvironmentalCommands commandId; |
| |
| // Size of the MCTP request buffer. The helper allocates a buffer of |
| // this size once at construction and reuses it across update() calls, |
| // so no per-request allocation occurs. |
| size_t requestSize; |
| |
| // Fills the request bytes into `buf`. Returns 0 on success. |
| std::move_only_function<int(std::span<uint8_t> buf)> encodeRequest; |
| |
| // Invoked when the device replies SUCCESS synchronously. `fullBuffer` |
| // is the entire MCTP response (including the common response header) |
| // so the caller can reuse the existing decodeGet*Response() helpers. |
| std::move_only_function<void(std::span<const uint8_t> fullBuffer)> |
| onImmediateSuccess; |
| |
| // Invoked when the long-running response event arrives successfully. |
| // `payload` is the bytes the device returned for the command (no |
| // OCP/common header). The caller decodes via the matching |
| // decodeGet*Response() overload. |
| std::move_only_function<void(std::span<const uint8_t> payload)> |
| onLongRunningPayload; |
| }; |
| |
| NvidiaGpuLongRunningCommand( |
| uint8_t eid, mctp::MctpRequester& mctpRequester, |
| std::shared_ptr<SerialQueue> longRunningQueue, |
| std::shared_ptr<NvidiaLongRunningResponseHandler> |
| longRunningResponseHandler, |
| Config config); |
| |
| void update(); |
| |
| private: |
| void doUpdate(SerialQueue::ReleaseHandle handle); |
| |
| void processResponse(SerialQueue::ReleaseHandle handle, |
| const std::error_code& ec, |
| std::span<const uint8_t> buffer); |
| |
| void processLongRunningResponse( |
| boost::system::error_code ec, |
| ocp::accelerator_management::CompletionCode cc, uint16_t reasonCode, |
| std::span<const uint8_t> responseData); |
| |
| uint8_t eid; |
| |
| mctp::MctpRequester& mctpRequester; |
| |
| std::shared_ptr<SerialQueue> longRunningQueue; |
| |
| std::shared_ptr<NvidiaLongRunningResponseHandler> |
| longRunningResponseHandler; |
| |
| Config config; |
| |
| std::vector<uint8_t> request; |
| |
| bool requestEncoded{false}; |
| }; |