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