Line data Source code
1 : /**
2 : * Copyright (c) 2025 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 :
11 : #include "rts_notify.h"
12 : #include "sal_pub.h"
13 :
14 : namespace hccl {
15 :
16 1013 : RtsNotify::RtsNotify(NotifyType notifyType)
17 1013 : : NotifyBase(notifyType)
18 : {
19 1013 : }
20 :
21 1 : RtsNotify::RtsNotify(NotifyType notifyType, HcclNotifyInfo notifyInfo)
22 1 : : NotifyBase(notifyType, notifyInfo)
23 : {
24 1 : }
25 :
26 4350 : RtsNotify::RtsNotify(NotifyType notifyType, const HcclSignalInfo ¬ifyInfo)
27 4350 : : NotifyBase(notifyType)
28 : {
29 4350 : (void)SetNotifyData(notifyInfo);
30 4350 : }
31 :
32 10734 : RtsNotify::~RtsNotify()
33 : {
34 5367 : (void)Destroy();
35 10734 : }
36 :
37 1 : HcclResult RtsNotify::Open()
38 : {
39 1 : HCCL_DEBUG("[RtsNotify][Open]remote withIpc[%d], notify type[%d], ipcName[%s].",
40 : notifyInfo_.ipcNotify.withIpc, notifyType, notifyInfo_.ipcNotify.ipcName);
41 1 : if (notifyInfo_.ipcNotify.withIpc) {
42 0 : if (notifyType == NotifyType::RUNTIME_NOTIFY) {
43 0 : CHK_RET(hrtIpcOpenNotify(¬ifyPtr, notifyInfo_.ipcNotify.ipcName));
44 : } else {
45 0 : CHK_RET(hrtIpcOpenNotifyWithFlag(¬ifyPtr, notifyInfo_.ipcNotify.ipcName,
46 : ACL_NOTIFY_DEVICE_USE_ONLY));
47 : }
48 : } else {
49 1 : notifyPtr = notifyInfo_.ipcNotify.ptr;
50 : }
51 1 : HCCL_DEBUG("[RtsNotify][Open]notifyPtr[%p], ipcNotify[%p].", notifyPtr, notifyInfo_.ipcNotify.ptr);
52 :
53 1 : CHK_PRT_RET(notifyPtr == nullptr, HCCL_ERROR("[RtsNotify][Open]errNo[0x%016llx] Notify open failed. "\
54 : "notify is nullptr", HCCL_ERROR_CODE(HCCL_E_RUNTIME)), HCCL_E_RUNTIME);
55 :
56 1 : inchip = false;
57 1 : isLocal = false;
58 1 : CHK_RET(UpdateNotifyInfo());
59 1 : CHK_RET(hrtNotifyGetAddr(notifyPtr, &address));
60 :
61 1 : return HCCL_SUCCESS;
62 : }
63 :
64 4 : HcclResult RtsNotify::Close()
65 : {
66 4 : return Destroy();
67 : }
68 :
69 0 : HcclResult RtsNotify::Wait(Stream& stream, HcclDispatcher dispatcher, s32 stage, u32 timeOut)
70 : {
71 0 : CHK_PTR_NULL(dispatcher);
72 0 : return reinterpret_cast<DispatcherPub*>(dispatcher)->SignalWait(
73 0 : notifyPtr, stream, INVALID_VALUE_RANKID, INVALID_VALUE_RANKID, stage, inchip, INVALID_UINT, timeOut);
74 : }
75 :
76 0 : HcclResult RtsNotify::Post(Stream& stream, HcclDispatcher dispatcher, s32 stage)
77 : {
78 0 : CHK_PTR_NULL(dispatcher);
79 0 : return reinterpret_cast<DispatcherPub*>(dispatcher)->SignalRecord(
80 0 : notifyPtr, stream, INVALID_VALUE_RANKID, notifyInfo_.ipcNotify.offset, stage, inchip, address);
81 : }
82 :
83 0 : HcclResult RtsNotify::Wait(Stream& stream, HcclDispatcher dispatcher, s32 stage, u32 timeOut,
84 : u32 userRank, u32 remoteUserRank)
85 : {
86 0 : CHK_PTR_NULL(dispatcher);
87 0 : return reinterpret_cast<DispatcherPub*>(dispatcher)->SignalWait(
88 0 : notifyPtr, stream, userRank, remoteUserRank, stage, inchip, INVALID_UINT, timeOut);
89 : }
90 :
91 0 : HcclResult RtsNotify::Post(Stream& stream, HcclDispatcher dispatcher, s32 stage, u32 remoteUserRank)
92 : {
93 0 : CHK_PTR_NULL(dispatcher);
94 0 : return reinterpret_cast<DispatcherPub*>(dispatcher)->SignalRecord(
95 0 : notifyPtr, stream, remoteUserRank, notifyInfo_.ipcNotify.offset, stage, inchip, address);
96 : }
97 :
98 1 : HcclResult RtsNotify::Post(Stream& stream)
99 : {
100 1 : CHK_RET(hrtNotifyRecord(notifyPtr, stream.ptr()));
101 1 : return HCCL_SUCCESS;
102 : }
103 :
104 1 : HcclResult RtsNotify::Wait(Stream& stream, u32 timeOut)
105 : {
106 1 : CHK_RET(hrtNotifyWaitWithTimeOut(notifyPtr, stream.ptr(), timeOut));
107 1 : return HCCL_SUCCESS;
108 : }
109 :
110 71 : HcclResult RtsNotify::SetIpc()
111 : {
112 71 : SecIpcName_t ipcName;
113 71 : HcclResult ret = hrtIpcSetNotifyName(notifyPtr, reinterpret_cast<u8 *>(ipcName.ipcName),
114 : sizeof(ipcName.ipcName));
115 71 : CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[SetIpc][hrtIpcSetNotifyName]errNo[0x%016llx] "\
116 : " IPC set notify name fail. return[%d] name len=[%zu].", HCCL_ERROR_CODE(HCCL_E_RUNTIME),\
117 : ret, sizeof(ipcName.ipcName)), HCCL_E_RUNTIME);
118 71 : if (memcpy_s(notifyInfo_.ipcNotify.ipcName, HCCL_IPC_MEM_NAME_LEN,
119 71 : reinterpret_cast<char *>(ipcName.ipcName), sizeof(ipcName.ipcName)) != EOK) {
120 0 : HCCL_ERROR("ipcName:%s, size:%u", ipcName.ipcName, sizeof(ipcName.ipcName));
121 0 : return HCCL_E_MEMORY;
122 : };
123 71 : HCCL_DEBUG("[RtsNotify][SetIpc]ipcName:%s, size:%u.", ipcName.ipcName, sizeof(ipcName.ipcName));
124 71 : CHK_RET(hrtNotifyGetAddr(notifyPtr, &address));
125 71 : CHK_RET(UpdateNotifyInfo());
126 :
127 71 : return HCCL_SUCCESS;
128 71 : }
129 :
130 0 : HcclResult RtsNotify::Grant(s64 recvId)
131 : {
132 : // 设置notify 的白名单
133 0 : inchip = false;
134 0 : s32 pid = static_cast<s32>((recvId & 0x00000000FFFFFFFF));
135 0 : s32 localPid = 0;
136 0 : CHK_RET(SalGetBareTgid(&localPid)); // 当前进程id
137 :
138 : // 多进程操作多卡场景,notify pool用pid区分notify
139 0 : s32 sdid = static_cast<s32>((recvId & 0xFFFFFFFF00000000) >> 32);
140 0 : HCCL_DEBUG("[RtsNotify][Grant]remote sdid[%016llx], remote pid[%d], local pid[%d], withIpc[%d].",
141 : sdid, pid, localPid, notifyInfo_.ipcNotify.withIpc);
142 :
143 : // 单进程多线程操作多卡场景,notify pool用rankId区分notify
144 0 : if (pid == localPid && sdid == INVALID_INT) {
145 0 : if (notifyType == NotifyType::RUNTIME_NOTIFY_MC2) {
146 0 : notifyInfo_.ipcNotify.withIpc = true;
147 : }
148 0 : return HCCL_SUCCESS;
149 : }
150 :
151 0 : notifyInfo_.ipcNotify.withIpc = true;
152 :
153 0 : if (sdid != INVALID_INT) {
154 : // recvId由s32的sdid和pid拼接而成, 高32位是sdid, 低32位是pid
155 0 : CHK_RET(hrtSetIpcNotifySuperPodPid(notifyPtr, sdid, &pid, IPC_NOTIFY_PID_ARRAY_SIZE));
156 : } else {
157 0 : CHK_RET(hrtSetIpcNotifyPid(notifyPtr, &pid, IPC_NOTIFY_PID_ARRAY_SIZE));
158 : }
159 0 : return HCCL_SUCCESS;
160 : }
161 :
162 1014 : HcclResult RtsNotify::Alloc()
163 : {
164 1014 : s32 deviceId = 0;
165 1014 : CHK_RET(hrtGetDevice(&deviceId));
166 :
167 1016 : if (notifyType == NotifyType::RUNTIME_NOTIFY) {
168 534 : CHK_RET(hrtNotifyCreate(deviceId, ¬ifyPtr));
169 534 : CHK_RET(hrtGetNotifyID(notifyPtr, &id));
170 : } else {
171 482 : CHK_RET(hrtNotifyCreateWithFlag(deviceId, ¬ifyPtr));
172 : }
173 1016 : CHK_PRT_RET(notifyPtr == nullptr, HCCL_ERROR("[RtsNotify][Alloc]errNo[0x%016llx] Notify create failed. "\
174 : "notify is nullptr", HCCL_ERROR_CODE(HCCL_E_RUNTIME)), HCCL_E_RUNTIME);
175 1016 : if (notifyType == NotifyType::RUNTIME_NOTIFY_MC2) {
176 482 : CHK_RET(UpdateNotifyInfo());
177 : }
178 1016 : CHK_RET(hrtNotifyGetOffset(notifyPtr, notifyInfo_.ipcNotify.offset));
179 1012 : notifyInfo_.ipcNotify.ptr = notifyPtr;
180 1012 : return HCCL_SUCCESS;
181 : }
182 :
183 6383 : HcclResult RtsNotify::Destroy()
184 : {
185 : // 本卡notify直接释放,非本卡判断且非单进程多线程场景直接释放
186 6383 : if (notifyPtr != nullptr && (isLocal || notifyInfo_.ipcNotify.withIpc)) {
187 1016 : CHK_RET(hrtNotifyDestroy(notifyPtr));
188 : }
189 6383 : notifyPtr = nullptr;
190 6383 : return HCCL_SUCCESS;
191 : }
192 :
193 554 : HcclResult RtsNotify::UpdateNotifyInfo()
194 : {
195 554 : CHK_RET(hrtGetNotifyID(notifyPtr, &id));
196 :
197 554 : DevType devType_ = DevType::DEV_TYPE_COUNT;
198 554 : CHK_RET(hrtGetDeviceType(devType_));
199 554 : if (devType_ == DevType::DEV_TYPE_950 || devType_ == DevType::DEV_TYPE_960) {
200 : s32 deviceLogicId;
201 206 : CHK_RET(hrtGetDevice(&deviceLogicId));
202 206 : CHK_RET(hrtGetDevicePhyIdByIndex(static_cast<uint32_t>(deviceLogicId), devId));
203 206 : return HCCL_SUCCESS;
204 : }
205 :
206 348 : CHK_RET(hrtNotifyGetPhyInfo(notifyPtr, &devId, &tsId));
207 :
208 : rtNotifyPhyInfo notifyInfo;
209 348 : CHK_RET(hrtNotifyGetPhyInfoExt(notifyPtr, ¬ifyInfo));
210 348 : flag = notifyInfo.flag;
211 :
212 348 : return HCCL_SUCCESS;
213 : }
214 :
215 : extern "C" {
216 : drvError_t __attribute__((weak)) halResourceIdCheck(struct drvResIdKey *info);
217 : drvError_t __attribute__((weak)) halResourceIdInfoGet(struct drvResIdKey *key, drvResIdProcType type, uint64_t *value);
218 : };
219 :
220 4347 : HcclResult RtsNotify::InitAndVerifySingleSignal()
221 : {
222 : #ifdef CCL_KERNEL
223 4347 : if (id == INVALID_UINT) {
224 : // 无效值不做校验
225 0 : HCCL_DEBUG("[%s]resId[%u] is invalid, need not check", __func__, id);
226 0 : return HCCL_SUCCESS;
227 : }
228 :
229 4347 : drvResIdKey resInfo = {};
230 4347 : resInfo.ruDevId = devId;
231 4347 : resInfo.tsId = tsId;
232 4347 : resInfo.resType = DRV_NOTIFY_ID;
233 4347 : resInfo.resId = static_cast<uint32_t>(id);
234 4347 : resInfo.flag = flag;
235 4347 : resInfo.rsv[0] = 0; // 0 is reserved array idx
236 4347 : resInfo.rsv[1] = 0; // 1 is reserved array idx
237 4347 : resInfo.rsv[2] = 0; // 2 is reserved array idx
238 :
239 : static bool init = false;
240 4347 : if (!init) {
241 5 : CHK_PRT_RET(halResourceIdCheck == nullptr, HCCL_ERROR("halResourceIdCheck is nullptr, "
242 : "Does not support this interface."), HCCL_E_DRV);
243 5 : CHK_PRT_RET(halResourceIdInfoGet == nullptr, HCCL_ERROR("halResourceIdInfoGet is nullptr, "
244 : "Does not support this interface."), HCCL_E_DRV);
245 5 : init = true;
246 : }
247 :
248 4347 : HcclResult ret = hrtHalResourceIdRestore(resInfo.ruDevId, resInfo.tsId, resInfo.resType, resInfo.resId, resInfo.flag);
249 4347 : if (ret != HCCL_SUCCESS && ret != HCCL_E_NOT_SUPPORT) {
250 0 : HCCL_ERROR("[drv api]res restore failed, result:%d, resType:%d, resId:%u, tsId:%d, ruDevId:%d, flag:%d",
251 : ret, resInfo.resType, resInfo.resId, resInfo.tsId, resInfo.ruDevId, resInfo.flag);
252 0 : return HCCL_E_DRV;
253 : }
254 4347 : HCCL_DEBUG("res restore end, ret:%d, resType:%d, resId:%u, tsId:%u, ruDevId:%u, flag:%u",
255 : ret, resInfo.resType, resInfo.resId, resInfo.tsId, resInfo.ruDevId, resInfo.flag);
256 :
257 4347 : int checkResult = halResourceIdCheck(&resInfo);
258 4347 : if (checkResult != 0) {
259 0 : HCCL_ERROR("[drv api]res check failed, result:%d, resType:%d, resId:%u, tsId:%u, ruDevId:%u, flag:%u",
260 : checkResult, resInfo.resType, resInfo.resId, resInfo.tsId, resInfo.ruDevId, resInfo.flag);
261 0 : return HCCL_E_DRV;
262 : }
263 4347 : HCCL_DEBUG("res check success, resType:%d, resId:%u, tsId:%u, ruDevId:%u, flag:%u", resInfo.resType, resInfo.resId,
264 : resInfo.tsId, resInfo.ruDevId, resInfo.flag);
265 :
266 4347 : checkResult = halResourceIdInfoGet(&resInfo, TRS_RES_ID_ADDR, reinterpret_cast<uint64_t *>(&address));
267 4347 : if (checkResult != 0) {
268 0 : HCCL_ERROR("[drv api]res get addr failed, result:%d, resType:%d, resId:%u, tsId:%d, ruDevId:%u, flag:%u",
269 : checkResult, resInfo.resType, resInfo.resId, resInfo.tsId, resInfo.ruDevId, resInfo.flag);
270 0 : return HCCL_E_DRV;
271 : }
272 4347 : HCCL_DEBUG("res get write value success, resType:%d, resId:%u, tsId:%u, ruDevId:%u, flag:%u, addr:%llu",
273 : resInfo.resType, resInfo.resId, resInfo.tsId, resInfo.ruDevId, resInfo.flag, address);
274 : #endif
275 :
276 4347 : return HCCL_SUCCESS;
277 : }
278 : }
|