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