From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5C6A0481250; Tue, 25 Aug 2026 13:35:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787664955; cv=none; b=gnwarp74kvrH5e6nPjb9xSGMIYNwdyF8s9yvmln8yOuefTlTBNmL2zegzEutOL/dHk5GZ/7s6rBtH3/A+o1ovVuy325NX5SyQKh3sMCToi/vIo5tGS+xKZBaSiS7FXb/gKxAEVh1K0thEdtseqW8EqF9ydaUQiQrXcuUN4jP+ys= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787664955; c=relaxed/simple; bh=GVgHV1FPA0hVPHVINvncbL13CWDQmu9tglDFryH29A8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FbaghTZ/j+eKE5UgAWJLfl2+DNOxgjoGeY6NMUwakDd1hVnQF6iwkgXgxBlw79UcBT6WSS+Z3u3dRr4IL3SPRGY7WAP7ArOPojEJBWTMHyCoZZ5fsJ381mzQGkdNeJfli9jbCv2gqUqRy4ZX/mTe5iZ4Dfg/BmntzVDiwPDyocw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=OdSAuGGC; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="OdSAuGGC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AFDEE1F000E9; Tue, 25 Aug 2026 13:35:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1787664954; bh=DjHp9mumTT0s/MzVdPzo3KtzLbPKbgmhHtEOiu///rs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=OdSAuGGCCpp954GjpF9WleqwQPiBEJpohgQzFXidLqwxi0dX9UuF0b7cha5c336aq qe9LXRFzJKnhvdqutHHiLA5AwYMW5qwVBsF4pNgB8lgQtW2tT0naSVFBrAHFwvQjTd d9e+6nDZ61K3KytDNkx+OmmWjPn+IspjbOTawqxw= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Lijo Lazar , Alex Deucher , Sasha Levin Subject: [PATCH 7.1 062/101] drm/amdgpu: Allocate coredump ring buffers per ring Date: Tue, 25 Aug 2026 15:25:40 +0200 Message-ID: <20260825132544.426882540@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260825132541.986300899@linuxfoundation.org> References: <20260825132541.986300899@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 7.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Lijo Lazar [ 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 Assisted-by: Claude Code Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher (cherry picked from commit 3e8e92b7892a6377bef86106bfff1b98cf586aee) Cc: stable@vger.kernel.org Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c | 50 +++++++++++------------ drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.h | 3 - 2 files changed, 27 insertions(+), 26 deletions(-) --- 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, 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, 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, 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, lo 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_devic 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_devic /* 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_devic 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]; - memcpy(&coredump->rings_dw[off], ring->ring, ring->ring_size); - off += ring->ring_size / 4; + 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); + + 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; --- 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