Skip to content

Commit 07c1db7

Browse files
Yang Wangalexdeucher
authored andcommitted
drm/amdgpu: refine smu v13.0.6 mca dump driver
refine smu mca driver to support query ras error from pmfw path. - correct gfx smu bank hwid (from mp5 to smu bank) - retire unused callback function in amdgpu_mca_smu_funcs{} - add new mca_bank_set{} structure to collect mca bank - move enum mca_reg_idx into amdgpu_mca.h header - add mca status register field decode macro Signed-off-by: Yang Wang <[email protected]> Reviewed-by: Hawking Zhang <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 0b16957 commit 07c1db7

File tree

3 files changed

+319
-182
lines changed

3 files changed

+319
-182
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c

Lines changed: 158 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,46 @@ int amdgpu_mca_mpio_ras_sw_init(struct amdgpu_device *adev)
143143
return 0;
144144
}
145145

146+
void amdgpu_mca_bank_set_init(struct mca_bank_set *mca_set)
147+
{
148+
if (!mca_set)
149+
return;
150+
151+
memset(mca_set, 0, sizeof(*mca_set));
152+
INIT_LIST_HEAD(&mca_set->list);
153+
}
154+
155+
int amdgpu_mca_bank_set_add_entry(struct mca_bank_set *mca_set, struct mca_bank_entry *entry)
156+
{
157+
struct mca_bank_node *node;
158+
159+
if (!entry)
160+
return -EINVAL;
161+
162+
node = kvzalloc(sizeof(*node), GFP_KERNEL);
163+
if (!node)
164+
return -ENOMEM;
165+
166+
memcpy(&node->entry, entry, sizeof(*entry));
167+
168+
INIT_LIST_HEAD(&node->node);
169+
list_add_tail(&node->node, &mca_set->list);
170+
171+
mca_set->nr_entries++;
172+
173+
return 0;
174+
}
175+
176+
void amdgpu_mca_bank_set_release(struct mca_bank_set *mca_set)
177+
{
178+
struct mca_bank_node *node, *tmp;
179+
180+
list_for_each_entry_safe(node, tmp, &mca_set->list, node) {
181+
list_del(&node->node);
182+
kvfree(node);
183+
}
184+
}
185+
146186
void amdgpu_mca_smu_init_funcs(struct amdgpu_device *adev, const struct amdgpu_mca_smu_funcs *mca_funcs)
147187
{
148188
struct amdgpu_mca *mca = &adev->mca;
@@ -160,6 +200,58 @@ int amdgpu_mca_smu_set_debug_mode(struct amdgpu_device *adev, bool enable)
160200
return -EOPNOTSUPP;
161201
}
162202

203+
static void amdgpu_mca_smu_mca_bank_dump(struct amdgpu_device *adev, int idx, struct mca_bank_entry *entry)
204+
{
205+
int i;
206+
207+
for (i = 0; i < ARRAY_SIZE(entry->regs); i++)
208+
dev_dbg(adev->dev, "mca entry[%02d].regs[%02d]=0x%016llx\n", idx, i, entry->regs[i]);
209+
}
210+
211+
int amdgpu_mca_smu_log_ras_error(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type, struct ras_err_data *err_data)
212+
{
213+
struct amdgpu_smuio_mcm_config_info mcm_info;
214+
struct mca_bank_set mca_set;
215+
struct mca_bank_node *node;
216+
struct mca_bank_entry *entry;
217+
uint32_t count;
218+
int ret, i = 0;
219+
220+
amdgpu_mca_bank_set_init(&mca_set);
221+
222+
ret = amdgpu_mca_smu_get_mca_set(adev, blk, type, &mca_set);
223+
if (ret)
224+
goto out_mca_release;
225+
226+
list_for_each_entry(node, &mca_set.list, node) {
227+
entry = &node->entry;
228+
229+
amdgpu_mca_smu_mca_bank_dump(adev, i++, entry);
230+
231+
count = 0;
232+
ret = amdgpu_mca_smu_parse_mca_error_count(adev, blk, type, entry, &count);
233+
if (ret)
234+
goto out_mca_release;
235+
236+
if (!count)
237+
continue;
238+
239+
mcm_info.socket_id = entry->info.socket_id;
240+
mcm_info.die_id = entry->info.aid;
241+
242+
if (type == AMDGPU_MCA_ERROR_TYPE_UE)
243+
amdgpu_ras_error_statistic_ue_count(err_data, &mcm_info, (uint64_t)count);
244+
else
245+
amdgpu_ras_error_statistic_ce_count(err_data, &mcm_info, (uint64_t)count);
246+
}
247+
248+
out_mca_release:
249+
amdgpu_mca_bank_set_release(&mca_set);
250+
251+
return ret;
252+
}
253+
254+
163255
int amdgpu_mca_smu_get_valid_mca_count(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, uint32_t *count)
164256
{
165257
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
@@ -173,17 +265,77 @@ int amdgpu_mca_smu_get_valid_mca_count(struct amdgpu_device *adev, enum amdgpu_m
173265
return -EOPNOTSUPP;
174266
}
175267

176-
int amdgpu_mca_smu_get_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
177-
enum amdgpu_mca_error_type type, uint32_t *count)
268+
int amdgpu_mca_smu_get_mca_set_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
269+
enum amdgpu_mca_error_type type, uint32_t *total)
178270
{
179271
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
180-
if (!count)
272+
struct mca_bank_set mca_set;
273+
struct mca_bank_node *node;
274+
struct mca_bank_entry *entry;
275+
uint32_t count;
276+
int ret;
277+
278+
if (!total)
181279
return -EINVAL;
182280

183-
if (mca_funcs && mca_funcs->mca_get_error_count)
184-
return mca_funcs->mca_get_error_count(adev, blk, type, count);
281+
if (!mca_funcs)
282+
return -EOPNOTSUPP;
185283

186-
return -EOPNOTSUPP;
284+
if (!mca_funcs->mca_get_ras_mca_set || !mca_funcs->mca_get_valid_mca_count)
285+
return -EOPNOTSUPP;
286+
287+
amdgpu_mca_bank_set_init(&mca_set);
288+
289+
ret = mca_funcs->mca_get_ras_mca_set(adev, blk, type, &mca_set);
290+
if (ret)
291+
goto err_mca_set_release;
292+
293+
*total = 0;
294+
list_for_each_entry(node, &mca_set.list, node) {
295+
entry = &node->entry;
296+
297+
count = 0;
298+
ret = mca_funcs->mca_parse_mca_error_count(adev, blk, type, entry, &count);
299+
if (ret)
300+
goto err_mca_set_release;
301+
302+
*total += count;
303+
}
304+
305+
err_mca_set_release:
306+
amdgpu_mca_bank_set_release(&mca_set);
307+
308+
return ret;
309+
}
310+
311+
int amdgpu_mca_smu_parse_mca_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
312+
enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, uint32_t *count)
313+
{
314+
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
315+
if (!count || !entry)
316+
return -EINVAL;
317+
318+
if (!mca_funcs || !mca_funcs->mca_parse_mca_error_count)
319+
return -EOPNOTSUPP;
320+
321+
322+
return mca_funcs->mca_parse_mca_error_count(adev, blk, type, entry, count);
323+
}
324+
325+
int amdgpu_mca_smu_get_mca_set(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
326+
enum amdgpu_mca_error_type type, struct mca_bank_set *mca_set)
327+
{
328+
const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs;
329+
330+
if (!mca_set)
331+
return -EINVAL;
332+
333+
if (!mca_funcs || !mca_funcs->mca_get_ras_mca_set)
334+
return -EOPNOTSUPP;
335+
336+
WARN_ON(!list_empty(&mca_set->list));
337+
338+
return mca_funcs->mca_get_ras_mca_set(adev, blk, type, mca_set);
187339
}
188340

189341
int amdgpu_mca_smu_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,

drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,27 @@
2525

2626
#define MCA_MAX_REGS_COUNT (16)
2727

28+
#define MCA_REG_FIELD(x, h, l) (((x) & GENMASK_ULL(h, l)) >> l)
29+
#define MCA_REG__STATUS__VAL(x) MCA_REG_FIELD(x, 63, 63)
30+
#define MCA_REG__STATUS__OVERFLOW(x) MCA_REG_FIELD(x, 62, 62)
31+
#define MCA_REG__STATUS__UC(x) MCA_REG_FIELD(x, 61, 61)
32+
#define MCA_REG__STATUS__EN(x) MCA_REG_FIELD(x, 60, 60)
33+
#define MCA_REG__STATUS__MISCV(x) MCA_REG_FIELD(x, 59, 59)
34+
#define MCA_REG__STATUS__ADDRV(x) MCA_REG_FIELD(x, 58, 58)
35+
#define MCA_REG__STATUS__PCC(x) MCA_REG_FIELD(x, 57, 57)
36+
#define MCA_REG__STATUS__ERRCOREIDVAL(x) MCA_REG_FIELD(x, 56, 56)
37+
#define MCA_REG__STATUS__TCC(x) MCA_REG_FIELD(x, 55, 55)
38+
#define MCA_REG__STATUS__SYNDV(x) MCA_REG_FIELD(x, 53, 53)
39+
#define MCA_REG__STATUS__CECC(x) MCA_REG_FIELD(x, 46, 46)
40+
#define MCA_REG__STATUS__UECC(x) MCA_REG_FIELD(x, 45, 45)
41+
#define MCA_REG__STATUS__DEFERRED(x) MCA_REG_FIELD(x, 44, 44)
42+
#define MCA_REG__STATUS__POISON(x) MCA_REG_FIELD(x, 43, 43)
43+
#define MCA_REG__STATUS__SCRUB(x) MCA_REG_FIELD(x, 40, 40)
44+
#define MCA_REG__STATUS__ERRCOREID(x) MCA_REG_FIELD(x, 37, 32)
45+
#define MCA_REG__STATUS__ADDRLSB(x) MCA_REG_FIELD(x, 29, 24)
46+
#define MCA_REG__STATUS__ERRORCODEEXT(x) MCA_REG_FIELD(x, 21, 16)
47+
#define MCA_REG__STATUS__ERRORCODE(x) MCA_REG_FIELD(x, 15, 0)
48+
2849
enum amdgpu_mca_ip {
2950
AMDGPU_MCA_IP_UNKNOW = -1,
3051
AMDGPU_MCA_IP_PSP = 0,
@@ -57,6 +78,17 @@ struct amdgpu_mca {
5778
const struct amdgpu_mca_smu_funcs *mca_funcs;
5879
};
5980

81+
enum mca_reg_idx {
82+
MCA_REG_IDX_CONTROL = 0,
83+
MCA_REG_IDX_STATUS = 1,
84+
MCA_REG_IDX_ADDR = 2,
85+
MCA_REG_IDX_MISC0 = 3,
86+
MCA_REG_IDX_CONFIG = 4,
87+
MCA_REG_IDX_IPID = 5,
88+
MCA_REG_IDX_SYND = 6,
89+
MCA_REG_IDX_COUNT = 16,
90+
};
91+
6092
struct mca_bank_info {
6193
int socket_id;
6294
int aid;
@@ -72,18 +104,28 @@ struct mca_bank_entry {
72104
uint64_t regs[MCA_MAX_REGS_COUNT];
73105
};
74106

107+
struct mca_bank_node {
108+
struct mca_bank_entry entry;
109+
struct list_head node;
110+
};
111+
112+
struct mca_bank_set {
113+
int nr_entries;
114+
struct list_head list;
115+
};
116+
75117
struct amdgpu_mca_smu_funcs {
76118
int max_ue_count;
77119
int max_ce_count;
78120
int (*mca_set_debug_mode)(struct amdgpu_device *adev, bool enable);
79-
int (*mca_get_error_count)(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
80-
enum amdgpu_mca_error_type type, uint32_t *count);
121+
int (*mca_get_ras_mca_set)(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type,
122+
struct mca_bank_set *mca_set);
123+
int (*mca_parse_mca_error_count)(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type,
124+
struct mca_bank_entry *entry, uint32_t *count);
81125
int (*mca_get_valid_mca_count)(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,
82126
uint32_t *count);
83127
int (*mca_get_mca_entry)(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,
84128
int idx, struct mca_bank_entry *entry);
85-
int (*mca_get_ras_mca_idx_array)(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
86-
enum amdgpu_mca_error_type type, int *idx_array, int *idx_array_size);
87129
};
88130

89131
void amdgpu_mca_query_correctable_error_count(struct amdgpu_device *adev,
@@ -107,11 +149,22 @@ int amdgpu_mca_mpio_ras_sw_init(struct amdgpu_device *adev);
107149
void amdgpu_mca_smu_init_funcs(struct amdgpu_device *adev, const struct amdgpu_mca_smu_funcs *mca_funcs);
108150
int amdgpu_mca_smu_set_debug_mode(struct amdgpu_device *adev, bool enable);
109151
int amdgpu_mca_smu_get_valid_mca_count(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, uint32_t *count);
152+
int amdgpu_mca_smu_get_mca_set_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
153+
enum amdgpu_mca_error_type type, uint32_t *total);
110154
int amdgpu_mca_smu_get_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
111155
enum amdgpu_mca_error_type type, uint32_t *count);
156+
int amdgpu_mca_smu_parse_mca_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
157+
enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, uint32_t *count);
158+
int amdgpu_mca_smu_get_mca_set(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
159+
enum amdgpu_mca_error_type type, struct mca_bank_set *mca_set);
112160
int amdgpu_mca_smu_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,
113161
int idx, struct mca_bank_entry *entry);
114162

115163
void amdgpu_mca_smu_debugfs_init(struct amdgpu_device *adev, struct dentry *root);
116164

165+
void amdgpu_mca_bank_set_init(struct mca_bank_set *mca_set);
166+
int amdgpu_mca_bank_set_add_entry(struct mca_bank_set *mca_set, struct mca_bank_entry *entry);
167+
void amdgpu_mca_bank_set_release(struct mca_bank_set *mca_set);
168+
int amdgpu_mca_smu_log_ras_error(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type, struct ras_err_data *err_data);
169+
117170
#endif

0 commit comments

Comments
 (0)