From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Lijo Lazar <lijo.lazar@amd.com>,
Alex Deucher <alexander.deucher@amd.com>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 7.1.y 2/2] drm/amdgpu: Allocate coredump ring buffers per ring
Date: Mon, 24 Aug 2026 14:28:07 -0400 [thread overview]
Message-ID: <20260824182807.271396-2-sashal@kernel.org> (raw)
In-Reply-To: <20260824182807.271396-1-sashal@kernel.org>
From: Lijo Lazar <lijo.lazar@amd.com>
[ Upstream commit e40ff9840fa8a633d149f0242df10cae5e518062 ]
Allocate each ring buffer separately. A single allocation summing all
ring sizes can exceed the page allocator's MAX_ORDER limit and fail;
per-ring buffers stay small enough to satisfy. The existing allocation
style doesn't capture any ring data if the huge allocation fails.
Splitting into multiple allocations helps to capture as much data as
possible for the core dump.
A failed ring is left with a NULL buffer and skipped when formatting.
Fixes: eea85914d15b ("drm/amdgpu: save ring content before resetting the device")
Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Assisted-by: Claude Code
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 3e8e92b7892a6377bef86106bfff1b98cf586aee)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c | 50 ++++++++++---------
.../gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h | 3 +-
2 files changed, 27 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
index 5ae9fde80e510..029f678e59b7e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
@@ -339,7 +339,7 @@ amdgpu_devcoredump_format(char *buffer, size_t count, struct amdgpu_coredump_inf
struct amdgpu_ip_block *ip_block;
struct amdgpu_ring *ring;
int ver, i, j;
- u32 ring_idx, off;
+ u32 ring_idx;
bool sizing_pass;
sizing_pass = buffer == NULL;
@@ -439,7 +439,6 @@ amdgpu_devcoredump_format(char *buffer, size_t count, struct amdgpu_coredump_inf
for (i = 0; i < coredump->num_rings; i++) {
ring_idx = coredump->rings[i].ring_index;
ring = coredump->adev->rings[ring_idx];
- off = coredump->rings[i].offset;
drm_printf(&p, "ring name: %s\n", ring->name);
drm_printf(&p, "Rptr: 0x%llx Wptr: 0x%llx RB mask: %x\n",
@@ -448,12 +447,18 @@ amdgpu_devcoredump_format(char *buffer, size_t count, struct amdgpu_coredump_inf
ring->buf_mask);
drm_printf(&p, "Ring size in dwords: %d\n",
ring->ring_size / 4);
+
+ if (!coredump->rings[i].ring_dw) {
+ drm_printf(&p, "Ring contents unavailable\n");
+ continue;
+ }
+
drm_printf(&p, "Ring contents\n");
drm_printf(&p, "Offset \t Value\n");
for (j = 0; j < ring->ring_size; j += 4)
drm_printf(&p, "0x%x \t 0x%x\n", j,
- coredump->rings_dw[off + j / 4]);
+ coredump->rings[i].ring_dw[j / 4]);
}
}
@@ -494,10 +499,12 @@ amdgpu_devcoredump_read(char *buffer, loff_t offset, size_t count,
static void amdgpu_devcoredump_free(void *data)
{
struct amdgpu_coredump_info *coredump = data;
+ u32 i;
kvfree(coredump->formatted);
+ for (i = 0; i < coredump->num_rings; i++)
+ kvfree(coredump->rings[i].ring_dw);
kvfree(coredump->rings);
- kvfree(coredump->rings_dw);
kvfree(data);
}
@@ -539,9 +546,9 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
struct amdgpu_coredump_info *coredump;
size_t size = sizeof(*coredump);
struct drm_sched_job *s_job;
- u64 total_ring_size, ring_count;
+ u64 ring_count;
struct amdgpu_ring *ring;
- int i, off, idx;
+ int i, idx;
/* No need to generate a new coredump if there's one in progress already. */
if (work_busy(&adev->coredump_work))
@@ -581,7 +588,6 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
/* Dump ring content if memory allocation succeeds. */
ring_count = 0;
- total_ring_size = 0;
for (i = 0; i < adev->num_rings; i++) {
ring = adev->rings[i];
@@ -590,38 +596,34 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
coredump->ring != ring)
continue;
- total_ring_size += ring->ring_size;
ring_count++;
}
- if (ring_count) {
- coredump->rings_dw = kvzalloc(total_ring_size, GFP_NOWAIT);
+ if (ring_count)
coredump->rings = kvcalloc(ring_count,
sizeof(struct amdgpu_coredump_ring),
GFP_NOWAIT);
- }
- if (coredump->rings && coredump->rings_dw) {
- for (i = 0, off = 0, idx = 0; i < adev->num_rings && idx < ring_count; i++) {
+ if (coredump->rings) {
+ for (i = 0, idx = 0; i < adev->num_rings && idx < ring_count; i++) {
+ struct amdgpu_coredump_ring *cdump_ring;
+
ring = adev->rings[i];
if (atomic_read(&ring->fence_drv.last_seq) == ring->fence_drv.sync_seq &&
coredump->ring != ring)
continue;
- coredump->rings[idx].ring_index = ring->idx;
- coredump->rings[idx].rptr = amdgpu_ring_get_rptr(ring);
- coredump->rings[idx].wptr = amdgpu_ring_get_wptr(ring);
- coredump->rings[idx].offset = off;
+ cdump_ring = &coredump->rings[idx];
+
+ cdump_ring->ring_dw = kvzalloc(ring->ring_size, GFP_NOWAIT);
+ if (cdump_ring->ring_dw)
+ memcpy(cdump_ring->ring_dw, ring->ring, ring->ring_size);
- memcpy(&coredump->rings_dw[off], ring->ring, ring->ring_size);
- off += ring->ring_size / 4;
+ cdump_ring->ring_index = ring->idx;
+ cdump_ring->rptr = amdgpu_ring_get_rptr(ring);
+ cdump_ring->wptr = amdgpu_ring_get_wptr(ring);
idx++;
}
coredump->num_rings = idx;
- } else {
- kvfree(coredump->rings_dw);
- kvfree(coredump->rings);
- coredump->rings_dw = NULL;
- coredump->rings = NULL;
}
coredump->adev = adev;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h
index 63f27337c09ad..cb874d8c33947 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h
@@ -34,8 +34,8 @@
struct amdgpu_coredump_ring {
u64 rptr;
u64 wptr;
+ u32 *ring_dw;
u32 ring_index;
- u32 offset;
};
struct amdgpu_coredump_ib_info {
@@ -53,7 +53,6 @@ struct amdgpu_coredump_info {
struct amdgpu_ring *ring;
struct amdgpu_coredump_ring *rings;
- u32 *rings_dw;
u32 num_rings;
/* Readable form of coredevdump, generate once to speed up
--
2.53.0
prev parent reply other threads:[~2026-08-24 18:28 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-20 11:05 FAILED: patch "[PATCH] drm/amdgpu: Allocate coredump ring buffers per ring" failed to apply to 7.1-stable tree gregkh
2026-08-24 18:28 ` [PATCH 7.1.y 1/2] drm/amdgpu: fix recursive ww_mutex acquire in amdgpu_devcoredump_format Sasha Levin
2026-08-24 18:28 ` Sasha Levin [this message]
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=20260824182807.271396-2-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=alexander.deucher@amd.com \
--cc=lijo.lazar@amd.com \
--cc=stable@vger.kernel.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