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