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 : == 0) {
182 : // 找到相同ipc 名字,跳出循环
183 0 : *ptr = iter->first.ptr;
184 0 : ipcMemInfo.ptr = *ptr;
185 0 : ipcMemInfo.size = iter->first.size;
186 0 : ipcMemInfo.isSioToHccs = iter->first.isSioToHccs;
187 0 : HCCL_INFO("OpenIpcMem: name[%s] has opened, skip.", memName.ipcName);
188 0 : isOpened = true;
189 0 : break;
190 : } else {
191 0 : iter++;
192 : }
193 0 : }
194 0 : if (iter == openedNameMap_.end()) {
195 : /* 未找到相同IPC name , 调用open memory打开IPC */
196 0 : ret = hrtIpcOpenMemory(ptr, name);
197 0 : CHK_PRT_RET(
198 : ret != HCCL_SUCCESS,
199 : HCCL_ERROR(
200 : "[Open][IpcMem]errNo[0x%016llx] In mem repository, ipc open memory ptr[%p] offset[%llu]"
201 : " name[%s] local pid[%d]",
202 : ret, ptr, offset, name, SalGetPid()),
203 : ret);
204 :
205 0 : SecIpcName_t memName;
206 0 : s32 sret = memcpy_s(memName.ipcName, HCCL_IPC_MEM_NAME_LEN, name, nameLen);
207 0 : if (sret != EOK) {
208 0 : HCCL_ERROR(
209 : "[Open][IpcMem]errNo[0x%016llx] In SecIpcName, memset_s failed. errorno[%d], params:"
210 : "dest len[%u], src len[%u]",
211 : HCCL_ERROR_CODE(HCCL_E_SYSCALL), sret, HCCL_IPC_MEM_NAME_LEN, nameLen);
212 0 : return HCCL_E_SYSCALL;
213 : }
214 0 : ipcMemInfo.ptr = *ptr;
215 0 : ipcMemInfo.size = size;
216 0 : ipcMemInfo.isSioToHccs = isSioToHccs;
217 0 : openedNameMap_.insert(std::make_pair(ipcMemInfo, memName)); // 记录mem name
218 0 : isOpened = false;
219 0 : }
220 0 : openedNameMapRef_[ipcMemInfo].Ref();
221 :
222 0 : HCCL_DEBUG(
223 : "OpenIpcMem: name[%s] ptr[%p] alignPtr[%p] offset[%llu] size[%llu Byte].", name,
224 : (reinterpret_cast<char*>(*ptr) + offset), *ptr, offset, size);
225 :
226 0 : *ptr = reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(*ptr) + offset);
227 :
228 0 : return HCCL_SUCCESS;
229 0 : }
230 :
231 4 : void MemNameRepository::CloseIpcMem(const u8* name)
232 : {
233 : HcclResult ret;
234 4 : std::unique_lock<std::mutex> lock(memMutex_);
235 :
236 4 : if (name == nullptr) {
237 0 : HCCL_WARNING("In mem repository, destroy null ipc ptr");
238 0 : return;
239 : }
240 :
241 4 : if (unavailable_) {
242 0 : ClearMemNameRepositoryImpl();
243 0 : unavailable_ = false;
244 0 : HCCL_RUN_INFO("CloseIpMem unavailable_[%d]", unavailable_);
245 0 : return;
246 : }
247 :
248 4 : auto iter = openedNameMap_.begin();
249 4 : while (iter != openedNameMap_.end()) {
250 0 : SecIpcName_t memName = iter->second;
251 0 : if (strncmp(
252 : reinterpret_cast<char*>(memName.ipcName), reinterpret_cast<const char*>(name), HCCL_IPC_MEM_NAME_LEN)
253 : == 0) {
254 0 : if (openedNameMapRef_[iter->first].Unref() == 0) {
255 : // 找到相同ipc 名字, 并且引用计数减为0再close
256 0 : ret = hrtIpcDestroyMemoryName(memName.ipcName);
257 0 : if (ret != HCCL_SUCCESS) {
258 0 : HCCL_WARNING("In mem repository, ipc close memory ret[%d] ", ret);
259 : }
260 0 : openedNameMapRef_.erase(iter->first);
261 0 : openedNameMap_.erase(iter);
262 : }
263 0 : break;
264 : } else {
265 0 : iter++;
266 : }
267 0 : }
268 4 : }
269 :
270 17 : void MemNameRepository::DestroyIpcMem(void* ptr, u64 size, bool isSioToHccs)
271 : {
272 : HcclResult ret;
273 17 : std::unique_lock<std::mutex> lock(memMutex_);
274 :
275 17 : if (ptr == nullptr) {
276 8 : HCCL_WARNING("In mem repository, destroy null ipc ptr");
277 8 : return;
278 : }
279 :
280 9 : if (unavailable_) {
281 0 : ClearMemNameRepositoryImpl();
282 0 : unavailable_ = false;
283 0 : HCCL_RUN_INFO("DestoryIpcMem unavailable_[%d]", unavailable_);
284 0 : return;
285 : }
286 :
287 9 : IpcMemInfo ipcMemInfo = {};
288 9 : ipcMemInfo.ptr = ptr;
289 9 : ipcMemInfo.size = size;
290 9 : ipcMemInfo.isSioToHccs = isSioToHccs;
291 :
292 9 : auto it = alignPtrMap_.find(ipcMemInfo);
293 9 : if (it == alignPtrMap_.end()) {
294 9 : HCCL_WARNING("Unapplied Memory ptr");
295 9 : ptr = nullptr;
296 9 : return;
297 : } else {
298 0 : ipcMemInfo = it->second;
299 : }
300 :
301 0 : auto iter = setNameMap_.find(ipcMemInfo);
302 0 : if (iter == setNameMap_.end()) {
303 : // 说明已经销毁该IPC name
304 0 : ptr = nullptr;
305 0 : return;
306 : } else {
307 0 : if (setNameMapRef_[ipcMemInfo].Unref() == 0) {
308 : // 找到相同ipc 名字, 并且引用计数减为0再detroy
309 0 : SecIpcName_t memName = iter->second;
310 0 : ret = hrtIpcDestroyMemoryName(memName.ipcName);
311 0 : if (ret != HCCL_SUCCESS) {
312 0 : HCCL_WARNING("In mem repository, sal destroy ipc memory name ret[%d]", ret);
313 : }
314 0 : setNameMapRef_.erase(ipcMemInfo);
315 0 : setNameMap_.erase(iter);
316 0 : }
317 0 : ptr = nullptr;
318 : }
319 17 : }
320 :
321 156 : void MemNameRepository::ClearMemNameRepositoryImpl()
322 : {
323 156 : setNameMap_.clear();
324 156 : openedNameMap_.clear();
325 156 : setNameMapRef_.clear();
326 156 : openedNameMapRef_.clear();
327 156 : alignPtrMap_.clear();
328 156 : }
329 :
330 156 : void MemNameRepository::ClearMemNameRepository()
331 : {
332 156 : std::unique_lock<std::mutex> lock(memMutex_);
333 156 : ClearMemNameRepositoryImpl();
334 156 : }
335 : } // namespace hccl
|