Skip to content

Commit 5fb2107

Browse files
committed
Merge tag 'amd-drm-fixes-7.2-2026-08-06' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes
amd-drm-fixes-7.2-2026-08-06: amdgpu: - JPEG queue reset fixes - GC 12 fix - GMC 12.1 fixes - Lockdep false positive fix - Userq fix - Bounds checking fixes - Devcoredump fixes - DCN 2.0.1 fix - Aperture mapping fix - DC avmute fix - DC self refresh fix radeon: - Performance regression fix Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patch.msgid.link/20260806211538.994087-1-alexander.deucher@amd.com
2 parents 0f7f502 + 8099bd0 commit 5fb2107

16 files changed

Lines changed: 216 additions & 64 deletions

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

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,26 @@
4242
#include "amdgpu_ras.h"
4343
#include "amdgpu_hmm.h"
4444

45+
/*
46+
* Maximum IB length (dwords) for rings whose emit_ib packet format
47+
* documents a 20-bit size field.
48+
*/
49+
#define AMDGPU_GFX_SDMA_IB_PACKET_SIZE_MAX_DW 0xFFFFF
50+
#define AMDGPU_MM_IB_PACKET_SIZE_MAX_DW 0x7FFFF0
51+
52+
static u32 amdgpu_cs_ib_packet_size_max_dw(enum amdgpu_ring_type type)
53+
{
54+
switch (type) {
55+
case AMDGPU_RING_TYPE_GFX:
56+
case AMDGPU_RING_TYPE_COMPUTE:
57+
case AMDGPU_RING_TYPE_SDMA:
58+
case AMDGPU_RING_TYPE_VPE:
59+
return AMDGPU_GFX_SDMA_IB_PACKET_SIZE_MAX_DW;
60+
default:
61+
return AMDGPU_MM_IB_PACKET_SIZE_MAX_DW;
62+
}
63+
}
64+
4565
static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p,
4666
struct amdgpu_device *adev,
4767
struct drm_file *filp,
@@ -345,7 +365,6 @@ static int amdgpu_cs_p2_ib(struct amdgpu_cs_parser *p,
345365

346366
job = p->jobs[r];
347367
ring = amdgpu_job_ring(job);
348-
ib = &job->ibs[job->num_ibs++];
349368

350369
/* submissions to kernel queues are disabled */
351370
if (ring->no_user_submission)
@@ -374,6 +393,12 @@ static int amdgpu_cs_p2_ib(struct amdgpu_cs_parser *p,
374393
return -EINVAL;
375394
}
376395

396+
if (chunk_ib->ib_bytes / 4 >
397+
amdgpu_cs_ib_packet_size_max_dw(ring->funcs->type))
398+
return -EINVAL;
399+
400+
ib = &job->ibs[job->num_ibs++];
401+
377402
if (chunk_ib->flags & AMDGPU_IB_FLAG_PREAMBLE)
378403
job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT;
379404

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

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ amdgpu_devcoredump_format(char *buffer, size_t count, struct amdgpu_coredump_inf
342342
struct amdgpu_ip_block *ip_block;
343343
struct amdgpu_ring *ring;
344344
int ver, i, j;
345-
u32 ring_idx, off;
345+
u32 ring_idx;
346346
bool sizing_pass;
347347

348348
sizing_pass = buffer == NULL;
@@ -442,7 +442,6 @@ amdgpu_devcoredump_format(char *buffer, size_t count, struct amdgpu_coredump_inf
442442
for (i = 0; i < coredump->num_rings; i++) {
443443
ring_idx = coredump->rings[i].ring_index;
444444
ring = coredump->adev->rings[ring_idx];
445-
off = coredump->rings[i].offset;
446445

447446
drm_printf(&p, "ring name: %s\n", ring->name);
448447
drm_printf(&p, "Rptr: 0x%llx Wptr: 0x%llx RB mask: %x\n",
@@ -451,12 +450,18 @@ amdgpu_devcoredump_format(char *buffer, size_t count, struct amdgpu_coredump_inf
451450
ring->buf_mask);
452451
drm_printf(&p, "Ring size in dwords: %d\n",
453452
ring->ring_size / 4);
453+
454+
if (!coredump->rings[i].ring_dw) {
455+
drm_printf(&p, "Ring contents unavailable\n");
456+
continue;
457+
}
458+
454459
drm_printf(&p, "Ring contents\n");
455460
drm_printf(&p, "Offset \t Value\n");
456461

457462
for (j = 0; j < ring->ring_size; j += 4)
458463
drm_printf(&p, "0x%x \t 0x%x\n", j,
459-
coredump->rings_dw[off + j / 4]);
464+
coredump->rings[i].ring_dw[j / 4]);
460465
}
461466
}
462467

@@ -497,10 +502,12 @@ amdgpu_devcoredump_read(char *buffer, loff_t offset, size_t count,
497502
static void amdgpu_devcoredump_free(void *data)
498503
{
499504
struct amdgpu_coredump_info *coredump = data;
505+
u32 i;
500506

501507
kvfree(coredump->formatted);
508+
for (i = 0; i < coredump->num_rings; i++)
509+
kvfree(coredump->rings[i].ring_dw);
502510
kvfree(coredump->rings);
503-
kvfree(coredump->rings_dw);
504511
kvfree(data);
505512
}
506513

@@ -542,9 +549,9 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
542549
struct amdgpu_coredump_info *coredump;
543550
size_t size = sizeof(*coredump);
544551
struct drm_sched_job *s_job;
545-
u64 total_ring_size, ring_count;
552+
u64 ring_count;
546553
struct amdgpu_ring *ring;
547-
int i, off, idx;
554+
int i, idx;
548555

549556
/* No need to generate a new coredump if there's one in progress already. */
550557
if (work_busy(&adev->coredump_work))
@@ -553,7 +560,7 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
553560
if (job && job->pasid)
554561
size += sizeof(struct amdgpu_coredump_ib_info) * job->num_ibs;
555562

556-
coredump = kzalloc(size, GFP_NOWAIT);
563+
coredump = kvzalloc(size, GFP_NOWAIT);
557564
if (!coredump)
558565
return;
559566

@@ -584,7 +591,6 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
584591

585592
/* Dump ring content if memory allocation succeeds. */
586593
ring_count = 0;
587-
total_ring_size = 0;
588594
for (i = 0; i < adev->num_rings; i++) {
589595
ring = adev->rings[i];
590596

@@ -593,34 +599,34 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
593599
coredump->ring != ring)
594600
continue;
595601

596-
total_ring_size += ring->ring_size;
597602
ring_count++;
598603
}
599-
coredump->rings_dw = kzalloc(total_ring_size, GFP_NOWAIT);
600-
coredump->rings = kcalloc(ring_count, sizeof(struct amdgpu_coredump_ring), GFP_NOWAIT);
601-
if (coredump->rings && coredump->rings_dw) {
602-
for (i = 0, off = 0, idx = 0; i < adev->num_rings && idx < ring_count; i++) {
604+
if (ring_count)
605+
coredump->rings = kvcalloc(ring_count,
606+
sizeof(struct amdgpu_coredump_ring),
607+
GFP_NOWAIT);
608+
if (coredump->rings) {
609+
for (i = 0, idx = 0; i < adev->num_rings && idx < ring_count; i++) {
610+
struct amdgpu_coredump_ring *cdump_ring;
611+
603612
ring = adev->rings[i];
604613

605614
if (atomic_read(&ring->fence_drv.last_seq) == ring->fence_drv.sync_seq &&
606615
coredump->ring != ring)
607616
continue;
608617

609-
coredump->rings[idx].ring_index = ring->idx;
610-
coredump->rings[idx].rptr = amdgpu_ring_get_rptr(ring);
611-
coredump->rings[idx].wptr = amdgpu_ring_get_wptr(ring);
612-
coredump->rings[idx].offset = off;
618+
cdump_ring = &coredump->rings[idx];
619+
620+
cdump_ring->ring_dw = kvzalloc(ring->ring_size, GFP_NOWAIT);
621+
if (cdump_ring->ring_dw)
622+
memcpy(cdump_ring->ring_dw, ring->ring, ring->ring_size);
613623

614-
memcpy(&coredump->rings_dw[off], ring->ring, ring->ring_size);
615-
off += ring->ring_size / 4;
624+
cdump_ring->ring_index = ring->idx;
625+
cdump_ring->rptr = amdgpu_ring_get_rptr(ring);
626+
cdump_ring->wptr = amdgpu_ring_get_wptr(ring);
616627
idx++;
617628
}
618629
coredump->num_rings = idx;
619-
} else {
620-
kvfree(coredump->rings_dw);
621-
kvfree(coredump->rings);
622-
coredump->rings_dw = NULL;
623-
coredump->rings = NULL;
624630
}
625631

626632
coredump->adev = adev;

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
struct amdgpu_coredump_ring {
3535
u64 rptr;
3636
u64 wptr;
37+
u32 *ring_dw;
3738
u32 ring_index;
38-
u32 offset;
3939
};
4040

4141
struct amdgpu_coredump_ib_info {
@@ -53,7 +53,6 @@ struct amdgpu_coredump_info {
5353
struct amdgpu_ring *ring;
5454

5555
struct amdgpu_coredump_ring *rings;
56-
u32 *rings_dw;
5756
u32 num_rings;
5857

5958
/* Readable form of coredevdump, generate once to speed up

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4194,6 +4194,8 @@ static void amdgpu_device_unmap_mmio(struct amdgpu_device *adev)
41944194

41954195
iounmap(adev->rmmio);
41964196
adev->rmmio = NULL;
4197+
if (adev->mman.aper_base_kaddr)
4198+
iounmap(adev->mman.aper_base_kaddr);
41974199
adev->mman.aper_base_kaddr = NULL;
41984200

41994201
/* Memory manager related */

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,21 @@ int amdgpu_lockdep_init(void)
135135
lockdep_set_class(&locks->srbm_mutex, &amdgpu_srbm_lock_key);
136136
lockdep_set_class(&locks->grbm_idx_mutex, &amdgpu_grbm_lock_key);
137137
lockdep_set_class(&locks->mmio_idx_lock, &amdgpu_mmio_lock_key);
138+
139+
/*
140+
* Register fs_reclaim lock class FIRST, before taking any locks.
141+
*
142+
* This acquire/release pair does NOT create a static lockdep edge
143+
* (no locks are held between acquire and release). It only registers
144+
* the fs_reclaim lock class with lockdep.
145+
*
146+
* The actual fs_reclaim -> notifier_lock dependency is established at
147+
* RUNTIME when memory reclaim invokes MMU notifiers:
148+
* fs_reclaim (held by reclaim) -> notifier_lock (acquired in callback)
149+
*/
150+
fs_reclaim_acquire(GFP_KERNEL);
151+
fs_reclaim_release(GFP_KERNEL);
152+
138153
/*
139154
* Take locks in the correct order to train lockdep.
140155
* This establishes the dependency chain.
@@ -154,11 +169,6 @@ int amdgpu_lockdep_init(void)
154169

155170
/* Level 6: Reset control lock */
156171
mutex_lock(&locks->reset_lock);
157-
/*
158-
* Mark potential memory reclaim boundary.
159-
* GPU operations might trigger memory allocation/reclaim.
160-
*/
161-
fs_reclaim_acquire(GFP_KERNEL);
162172

163173
/* Level 7: SRBM register access */
164174
mutex_lock(&locks->srbm_mutex);
@@ -176,7 +186,6 @@ int amdgpu_lockdep_init(void)
176186
spin_unlock_irqrestore(&locks->mmio_idx_lock, flags);
177187
mutex_unlock(&locks->grbm_idx_mutex);
178188
mutex_unlock(&locks->srbm_mutex);
179-
fs_reclaim_release(GFP_KERNEL);
180189

181190
mutex_unlock(&locks->reset_lock);
182191
up_read(&reset_domain->sem);

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

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,23 +2120,17 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
21202120
/* Change the size here instead of the init above so only lpfn is affected */
21212121
amdgpu_ttm_disable_buffer_funcs(adev);
21222122
#ifdef CONFIG_64BIT
2123-
if (adev->gmc.xgmi.connected_to_cpu) {
2124-
void *kaddr = devm_memremap(adev->dev, adev->gmc.aper_base,
2125-
adev->gmc.visible_vram_size,
2126-
MEMREMAP_WB);
2127-
if (IS_ERR(kaddr))
2128-
return PTR_ERR(kaddr);
2129-
adev->mman.aper_base_kaddr = (__force void __iomem *)kaddr;
2130-
} else if (adev->gmc.is_app_apu) {
2123+
#ifdef CONFIG_X86
2124+
if (adev->gmc.xgmi.connected_to_cpu)
2125+
adev->mman.aper_base_kaddr = ioremap_cache(adev->gmc.aper_base,
2126+
adev->gmc.visible_vram_size);
2127+
else if (adev->gmc.is_app_apu)
21312128
DRM_DEBUG_DRIVER(
21322129
"No need to ioremap when real vram size is 0\n");
2133-
} else {
2134-
adev->mman.aper_base_kaddr = devm_ioremap_wc(adev->dev,
2135-
adev->gmc.aper_base,
2136-
adev->gmc.visible_vram_size);
2137-
if (!adev->mman.aper_base_kaddr)
2138-
return -ENOMEM;
2139-
}
2130+
else
2131+
#endif
2132+
adev->mman.aper_base_kaddr = ioremap_wc(adev->gmc.aper_base,
2133+
adev->gmc.visible_vram_size);
21402134
#endif
21412135

21422136
amdgpu_ttm_init_vram_resv_regions(adev);
@@ -2287,7 +2281,10 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev)
22872281
amdgpu_ttm_unmark_vram_reserved(adev, AMDGPU_RESV_FW_VRAM_USAGE);
22882282
amdgpu_ttm_unmark_vram_reserved(adev, AMDGPU_RESV_DRV_VRAM_USAGE);
22892283

2290-
adev->mman.aper_base_kaddr = NULL;
2284+
if (adev->mman.aper_base_kaddr) {
2285+
iounmap(adev->mman.aper_base_kaddr);
2286+
adev->mman.aper_base_kaddr = NULL;
2287+
}
22912288

22922289
if (!adev->gmc.is_app_apu)
22932290
amdgpu_vram_mgr_fini(adev);

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,12 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
700700
if (!adev->userq_halt_for_enforce_isolation ||
701701
((queue->queue_type != AMDGPU_HW_IP_GFX) &&
702702
(queue->queue_type != AMDGPU_HW_IP_COMPUTE))) {
703+
/* Serialize the map against an in-progress GPU reset (MES is
704+
* unresponsive during recovery), matching amdgpu_userq_cleanup().
705+
*/
706+
down_read(&adev->reset_domain->sem);
703707
r = amdgpu_userq_map_helper(queue);
708+
up_read(&adev->reset_domain->sem);
704709
if (r) {
705710
drm_file_err(uq_mgr->file, "Failed to map Queue\n");
706711
mutex_unlock(&uq_mgr->userq_mutex);

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,6 +1823,11 @@ static void gfx_v12_0_constants_init(struct amdgpu_device *adev)
18231823
gfx_v12_0_get_tcc_info(adev);
18241824
adev->gfx.config.pa_sc_tile_steering_override = 0;
18251825

1826+
/* Set whether texture coordinate truncation is conformant. */
1827+
tmp = RREG32_SOC15(GC, 0, regTA_CNTL2);
1828+
adev->gfx.config.ta_cntl2_truncate_coord_mode =
1829+
REG_GET_FIELD(tmp, TA_CNTL2, TRUNCATE_COORD_MODE);
1830+
18261831
/* XXX SH_MEM regs */
18271832
/* where to put LDS, scratch, GPUVM in FSA64 space */
18281833
mutex_lock(&adev->srbm_mutex);

0 commit comments

Comments
 (0)