From: Stanley.Yang <Stanley.Yang@amd.com>
To: <amd-gfx@lists.freedesktop.org>
Cc: <Hawking.Zhang@amd.com>, <Tao.Zhou1@amd.com>,
<YiPeng.Chai@amd.com>, <Candice.Li@amd.com>,
Stanley.Yang <Stanley.Yang@amd.com>
Subject: [PATCH 3/5] drm/amd/ras: cap pending_ecc_list size
Date: Mon, 18 May 2026 17:40:19 +0800 [thread overview]
Message-ID: <20260518094021.280968-3-Stanley.Yang@amd.com> (raw)
In-Reply-To: <20260518094021.280968-1-Stanley.Yang@amd.com>
Drop new entries once pending_ecc_count hits RAS_UMC_PENDING_ECC_MAX
(4096) so an ECC storm or repeated UMC error injection cannot exhaust
kernel memory. Dropped events are counted and reported via a
rate-limited warning.
Signed-off-by: Stanley.Yang <Stanley.Yang@amd.com>
---
drivers/gpu/drm/amd/ras/ras_mgr/ras_sys.h | 9 ++++++
drivers/gpu/drm/amd/ras/rascore/ras_umc.c | 35 +++++++++++++++++++++++
drivers/gpu/drm/amd/ras/rascore/ras_umc.h | 12 ++++++++
3 files changed, 56 insertions(+)
diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/ras_sys.h b/drivers/gpu/drm/amd/ras/ras_mgr/ras_sys.h
index 8156531a7b63..f34dda7ce87b 100644
--- a/drivers/gpu/drm/amd/ras/ras_mgr/ras_sys.h
+++ b/drivers/gpu/drm/amd/ras/ras_mgr/ras_sys.h
@@ -46,6 +46,15 @@
printk(KERN_WARNING fmt, ##__VA_ARGS__); \
} while (0)
+#define RAS_DEV_WARN_RATELIMITED(device, fmt, ...) \
+ do { \
+ if (device) \
+ dev_warn_ratelimited(((struct amdgpu_device *)device)->dev, \
+ fmt, ##__VA_ARGS__); \
+ else \
+ printk_ratelimited(KERN_WARNING fmt, ##__VA_ARGS__); \
+ } while (0)
+
#define RAS_DEV_INFO(device, fmt, ...) \
do { \
if (device) \
diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
index d4072350f48f..e8c13e42c2f8 100644
--- a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
+++ b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c
@@ -193,12 +193,29 @@ static void ras_umc_reserve_eeprom_record(struct ras_core_context *ras_core,
}
/* When gpu reset is ongoing, ecc logging operations will be pended.
+ *
+ * The pending list is bounded by RAS_UMC_PENDING_ECC_MAX so that an ECC
+ * storm or repeated UMC error injection cannot make this list (and the
+ * kernel allocations behind it) grow without bound. Once the limit is
+ * reached, additional events are dropped and counted in
+ * pending_ecc_dropped, with a rate-limited warning emitted.
*/
int ras_umc_log_bad_bank_pending(struct ras_core_context *ras_core, struct ras_bank_ecc *bank)
{
struct ras_umc *ras_umc = &ras_core->ras_umc;
struct ras_bank_ecc_node *ecc_node;
+ mutex_lock(&ras_umc->pending_ecc_lock);
+ if (ras_umc->pending_ecc_count >= RAS_UMC_PENDING_ECC_MAX) {
+ ras_umc->pending_ecc_dropped++;
+ mutex_unlock(&ras_umc->pending_ecc_lock);
+ RAS_DEV_WARN_RATELIMITED(ras_core->dev,
+ "pending ECC list full (%u), dropping bad bank event (total dropped:%u)\n",
+ RAS_UMC_PENDING_ECC_MAX, ras_umc->pending_ecc_dropped);
+ return -ENOSPC;
+ }
+ mutex_unlock(&ras_umc->pending_ecc_lock);
+
ecc_node = kzalloc(sizeof(*ecc_node), GFP_KERNEL);
if (!ecc_node)
return -ENOMEM;
@@ -206,7 +223,15 @@ int ras_umc_log_bad_bank_pending(struct ras_core_context *ras_core, struct ras_b
memcpy(&ecc_node->ecc, bank, sizeof(ecc_node->ecc));
mutex_lock(&ras_umc->pending_ecc_lock);
+ /* re-check under the lock to honor the cap across concurrent callers */
+ if (ras_umc->pending_ecc_count >= RAS_UMC_PENDING_ECC_MAX) {
+ ras_umc->pending_ecc_dropped++;
+ mutex_unlock(&ras_umc->pending_ecc_lock);
+ kfree(ecc_node);
+ return -ENOSPC;
+ }
list_add_tail(&ecc_node->node, &ras_umc->pending_ecc_list);
+ ras_umc->pending_ecc_count++;
mutex_unlock(&ras_umc->pending_ecc_lock);
return 0;
@@ -225,8 +250,16 @@ int ras_umc_log_pending_bad_bank(struct ras_core_context *ras_core)
if (!ras_umc_log_bad_bank(ras_core, &ecc_node->ecc)) {
list_del(&ecc_node->node);
kfree(ecc_node);
+ if (ras_umc->pending_ecc_count)
+ ras_umc->pending_ecc_count--;
}
}
+ if (ras_umc->pending_ecc_dropped) {
+ RAS_DEV_WARN(ras_core->dev,
+ "%u pending ECC bad-bank events were dropped during GPU reset\n",
+ ras_umc->pending_ecc_dropped);
+ ras_umc->pending_ecc_dropped = 0;
+ }
mutex_unlock(&ras_umc->pending_ecc_lock);
return 0;
@@ -611,6 +644,8 @@ int ras_umc_sw_fini(struct ras_core_context *ras_core)
list_del(&ecc_node->node);
kfree(ecc_node);
}
+ ras_umc->pending_ecc_count = 0;
+ ras_umc->pending_ecc_dropped = 0;
mutex_unlock(&ras_umc->pending_ecc_lock);
mutex_destroy(&ras_umc->tree_lock);
diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_umc.h b/drivers/gpu/drm/amd/ras/rascore/ras_umc.h
index 1d3026be509b..237525b46b9b 100644
--- a/drivers/gpu/drm/amd/ras/rascore/ras_umc.h
+++ b/drivers/gpu/drm/amd/ras/rascore/ras_umc.h
@@ -139,8 +139,20 @@ struct ras_umc {
struct mutex pending_ecc_lock;
struct ras_umc_err_data umc_err_data;
struct list_head pending_ecc_list;
+ /* number of entries currently queued on pending_ecc_list */
+ u32 pending_ecc_count;
+ /* number of entries dropped because pending_ecc_list was full */
+ u32 pending_ecc_dropped;
};
+/*
+ * Upper bound on entries that can be queued on pending_ecc_list while a
+ * GPU reset is in progress. Beyond this, new ECC events are dropped to
+ * prevent unbounded kernel memory growth in case of an ECC storm or
+ * malicious/repeated UMC error injection.
+ */
+#define RAS_UMC_PENDING_ECC_MAX 8192
+
int ras_umc_sw_init(struct ras_core_context *ras);
int ras_umc_sw_fini(struct ras_core_context *ras);
int ras_umc_hw_init(struct ras_core_context *ras);
--
2.43.0
next prev parent reply other threads:[~2026-05-18 9:41 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-18 9:40 [PATCH 1/5] drm/amdgpu: fix potential overflow in fs_info.debugfs_name Stanley.Yang
2026-05-18 9:40 ` [PATCH 2/5] drm/amdgpu: init locals in umc_v12_0_convert_error_address Stanley.Yang
2026-05-18 9:40 ` Stanley.Yang [this message]
2026-05-18 9:40 ` [PATCH 4/5] drm/amd/ras: snapshot remote cmd header to fix double-fetch Stanley.Yang
2026-05-18 9:40 ` [PATCH 5/5] drm/amdgpu: harden FRU PIA parsing with bounded helpers Stanley.Yang
2026-05-19 7:00 ` Zhou1, Tao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260518094021.280968-3-Stanley.Yang@amd.com \
--to=stanley.yang@amd.com \
--cc=Candice.Li@amd.com \
--cc=Hawking.Zhang@amd.com \
--cc=Tao.Zhou1@amd.com \
--cc=YiPeng.Chai@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox