Line data Source code
1 : /**
2 : * Copyright (c) 2026 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 "topo_addr_info.h"
12 : #include <stdint.h>
13 : #include <stdlib.h>
14 : #include <syslog.h>
15 : #include <sys/stat.h>
16 : #include "hal.h"
17 : #include "topo.h"
18 : #include "topo_addr_info_perf.h"
19 : #include "product_card.h"
20 : #include "product_server.h"
21 : #include "product_pod.h"
22 :
23 : #define MAX_DUMP_FILE_LEN (256)
24 : #define DEFAULT_RANKINFO_FILE_PATH "/etc/hccl_rootinfo.json"
25 : #define DEFAULT_RANKINFO_SIZE (4096)
26 :
27 : typedef int (*GetSizeFuncType)(size_t* size);
28 :
29 : typedef int (*GetRootinfoFuncType)(int npu_id, unsigned int mainboard_id, void* buf, size_t* len);
30 :
31 : typedef struct {
32 : uint32_t mainboard_id;
33 : GetSizeFuncType get_size_func;
34 : } GetSizeFuncTable;
35 :
36 : typedef struct {
37 : uint32_t mainboard_id;
38 : GetRootinfoFuncType get_rootinfo_func;
39 : } GetRootinfoFuncTable;
40 :
41 : static GetSizeFuncTable g_get_size_func_table[] = {
42 : {MAIN_BOARD_ID_CARD_NOMESH, GetCardRankInfoLen},
43 : {MAIN_BOARD_ID_CARD_2PMESH, GetCardRankInfoLen},
44 : {MAIN_BOARD_ID_CARD_4PMESH, GetCardRankInfoLen},
45 : {MAIN_BOARD_ID_SERVER_8PMESH, ServerGetRootinfoLen},
46 : {MAIN_BOARD_ID_SERVER_TYPE1, ServerGetRootinfoLen},
47 : {MAIN_BOARD_ID_SERVER_8PMESH_UBOE, ServerGetRootinfoLen},
48 : {MAIN_BOARD_ID_SERVER_8PMESH_NOSP, ServerGetRootinfoLen},
49 : {MAIN_BOARD_ID_SERVER_8PMESH_NOSP_UBOE, ServerGetRootinfoLen},
50 : {MAIN_BOARD_ID_SERVER_UBX, ServerGetRootinfoLen},
51 : {MAIN_BOARD_ID_POD, PodGetRootinfoLen},
52 : {MAIN_BOARD_ID_POD_2D, PodGetRootinfoLen},
53 : };
54 :
55 : static GetRootinfoFuncTable g_get_rootinfo_func_table[] = {
56 : {MAIN_BOARD_ID_CARD_NOMESH, GetCardRankInfo},
57 : {MAIN_BOARD_ID_CARD_2PMESH, GetCardRankInfo},
58 : {MAIN_BOARD_ID_CARD_4PMESH, GetCardRankInfo},
59 : {MAIN_BOARD_ID_SERVER_8PMESH, ServerGetRootinfo},
60 : {MAIN_BOARD_ID_SERVER_TYPE1, ServerGetRootinfo},
61 : {MAIN_BOARD_ID_SERVER_8PMESH_UBOE, ServerGetRootinfo},
62 : {MAIN_BOARD_ID_SERVER_8PMESH_NOSP, ServerGetRootinfo},
63 : {MAIN_BOARD_ID_SERVER_8PMESH_NOSP_UBOE, ServerGetRootinfo},
64 : {MAIN_BOARD_ID_SERVER_UBX, ServerGetRootinfo},
65 : {MAIN_BOARD_ID_POD, PodGetRootinfo},
66 : {MAIN_BOARD_ID_POD_2D, PodGetRootinfo},
67 : };
68 :
69 3 : int TopoAddrInfoGetSize(int phyId, size_t* size)
70 : {
71 3 : if (size == NULL) {
72 0 : return -1;
73 : }
74 :
75 : struct stat st;
76 3 : if (stat(DEFAULT_RANKINFO_FILE_PATH, &st) == 0) {
77 0 : (*size) = st.st_size;
78 0 : return 0;
79 : }
80 :
81 3 : uint32_t mainboard_id = 0;
82 3 : int ret = hal_get_mainboard_id(phyId, &mainboard_id);
83 3 : if (ret != 0) {
84 0 : return ret;
85 : }
86 :
87 : // 从g_get_size_func_table中查找对应的函数
88 24 : for (size_t i = 0; i < sizeof(g_get_size_func_table) / sizeof(g_get_size_func_table[0]); i++) {
89 23 : if (g_get_size_func_table[i].mainboard_id == mainboard_id) {
90 2 : return g_get_size_func_table[i].get_size_func(size);
91 : }
92 : }
93 1 : (*size) = DEFAULT_RANKINFO_SIZE;
94 1 : return 0;
95 : }
96 :
97 7 : static int PassThroughTopoFilePath(char* filePath, size_t bufSize)
98 : {
99 7 : return GetTopoFilePathFromFile("/etc/hccl_rootinfo.json", filePath, bufSize);
100 : }
101 :
102 : /**
103 : * 获取拓扑文件路径
104 : */
105 7 : int TopoAddrInfoGetTopoFilePath(int phyId, char* filePath, size_t bufSize)
106 : {
107 7 : if (filePath == NULL) {
108 0 : return -1;
109 : }
110 : // 优先从/etc/hccl_rootinfo.json中读取
111 7 : int ret = PassThroughTopoFilePath(filePath, bufSize);
112 7 : if (ret == 0) {
113 0 : return ret;
114 : }
115 7 : uint32_t mainboard_id = 0;
116 7 : ret = hal_get_mainboard_id(phyId, &mainboard_id);
117 7 : if (ret != 0) {
118 7 : return ret;
119 : }
120 : struct dcmi_spod_info spod_info;
121 0 : ret = hal_get_spod_info(phyId, &spod_info);
122 0 : if (ret != 0) {
123 0 : return TopoGetFilePath(mainboard_id, TOPO_TYPE_IGNORE, filePath, bufSize);
124 : }
125 0 : return TopoGetFilePath(mainboard_id, spod_info.super_pod_type, filePath, bufSize);
126 : }
127 :
128 330 : static int PassThrough(char* rankInfo, size_t* bufSize)
129 : {
130 330 : FILE* fp = fopen(DEFAULT_RANKINFO_FILE_PATH, "r");
131 330 : if (fp == NULL) {
132 330 : return -1;
133 : }
134 : struct stat stat;
135 0 : fstat(fileno(fp), &stat);
136 0 : if ((size_t)stat.st_size > (*bufSize)) {
137 0 : fclose(fp);
138 0 : return -1;
139 : }
140 0 : int ret = fread(rankInfo, 1, stat.st_size, fp);
141 0 : if (ret < 0) {
142 0 : fclose(fp);
143 0 : return -1;
144 : }
145 0 : *bufSize = (size_t)stat.st_size;
146 0 : return 0;
147 : }
148 :
149 330 : int TopoAddrInfoGet(int phyId, char* rankInfo, size_t* bufSize)
150 : {
151 330 : TopoLogInit(); /* 懒初始化日志,全部下游共用 */
152 330 : TOPO_PERF_BEGIN(TopoAddrInfoGet);
153 330 : if (rankInfo == NULL || bufSize == NULL) {
154 0 : TOPO_PERF_END(TopoAddrInfoGet);
155 0 : return -1;
156 : }
157 : // 优先读取/etc/hccl_rootinfo.json中内容
158 330 : if (PassThrough(rankInfo, bufSize) == 0) {
159 0 : TOPO_PERF_END(TopoAddrInfoGet);
160 0 : return 0;
161 : }
162 : // 若/etc/hccl_rootinfo.json中无内容,根据mainboard_id生成rootinfo
163 330 : uint32_t mainboard_id = 0;
164 330 : int ret = hal_get_mainboard_id(phyId, &mainboard_id);
165 330 : if (ret != 0) {
166 0 : TOPO_PERF_END(TopoAddrInfoGet);
167 0 : return ret;
168 : }
169 :
170 330 : ret = -1;
171 2008 : for (size_t i = 0; i < sizeof(g_get_rootinfo_func_table) / sizeof(GetRootinfoFuncTable); ++i) {
172 2008 : if (g_get_rootinfo_func_table[i].mainboard_id == mainboard_id) {
173 330 : ret = g_get_rootinfo_func_table[i].get_rootinfo_func(phyId, mainboard_id, rankInfo, bufSize);
174 330 : break;
175 : }
176 : }
177 330 : TOPO_PERF_END(TopoAddrInfoGet);
178 330 : return ret;
179 : }
|