From 7e0357bef402875425de0296800c34c41842ba82 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Thu, 18 Apr 2024 12:07:27 +0800 Subject: drm/amdgpu: remove unused MCA driver codes - remove unused callback functions. - make part of mca functions static and refine the function order. Signed-off-by: Yang Wang Reviewed-by: Tao Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h index e5bf07ce3451..4d0a0f91c375 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h @@ -122,8 +122,6 @@ struct amdgpu_mca_smu_funcs { int max_ue_count; int max_ce_count; int (*mca_set_debug_mode)(struct amdgpu_device *adev, bool enable); - int (*mca_get_ras_mca_set)(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type, - struct mca_bank_set *mca_set); int (*mca_parse_mca_error_count)(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, uint32_t *count); int (*mca_get_valid_mca_count)(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, @@ -152,23 +150,9 @@ int amdgpu_mca_mpio_ras_sw_init(struct amdgpu_device *adev); void amdgpu_mca_smu_init_funcs(struct amdgpu_device *adev, const struct amdgpu_mca_smu_funcs *mca_funcs); int amdgpu_mca_smu_set_debug_mode(struct amdgpu_device *adev, bool enable); -int amdgpu_mca_smu_get_valid_mca_count(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, uint32_t *count); int amdgpu_mca_smu_get_mca_set_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type, uint32_t *total); -int amdgpu_mca_smu_get_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk, - enum amdgpu_mca_error_type type, uint32_t *count); -int amdgpu_mca_smu_parse_mca_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk, - enum amdgpu_mca_error_type type, struct mca_bank_entry *entry, uint32_t *count); -int amdgpu_mca_smu_get_mca_set(struct amdgpu_device *adev, enum amdgpu_ras_block blk, - enum amdgpu_mca_error_type type, struct mca_bank_set *mca_set); -int amdgpu_mca_smu_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, - int idx, struct mca_bank_entry *entry); - void amdgpu_mca_smu_debugfs_init(struct amdgpu_device *adev, struct dentry *root); - -void amdgpu_mca_bank_set_init(struct mca_bank_set *mca_set); -int amdgpu_mca_bank_set_add_entry(struct mca_bank_set *mca_set, struct mca_bank_entry *entry); -void amdgpu_mca_bank_set_release(struct mca_bank_set *mca_set); 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, struct ras_query_context *qctx); -- cgit v1.2.3 From 76ad30f51aa0d1bd99f12658d4775a86df6e4282 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Thu, 18 Apr 2024 15:46:00 +0800 Subject: drm/amdgpu: add MCA smu cache support v1: because SMU CE valid mca bank will be cleared after reading, this patch adds mca cache at the driver level to ensure that the mca bank is not lost. v2: refine amdgpu_mca_init/fini/reset() function name. v3: add mca_cache.lock support only add CE bank to mca bank cache. Signed-off-by: Yang Wang Reviewed-by: Tao Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c | 95 ++++++++++++++++++++++++++++++++- drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h | 19 +++++-- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 9 ++++ 3 files changed, 116 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c index 859d594c02a5..264f56fd4f66 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c @@ -183,6 +183,29 @@ static int amdgpu_mca_bank_set_add_entry(struct mca_bank_set *mca_set, struct mc return 0; } +static int amdgpu_mca_bank_set_merge(struct mca_bank_set *mca_set, struct mca_bank_set *new) +{ + struct mca_bank_node *node; + + list_for_each_entry(node, &new->list, node) + amdgpu_mca_bank_set_add_entry(mca_set, &node->entry); + + return 0; +} + +static int amdgpu_mca_bank_set_remove_node(struct mca_bank_set *mca_set, struct mca_bank_node *node) +{ + if (!node) + return -EINVAL; + + list_del(&node->node); + kvfree(node); + + mca_set->nr_entries--; + + return 0; +} + static void amdgpu_mca_bank_set_release(struct mca_bank_set *mca_set) { struct mca_bank_node *node, *tmp; @@ -200,6 +223,41 @@ void amdgpu_mca_smu_init_funcs(struct amdgpu_device *adev, const struct amdgpu_m mca->mca_funcs = mca_funcs; } +int amdgpu_mca_init(struct amdgpu_device *adev) +{ + struct amdgpu_mca *mca = &adev->mca; + struct mca_bank_cache *mca_cache; + int i; + + for (i = 0; i < ARRAY_SIZE(mca->mca_caches); i++) { + mca_cache = &mca->mca_caches[i]; + mutex_init(&mca_cache->lock); + amdgpu_mca_bank_set_init(&mca_cache->mca_set); + } + + return 0; +} + +void amdgpu_mca_fini(struct amdgpu_device *adev) +{ + struct amdgpu_mca *mca = &adev->mca; + struct mca_bank_cache *mca_cache; + int i; + + for (i = 0; i < ARRAY_SIZE(mca->mca_caches); i++) { + mca_cache = &mca->mca_caches[i]; + amdgpu_mca_bank_set_release(&mca_cache->mca_set); + mutex_destroy(&mca_cache->lock); + } +} + +int amdgpu_mca_reset(struct amdgpu_device *adev) +{ + amdgpu_mca_fini(adev); + + return amdgpu_mca_init(adev); +} + int amdgpu_mca_smu_set_debug_mode(struct amdgpu_device *adev, bool enable) { const struct amdgpu_mca_smu_funcs *mca_funcs = adev->mca.mca_funcs; @@ -314,7 +372,7 @@ static int amdgpu_mca_dispatch_mca_set(struct amdgpu_device *adev, enum amdgpu_r { struct ras_err_addr err_addr; struct amdgpu_smuio_mcm_config_info mcm_info; - struct mca_bank_node *node; + struct mca_bank_node *node, *tmp; struct mca_bank_entry *entry; uint32_t count; int ret; @@ -325,7 +383,7 @@ static int amdgpu_mca_dispatch_mca_set(struct amdgpu_device *adev, enum amdgpu_r if (!mca_set->nr_entries) return 0; - list_for_each_entry(node, &mca_set->list, node) { + list_for_each_entry_safe(node, tmp, &mca_set->list, node) { entry = &node->entry; count = 0; @@ -359,15 +417,30 @@ static int amdgpu_mca_dispatch_mca_set(struct amdgpu_device *adev, enum amdgpu_r amdgpu_ras_error_statistic_ce_count(err_data, &mcm_info, &err_addr, (uint64_t)count); } + + amdgpu_mca_bank_set_remove_node(mca_set, node); } return 0; } +static int amdgpu_mca_add_mca_set_to_cache(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, struct mca_bank_set *new) +{ + struct mca_bank_cache *mca_cache = &adev->mca.mca_caches[type]; + int ret; + + mutex_lock(&mca_cache->lock); + ret = amdgpu_mca_bank_set_merge(&mca_cache->mca_set, new); + mutex_unlock(&mca_cache->lock); + + return ret; +} + 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, struct ras_query_context *qctx) { struct mca_bank_set mca_set; + struct mca_bank_cache *mca_cache = &adev->mca.mca_caches[type]; int ret; amdgpu_mca_bank_set_init(&mca_set); @@ -377,6 +450,21 @@ int amdgpu_mca_smu_log_ras_error(struct amdgpu_device *adev, enum amdgpu_ras_blo goto out_mca_release; ret = amdgpu_mca_dispatch_mca_set(adev, blk, type, &mca_set, err_data); + if (ret) + goto out_mca_release; + + /* add remain mca bank to mca cache */ + if (mca_set.nr_entries) { + ret = amdgpu_mca_add_mca_set_to_cache(adev, type, &mca_set); + if (ret) + goto out_mca_release; + } + + /* dispatch mca set again if mca cache has valid data */ + mutex_lock(&mca_cache->lock); + if (mca_cache->mca_set.nr_entries) + ret = amdgpu_mca_dispatch_mca_set(adev, blk, type, &mca_cache->mca_set, err_data); + mutex_unlock(&mca_cache->lock); out_mca_release: amdgpu_mca_bank_set_release(&mca_set); @@ -443,6 +531,9 @@ static int mca_dump_show(struct seq_file *m, enum amdgpu_mca_error_type type) list_for_each_entry(node, &mca_set.list, node) mca_dump_entry(m, &node->entry); + /* add mca bank to mca bank cache */ + ret = amdgpu_mca_add_mca_set_to_cache(adev, type, &mca_set); + err_free_mca_set: amdgpu_mca_bank_set_release(&mca_set); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h index 4d0a0f91c375..9b97cfa28e05 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h @@ -77,11 +77,22 @@ struct amdgpu_mca_ras { struct amdgpu_mca_ras_block *ras; }; +struct mca_bank_set { + int nr_entries; + struct list_head list; +}; + +struct mca_bank_cache { + struct mca_bank_set mca_set; + struct mutex lock; +}; + struct amdgpu_mca { struct amdgpu_mca_ras mp0; struct amdgpu_mca_ras mp1; struct amdgpu_mca_ras mpio; const struct amdgpu_mca_smu_funcs *mca_funcs; + struct mca_bank_cache mca_caches[AMDGPU_MCA_ERROR_TYPE_DE]; }; enum mca_reg_idx { @@ -113,11 +124,6 @@ struct mca_bank_node { struct list_head node; }; -struct mca_bank_set { - int nr_entries; - struct list_head list; -}; - struct amdgpu_mca_smu_funcs { int max_ue_count; int max_ce_count; @@ -149,6 +155,9 @@ int amdgpu_mca_mp1_ras_sw_init(struct amdgpu_device *adev); int amdgpu_mca_mpio_ras_sw_init(struct amdgpu_device *adev); void amdgpu_mca_smu_init_funcs(struct amdgpu_device *adev, const struct amdgpu_mca_smu_funcs *mca_funcs); +int amdgpu_mca_init(struct amdgpu_device *adev); +void amdgpu_mca_fini(struct amdgpu_device *adev); +int amdgpu_mca_reset(struct amdgpu_device *adev); int amdgpu_mca_smu_set_debug_mode(struct amdgpu_device *adev, bool enable); int amdgpu_mca_smu_get_mca_set_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk, enum amdgpu_mca_error_type type, uint32_t *total); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 1adc81a55734..0522533c9182 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -3629,6 +3629,13 @@ int amdgpu_ras_late_init(struct amdgpu_device *adev) amdgpu_ras_set_aca_debug_mode(adev, false); } else { + if (amdgpu_in_reset(adev)) + r = amdgpu_mca_reset(adev); + else + r = amdgpu_mca_init(adev); + if (r) + return r; + amdgpu_ras_set_mca_debug_mode(adev, false); } @@ -3701,6 +3708,8 @@ int amdgpu_ras_fini(struct amdgpu_device *adev) if (amdgpu_aca_is_enabled(adev)) amdgpu_aca_fini(adev); + else + amdgpu_mca_fini(adev); WARN(AMDGPU_RAS_GET_FEATURES(con->features), "Feature mask is not cleared"); -- cgit v1.2.3 From 5eccab32c15f1e5cf9651d865fb20012d3563c96 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Tue, 23 Apr 2024 10:14:47 +0800 Subject: drm/amdgpu: avoid dump mca bank log muti times during ras ISR because the ue valid mca count will only be cleared after gpu reset, so only dump mca log on the first time to get mca bank after receive RAS interrupt. Signed-off-by: Yang Wang Reviewed-by: Tao Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c | 27 +++++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h | 1 + 2 files changed, 28 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c index 264f56fd4f66..a111751b9781 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c @@ -229,6 +229,8 @@ int amdgpu_mca_init(struct amdgpu_device *adev) struct mca_bank_cache *mca_cache; int i; + atomic_set(&mca->ue_update_flag, 0); + for (i = 0; i < ARRAY_SIZE(mca->mca_caches); i++) { mca_cache = &mca->mca_caches[i]; mutex_init(&mca_cache->lock); @@ -244,6 +246,8 @@ void amdgpu_mca_fini(struct amdgpu_device *adev) struct mca_bank_cache *mca_cache; int i; + atomic_set(&mca->ue_update_flag, 0); + for (i = 0; i < ARRAY_SIZE(mca->mca_caches); i++) { mca_cache = &mca->mca_caches[i]; amdgpu_mca_bank_set_release(&mca_cache->mca_set); @@ -325,6 +329,26 @@ static int amdgpu_mca_smu_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_ return mca_funcs->mca_get_mca_entry(adev, type, idx, entry); } +static bool amdgpu_mca_bank_should_update(struct amdgpu_device *adev, enum amdgpu_mca_error_type type) +{ + struct amdgpu_mca *mca = &adev->mca; + bool ret = true; + + /* + * Because the UE Valid MCA count will only be cleared after reset, + * in order to avoid repeated counting of the error count, + * the aca bank is only updated once during the gpu recovery stage. + */ + if (type == AMDGPU_MCA_ERROR_TYPE_UE) { + if (amdgpu_ras_intr_triggered()) + ret = atomic_cmpxchg(&mca->ue_update_flag, 0, 1) == 0; + else + atomic_set(&mca->ue_update_flag, 0); + } + + return ret; +} + static int amdgpu_mca_smu_get_mca_set(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, struct mca_bank_set *mca_set, struct ras_query_context *qctx) { @@ -335,6 +359,9 @@ static int amdgpu_mca_smu_get_mca_set(struct amdgpu_device *adev, enum amdgpu_mc if (!mca_set) return -EINVAL; + if (!amdgpu_mca_bank_should_update(adev, type)) + return 0; + ret = amdgpu_mca_smu_get_valid_mca_count(adev, type, &count); if (ret) return ret; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h index 9b97cfa28e05..e80323ff90c1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h @@ -93,6 +93,7 @@ struct amdgpu_mca { struct amdgpu_mca_ras mpio; const struct amdgpu_mca_smu_funcs *mca_funcs; struct mca_bank_cache mca_caches[AMDGPU_MCA_ERROR_TYPE_DE]; + atomic_t ue_update_flag; }; enum mca_reg_idx { -- cgit v1.2.3 From 258ed689bc3163f86204f75df6c23f92b59b3fad Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Fri, 17 May 2024 07:56:24 +0800 Subject: drm/amdgpu: change bank cache lock type to spinlock modify the lock type to 'spinlock' to avoid schedule issue in interrupt context. Signed-off-by: Yang Wang Reviewed-by: Tao Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c | 11 +++++------ drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c index e0fe47c54e75..da40c2d97df8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c @@ -233,7 +233,7 @@ int amdgpu_mca_init(struct amdgpu_device *adev) for (i = 0; i < ARRAY_SIZE(mca->mca_caches); i++) { mca_cache = &mca->mca_caches[i]; - mutex_init(&mca_cache->lock); + spin_lock_init(&mca_cache->lock); amdgpu_mca_bank_set_init(&mca_cache->mca_set); } @@ -251,7 +251,6 @@ void amdgpu_mca_fini(struct amdgpu_device *adev) for (i = 0; i < ARRAY_SIZE(mca->mca_caches); i++) { mca_cache = &mca->mca_caches[i]; amdgpu_mca_bank_set_release(&mca_cache->mca_set); - mutex_destroy(&mca_cache->lock); } } @@ -456,9 +455,9 @@ static int amdgpu_mca_add_mca_set_to_cache(struct amdgpu_device *adev, enum amdg struct mca_bank_cache *mca_cache = &adev->mca.mca_caches[type]; int ret; - mutex_lock(&mca_cache->lock); + spin_lock(&mca_cache->lock); ret = amdgpu_mca_bank_set_merge(&mca_cache->mca_set, new); - mutex_unlock(&mca_cache->lock); + spin_unlock(&mca_cache->lock); return ret; } @@ -488,10 +487,10 @@ int amdgpu_mca_smu_log_ras_error(struct amdgpu_device *adev, enum amdgpu_ras_blo } /* dispatch mca set again if mca cache has valid data */ - mutex_lock(&mca_cache->lock); + spin_lock(&mca_cache->lock); if (mca_cache->mca_set.nr_entries) ret = amdgpu_mca_dispatch_mca_set(adev, blk, type, &mca_cache->mca_set, err_data); - mutex_unlock(&mca_cache->lock); + spin_unlock(&mca_cache->lock); out_mca_release: amdgpu_mca_bank_set_release(&mca_set); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h index e80323ff90c1..c3c184c88dad 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.h @@ -84,7 +84,7 @@ struct mca_bank_set { struct mca_bank_cache { struct mca_bank_set mca_set; - struct mutex lock; + spinlock_t lock; }; struct amdgpu_mca { -- cgit v1.2.3