Line data Source code
1 : /**
2 : * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 : #include "dump_stats_server.h"
11 :
12 : namespace kfc_dump_stats {
13 : uint64_t g_kfcDumpWaitTimeout = DEFAULT_KFC_DUMP_WAIT_TIMEOUT;
14 :
15 33 : void KfcDumpStatsServer::Init(uint64_t workSpaceAddr)
16 : {
17 33 : msgBody_ = reinterpret_cast<KfcDumpMsgBody*>(workSpaceAddr);
18 33 : rcvMsgPos_ = 0;
19 33 : sndMsgPos_ = 0;
20 33 : }
21 :
22 : #pragma GCC push_options
23 : #pragma GCC optimize("O0")
24 :
25 466 : KfcDumpResult KfcDumpStatsServer::PostMsg(KfcDumpStatsMsg* rMsg)
26 : {
27 466 : auto pos = sndMsgPos_;
28 466 : auto* msg = &msgBody_->msgSndArea[pos];
29 466 : uint64_t startPostTime = GetCurCpuTimestamp();
30 466 : while (msg->valid == DUMP_MSG_VALID_MASK) {
31 0 : if (GetCurCpuTimestamp() - startPostTime >= g_kfcDumpWaitTimeout) {
32 0 : IDE_LOGE("Failed to post kfc dump message, wait for free message slot timeout");
33 0 : return KFC_DUMP_E_TIMEOUT;
34 : }
35 : }
36 :
37 466 : IDE_LOGI("Post kfc dump message to global memory address[%p]", msg);
38 466 : errno_t ret = memcpy_s(msg, sizeof(KfcDumpStatsMsg), rMsg, sizeof(KfcDumpStatsMsg));
39 466 : if (ret != EOK) {
40 0 : IDE_LOGE("Failed to copy kfc dump message to send area, ret[%d]", ret);
41 0 : return KFC_DUMP_E_MEMORY;
42 : }
43 : // ARM弱序:此屏障保证msg其他字段先于valid字段对AIV可见,使AIV侧见valid字段即msg就绪,不可删除。
44 : #ifdef __aarch64__
45 : __asm__ __volatile__("dsb st" : : : "memory");
46 : #endif
47 466 : msg->valid = DUMP_MSG_VALID_MASK;
48 : // 此屏障保证valid字段尽快排出store buffer对AIV可见,减少AIV的轮询等待。
49 : #ifdef __aarch64__
50 : __asm__ __volatile__("dsb st" : : : "memory");
51 : #endif
52 466 : IDE_LOGI(
53 : "Post kfc dump message done. position=%u, sndAddr=%p, msgType=%u, dataType=%u, dataCount=%lu, "
54 : "dataAddr=0x%lx, dumpStatClass=%lu, outputAddr=0x%lx, outputAddrSize=%lu, valid=0x%x, result=%u",
55 : pos, static_cast<void*>(msg), static_cast<uint32_t>(msg->msgType), msg->dataType, msg->dataCount, msg->dataAddr,
56 : msg->dumpStatClass, msg->outputAddr, msg->outputAddrSize, msg->valid, msg->result);
57 466 : pos = (pos + 1) % DUMP_MSG_CNT;
58 466 : sndMsgPos_ = pos;
59 466 : return KFC_DUMP_SUCCESS;
60 : }
61 :
62 437 : KfcDumpResult KfcDumpStatsServer::RcvMsg(KfcDumpStatsMsg* rMsg)
63 : {
64 437 : if (rMsg == nullptr) {
65 1 : return KFC_DUMP_E_PARA;
66 : }
67 436 : auto pos = rcvMsgPos_;
68 436 : auto msg = &msgBody_->msgRcvArea[pos];
69 436 : IDE_LOGD("Waiting for kfc dump message response, receive position[%u]", pos);
70 436 : auto startWaitTime = GetCurCpuTimestamp();
71 : do {
72 43863743 : if (CheckTimeOut(startWaitTime) != KFC_DUMP_SUCCESS) {
73 1 : IDE_LOGE("Failed to receive kfc dump message, wait for response timeout");
74 1 : return KFC_DUMP_E_TIMEOUT;
75 : }
76 43863742 : } while (!ReadValidMsg(rMsg, msg));
77 435 : IDE_LOGI(
78 : "Receive kfc dump message done. position=%u, sndAddr=%p, msgType=%u, dataType=%u, dataCount=%lu, "
79 : "dataAddr=0x%lx, dumpStatClass=%lu, outputAddr=0x%lx, outputAddrSize=%lu, valid=0x%x, result=%u",
80 : pos, static_cast<void*>(msg), static_cast<uint32_t>(msg->msgType), msg->dataType, msg->dataCount, msg->dataAddr,
81 : msg->dumpStatClass, msg->outputAddr, msg->outputAddrSize, msg->valid, msg->result);
82 435 : pos = (pos + 1) % DUMP_MSG_CNT;
83 435 : rcvMsgPos_ = pos;
84 435 : return KFC_DUMP_SUCCESS;
85 : }
86 :
87 43863742 : bool KfcDumpStatsServer::ReadValidMsg(KfcDumpStatsMsg* rMsg, KfcDumpStatsMsg* msg)
88 : {
89 : // 见valid字段即msg就绪,AIV写完全部字段后才刷出msg(单cache line 64B),valid字段和msg其他字段同时可见。
90 43863742 : if (msg->valid != DUMP_MSG_VALID_MASK) {
91 43863307 : return false;
92 : }
93 435 : errno_t ret = memcpy_s(rMsg, sizeof(KfcDumpStatsMsg), msg, sizeof(KfcDumpStatsMsg));
94 435 : if (ret != EOK) {
95 0 : IDE_LOGE("Failed to copy kfc dump message from receive area, ret[%d]", ret);
96 0 : return false;
97 : }
98 435 : msg->valid = ~DUMP_MSG_VALID_MASK;
99 435 : return true;
100 : }
101 :
102 432 : KfcDumpResult KfcDumpStatsServer::CheckDumpResult(KfcDumpStatsMsg* rMsg)
103 : {
104 432 : if (rMsg->result != 0) {
105 20 : IDE_LOGW("Statistics are not supported for tensor data type[%u]", rMsg->dataType);
106 : }
107 432 : return KFC_DUMP_SUCCESS;
108 : }
109 :
110 : #pragma GCC pop_options
111 : } // namespace kfc_dump_stats
|