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 "adapter_rts.h"
12 :
13 : #include "log.h"
14 : #include "sal_pub.h"
15 : #include "mem_name_repository.h"
16 :
17 : namespace hccl {
18 64 : MemNameRepository::~MemNameRepository() { ClearMemNameRepository(); }
19 :
20 129 : MemNameRepository* MemNameRepository::GetInstance(s32 deviceLogicID)
21 : {
22 193 : static MemNameRepository instances[MAX_DEV_NUM_IPC_MEM];
23 129 : if (deviceLogicID == HOST_DEVICE_ID) {
24 0 : return &instances[0];
25 : }
26 :
27 129 : if (static_cast<u32>(deviceLogicID) >= MAX_DEV_NUM_IPC_MEM || deviceLogicID < 0) {
28 0 : HCCL_WARNING("[Get][Instance]deviceLogicID[%d] is invalid", deviceLogicID);
29 0 : return &instances[0];
30 : }
31 129 : return &instances[deviceLogicID];
32 : }
33 :
34 1 : HcclResult MemNameRepository::SetDeviceUnavailable(bool unavailable)
35 : {
36 1 : unavailable_ = unavailable;
37 1 : HCCL_RUN_INFO("SetDeviceUnavailable unavailable[%d]", unavailable);
38 1 : return HCCL_SUCCESS;
39 : }
40 :
41 0 : HcclResult MemNameRepository::SetIpcMem(void* ptr, u64 size, u8* name, u32 nameLen, u64& offset, bool isSioToHccs)
42 : {
43 0 : CHK_PTR_NULL(name);
44 0 : CHK_PTR_NULL(ptr);
45 :
46 : HcclResult ret;
47 0 : std::unique_lock<std::mutex> lock(memMutex_);
48 0 : IpcMemInfo ipcMemInfo = {};
49 :
50 0 : ipcMemInfo.ptr = ptr;
51 0 : ipcMemInfo.size = size;
52 0 : ipcMemInfo.isSioToHccs = isSioToHccs;
53 0 : IpcMemInfo preIpcMemInfo = ipcMemInfo;
54 :
55 : // 记录页表大小
56 0 : ret = hrtDevMemAlignWithPage(ipcMemInfo.ptr, ipcMemInfo.size);
57 0 : CHK_PRT_RET(
58 : ret != HCCL_SUCCESS,
59 : HCCL_ERROR(
60 : "[Set][IpcMem]errNo[0x%016llx] Set ptr and offset error. ptr[%p] size[%llu Byte]", HCCL_ERROR_CODE(ret),
61 : ipcMemInfo.ptr, ipcMemInfo.size),
62 : ret);
63 0 : alignPtrMap_.insert(std::make_pair(preIpcMemInfo, ipcMemInfo));
64 :
65 : // 在SetNameMap中查找MemName,若未找到则插入
66 0 : ret = FindIpcMem(ipcMemInfo, name, nameLen);
67 0 : CHK_PRT_RET(
68 : ret != HCCL_SUCCESS,
69 : HCCL_ERROR(
70 : "[Find][IpcMem]errNo[0x%016llx] In link base, sal Find ipc memory error. ptr[%p] size[%llu Byte]",
71 : HCCL_ERROR_CODE(ret), ipcMemInfo.ptr, ipcMemInfo.size),
72 : ret);
73 :
74 0 : offset = reinterpret_cast<u64>(ptr) - reinterpret_cast<u64>(ipcMemInfo.ptr);
75 :
76 0 : return HCCL_SUCCESS;
77 0 : }
78 :
79 0 : HcclResult MemNameRepository::SetIpcMem(void* ptr, u64 size, u8* name, u32 nameLen)
80 : {
81 0 : CHK_PTR_NULL(name);
82 0 : CHK_PTR_NULL(ptr);
83 :
84 : HcclResult ret;
85 0 : std::unique_lock<std::mutex> lock(memMutex_);
86 0 : IpcMemInfo ipcMemInfo = {};
87 :
88 0 : ipcMemInfo.ptr = ptr;
89 0 : ipcMemInfo.size = size;
90 0 : ipcMemInfo.isSioToHccs = false;
91 0 : alignPtrMap_.insert(std::make_pair(ipcMemInfo, ipcMemInfo));
92 :
93 : // 在SetNameMap中查找memName,若未找到则插入
94 0 : ret = FindIpcMem(ipcMemInfo, name, nameLen);
95 0 : CHK_PRT_RET(
96 : ret != HCCL_SUCCESS,
97 : HCCL_ERROR(
98 : "[Find][IpcMem]errNo[0x%016llx] In link base, sal Find ipc memory error. ptr[%p] size[%llu Byte]",
99 : HCCL_ERROR_CODE(ret), ipcMemInfo.ptr, ipcMemInfo.size),
100 : ret);
101 :
102 0 : return HCCL_SUCCESS;
103 0 : }
104 :
105 0 : HcclResult MemNameRepository::SetIpcMem(
106 : void* ptr, u64 size, u8* name, u32 nameLen, u64& offset, s32 pid, s32 sdid, bool isSioToHccs)
107 : {
108 0 : HCCL_DEBUG(
109 : "SetIpcMem para: ptr[%p], size[%llu Byte], name[%d], nameLen[%u], pid[%d], sdid[%016llx], isSioToHccs[%d]", ptr,
110 : size, name, nameLen, pid, sdid, isSioToHccs);
111 :
112 0 : CHK_RET(SetIpcMem(ptr, size, name, nameLen, offset, isSioToHccs));
113 :
114 : /* 不管任何情况,都需设置PID 的白名单 */
115 0 : if (sdid != INVALID_INT) {
116 0 : CHK_RET(hrtSetIpcMemorySuperPodPid(name, sdid, &pid, HCCL_IPC_PID_ARRAY_SIZE));
117 : } else {
118 0 : CHK_RET(hrtIpcSetMemoryPid(name, &pid, HCCL_IPC_PID_ARRAY_SIZE));
119 : }
120 0 : return HCCL_SUCCESS;
121 : }
122 :
123 : // 在SetNameMap中查找MemName,若未找到则插入
124 0 : HcclResult MemNameRepository::FindIpcMem(IpcMemInfo& ipcMemInfo, u8* name, u32 nameLen)
125 : {
126 : s32 sret;
127 : HcclResult ret;
128 0 : auto iter = setNameMap_.find(ipcMemInfo);
129 0 : if (iter == setNameMap_.end()) {
130 0 : ret = hrtIpcSetMemoryName(ipcMemInfo.ptr, name, ipcMemInfo.size, nameLen);
131 0 : CHK_PRT_RET(
132 : ret != HCCL_SUCCESS,
133 : HCCL_ERROR(
134 : "[Set][IpcMem]errNo[0x%016llx] In link base, sal set ipc memory error. ptr[%p] size[%llu Byte]",
135 : HCCL_ERROR_CODE(ret), ipcMemInfo.ptr, ipcMemInfo.size),
136 : ret);
137 :
138 0 : SecIpcName_t memName;
139 0 : sret = memcpy_s(memName.ipcName, HCCL_IPC_MEM_NAME_LEN, name, nameLen);
140 0 : if (sret != EOK) {
141 0 : HCCL_ERROR(
142 : "[Set][IpcMem]errNo[0x%016llx] In SecIpcName, memcpy_s failed. errorno[%d], params:"
143 : "dest len[%u], src len[%u]",
144 : HCCL_ERROR_CODE(HCCL_E_SYSCALL), sret, HCCL_IPC_MEM_NAME_LEN, nameLen);
145 0 : return HCCL_E_SYSCALL;
146 : }
147 0 : setNameMap_.insert(std::make_pair(ipcMemInfo, memName)); // 记录mem name
148 0 : } else {
149 0 : SecIpcName_t memName = iter->second;
150 0 : sret = memcpy_s(name, HCCL_IPC_MEM_NAME_LEN, memName.ipcName, nameLen);
151 0 : if (sret != EOK) {
152 0 : HCCL_ERROR(
153 : "[Set][IpcMem]errNo[0x%016llx] In SecIpcName, memcpy_s failed. errorno[%d], params:"
154 : "dest len[%u], src len[%u]",
155 : HCCL_ERROR_CODE(HCCL_E_SYSCALL), sret, HCCL_IPC_MEM_NAME_LEN, nameLen);
156 0 : return HCCL_E_SYSCALL;
157 : }
158 0 : HCCL_INFO("SetIpcMem: name[%s] has opened, skip.", memName.ipcName);
159 0 : }
160 0 : setNameMapRef_[ipcMemInfo].Ref();
161 :
162 0 : return HCCL_SUCCESS;
163 : }
164 :
165 0 : HcclResult MemNameRepository::OpenIpcMem(
166 : void** ptr, u64 size, const u8* name, u32 nameLen, u64 offset, bool& isOpened, bool isSioToHccs)
167 : {
168 0 : CHK_PTR_NULL(name);
169 0 : CHK_PTR_NULL(ptr);
170 :
171 : HcclResult ret;
172 0 : IpcMemInfo ipcMemInfo = {};
173 :
174 0 : std::unique_lock<std::mutex> lock(memMutex_);
175 0 : auto iter = openedNameMap_.begin();
176 0 : while (iter != openedNameMap_.end()) {
177 0 : SecIpcName_t memName = iter->second;
178 0 : if (!strncmp(
179 : reinterpret_cast<char*>(memName.ipcName), reinterpret_cast<char*>(const_cast<u8*>(name)),
180 : HCCL_IPC_MEM_NAME_LEN)) {
181 : // 找到相同ipc 名字,跳出循环
182 0 : *ptr = iter->first.ptr;
183 0 : ipcMemInfo.ptr = *ptr;
184 0 : ipcMemInfo.size = iter->first.size;
185 0 : ipcMemInfo.isSioToHccs = iter->first.isSioToHccs;
186 0 : HCCL_INFO("OpenIpcMem: name[%s] has opened, skip.", memName.ipcName);
187 0 : isOpened = true;
188 0 : break;
189 : } else {
190 0 : iter++;
191 : }
192 0 : }
193 0 : if (iter == openedNameMap_.end()) {
194 : /* 未找到相同IPC name , 调用open memory打开IPC */
195 0 : ret = hrtIpcOpenMemory(ptr, name);
196 0 : CHK_PRT_RET(
197 : ret != HCCL_SUCCESS,
198 : HCCL_ERROR(
199 : "[Open][IpcMem]errNo[0x%016llx] In mem repository, ipc open memory ptr[%p] offset[%llu]"
200 : " name[%s] local pid[%d]",
201 : ret, ptr, offset, name, SalGetPid()),
202 : ret);
203 :
204 0 : SecIpcName_t memName;
205 0 : s32 sret = memcpy_s(memName.ipcName, HCCL_IPC_MEM_NAME_LEN, name, nameLen);
206 0 : if (sret != EOK) {
207 0 : HCCL_ERROR(
208 : "[Open][IpcMem]errNo[0x%016llx] In SecIpcName, memset_s failed. errorno[%d], params:"
209 : "dest len[%u], src len[%u]",
210 : HCCL_ERROR_CODE(HCCL_E_SYSCALL), sret, HCCL_IPC_MEM_NAME_LEN, nameLen);
211 0 : return HCCL_E_SYSCALL;
212 : }
213 0 : ipcMemInfo.ptr = *ptr;
214 0 : ipcMemInfo.size = size;
215 0 : ipcMemInfo.isSioToHccs = isSioToHccs;
216 0 : openedNameMap_.insert(std::make_pair(ipcMemInfo, memName)); // 记录mem name
217 0 : isOpened = false;
218 0 : }
219 0 : openedNameMapRef_[ipcMemInfo].Ref();
220 :
221 0 : HCCL_DEBUG(
222 : "OpenIpcMem: name[%s] ptr[%p] alignPtr[%p] offset[%llu] size[%llu Byte].", name,
223 : (reinterpret_cast<char*>(*ptr) + offset), *ptr, offset, size);
224 :
225 0 : *ptr = reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(*ptr) + offset);
226 :
227 0 : return HCCL_SUCCESS;
228 0 : }
229 :
230 4 : void MemNameRepository::CloseIpcMem(const u8* name)
231 : {
232 : HcclResult ret;
233 4 : std::unique_lock<std::mutex> lock(memMutex_);
234 :
235 4 : if (name == nullptr) {
236 0 : HCCL_WARNING("In mem repository, destroy null ipc ptr");
237 0 : return;
238 : }
239 :
240 4 : if (unavailable_) {
241 0 : ClearMemNameRepositoryImpl();
242 0 : unavailable_ = false;
243 0 : HCCL_RUN_INFO("CloseIpMem unavailable_[%d]", unavailable_);
244 0 : return;
245 : }
246 :
247 4 : auto iter = openedNameMap_.begin();
248 4 : while (iter != openedNameMap_.end()) {
249 0 : SecIpcName_t memName = iter->second;
250 0 : if (!strncmp(
251 : reinterpret_cast<char*>(memName.ipcName), reinterpret_cast<const char*>(name), HCCL_IPC_MEM_NAME_LEN)) {
252 0 : if (openedNameMapRef_[iter->first].Unref() == 0) {
253 : // 找到相同ipc 名字, 并且引用计数减为0再close
254 0 : ret = hrtIpcDestroyMemoryName(memName.ipcName);
255 0 : if (ret != HCCL_SUCCESS) {
256 0 : HCCL_WARNING("In mem repository, ipc close memory ret[%d] ", ret);
257 : }
258 0 : openedNameMapRef_.erase(iter->first);
259 0 : openedNameMap_.erase(iter);
260 : }
261 0 : break;
262 : } else {
263 0 : iter++;
264 : }
265 0 : }
266 4 : }
267 :
268 17 : void MemNameRepository::DestroyIpcMem(void* ptr, u64 size, bool isSioToHccs)
269 : {
270 : HcclResult ret;
271 17 : std::unique_lock<std::mutex> lock(memMutex_);
272 :
273 17 : if (ptr == nullptr) {
274 8 : HCCL_WARNING("In mem repository, destroy null ipc ptr");
275 8 : return;
276 : }
277 :
278 9 : if (unavailable_) {
279 0 : ClearMemNameRepositoryImpl();
280 0 : unavailable_ = false;
281 0 : HCCL_RUN_INFO("DestoryIpcMem unavailable_[%d]", unavailable_);
282 0 : return;
283 : }
284 :
285 9 : IpcMemInfo ipcMemInfo = {};
286 9 : ipcMemInfo.ptr = ptr;
287 9 : ipcMemInfo.size = size;
288 9 : ipcMemInfo.isSioToHccs = isSioToHccs;
289 :
290 9 : auto it = alignPtrMap_.find(ipcMemInfo);
291 9 : if (it == alignPtrMap_.end()) {
292 9 : HCCL_WARNING("Unapplied Memory ptr");
293 9 : ptr = nullptr;
294 9 : return;
295 : } else {
296 0 : ipcMemInfo = it->second;
297 : }
298 :
299 0 : auto iter = setNameMap_.find(ipcMemInfo);
300 0 : if (iter == setNameMap_.end()) {
301 : // 说明已经销毁该IPC name
302 0 : ptr = nullptr;
303 0 : return;
304 : } else {
305 0 : if (setNameMapRef_[ipcMemInfo].Unref() == 0) {
306 : // 找到相同ipc 名字, 并且引用计数减为0再detroy
307 0 : SecIpcName_t memName = iter->second;
308 0 : ret = hrtIpcDestroyMemoryName(memName.ipcName);
309 0 : if (ret != HCCL_SUCCESS) {
310 0 : HCCL_WARNING("In mem repository, sal destroy ipc memory name ret[%d]", ret);
311 : }
312 0 : setNameMapRef_.erase(ipcMemInfo);
313 0 : setNameMap_.erase(iter);
314 0 : }
315 0 : ptr = nullptr;
316 : }
317 17 : }
318 :
319 156 : void MemNameRepository::ClearMemNameRepositoryImpl()
320 : {
321 156 : setNameMap_.clear();
322 155 : openedNameMap_.clear();
323 154 : setNameMapRef_.clear();
324 156 : openedNameMapRef_.clear();
325 154 : alignPtrMap_.clear();
326 156 : }
327 :
328 156 : void MemNameRepository::ClearMemNameRepository()
329 : {
330 156 : std::unique_lock<std::mutex> lock(memMutex_);
331 156 : ClearMemNameRepositoryImpl();
332 156 : }
333 : } // namespace hccl
|