Skip to content

Commit 7261c2f

Browse files
committed
Merge tag 'amd-drm-fixes-7.0-2026-03-25' of https://gitlab.freedesktop.org/agd5f/linux into drm-fixes
amd-drm-fixes-7.0-2026-03-25: amdgpu: - DSC fix - Module parameter parsing fix - PASID reuse fix - drm_edid leak fix - SMU 13.x fixes - SMU 14.x fix - Fence fix in amdgpu_amdkfd_submit_ib() - LVDS fixes - GPU page fault fix for non-4K pages amdkfd: - Ordering fix in kfd_ioctl_create_process() Signed-off-by: Dave Airlie <[email protected]> From: Alex Deucher <[email protected]> Link: https://patch.msgid.link/[email protected]
2 parents c369299 + 90d239c commit 7261c2f

19 files changed

Lines changed: 192 additions & 60 deletions

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -692,9 +692,9 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev,
692692
goto err_ib_sched;
693693
}
694694

695-
/* Drop the initial kref_init count (see drm_sched_main as example) */
696-
dma_fence_put(f);
697695
ret = dma_fence_wait(f, false);
696+
/* Drop the returned fence reference after the wait completes */
697+
dma_fence_put(f);
698698

699699
err_ib_sched:
700700
amdgpu_job_free(job);

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4207,7 +4207,8 @@ static void amdgpu_device_xgmi_reset_func(struct work_struct *__work)
42074207

42084208
static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev)
42094209
{
4210-
char *input = amdgpu_lockup_timeout;
4210+
char buf[AMDGPU_MAX_TIMEOUT_PARAM_LENGTH];
4211+
char *input = buf;
42114212
char *timeout_setting = NULL;
42124213
int index = 0;
42134214
long timeout;
@@ -4217,9 +4218,17 @@ static int amdgpu_device_get_job_timeout_settings(struct amdgpu_device *adev)
42174218
adev->gfx_timeout = adev->compute_timeout = adev->sdma_timeout =
42184219
adev->video_timeout = msecs_to_jiffies(2000);
42194220

4220-
if (!strnlen(input, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH))
4221+
if (!strnlen(amdgpu_lockup_timeout, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH))
42214222
return 0;
42224223

4224+
/*
4225+
* strsep() destructively modifies its input by replacing delimiters
4226+
* with '\0'. Use a stack copy so the global module parameter buffer
4227+
* remains intact for multi-GPU systems where this function is called
4228+
* once per device.
4229+
*/
4230+
strscpy(buf, amdgpu_lockup_timeout, sizeof(buf));
4231+
42234232
while ((timeout_setting = strsep(&input, ",")) &&
42244233
strnlen(timeout_setting, AMDGPU_MAX_TIMEOUT_PARAM_LENGTH)) {
42254234
ret = kstrtol(timeout_setting, 0, &timeout);

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

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,13 @@
3535
* PASIDs are global address space identifiers that can be shared
3636
* between the GPU, an IOMMU and the driver. VMs on different devices
3737
* may use the same PASID if they share the same address
38-
* space. Therefore PASIDs are allocated using a global IDA. VMs are
39-
* looked up from the PASID per amdgpu_device.
38+
* space. Therefore PASIDs are allocated using IDR cyclic allocator
39+
* (similar to kernel PID allocation) which naturally delays reuse.
40+
* VMs are looked up from the PASID per amdgpu_device.
4041
*/
41-
static DEFINE_IDA(amdgpu_pasid_ida);
42+
43+
static DEFINE_IDR(amdgpu_pasid_idr);
44+
static DEFINE_SPINLOCK(amdgpu_pasid_idr_lock);
4245

4346
/* Helper to free pasid from a fence callback */
4447
struct amdgpu_pasid_cb {
@@ -50,23 +53,24 @@ struct amdgpu_pasid_cb {
5053
* amdgpu_pasid_alloc - Allocate a PASID
5154
* @bits: Maximum width of the PASID in bits, must be at least 1
5255
*
53-
* Allocates a PASID of the given width while keeping smaller PASIDs
54-
* available if possible.
56+
* Uses kernel's IDR cyclic allocator (same as PID allocation).
57+
* Allocates sequentially with automatic wrap-around.
5558
*
5659
* Returns a positive integer on success. Returns %-EINVAL if bits==0.
5760
* Returns %-ENOSPC if no PASID was available. Returns %-ENOMEM on
5861
* memory allocation failure.
5962
*/
6063
int amdgpu_pasid_alloc(unsigned int bits)
6164
{
62-
int pasid = -EINVAL;
65+
int pasid;
6366

64-
for (bits = min(bits, 31U); bits > 0; bits--) {
65-
pasid = ida_alloc_range(&amdgpu_pasid_ida, 1U << (bits - 1),
66-
(1U << bits) - 1, GFP_KERNEL);
67-
if (pasid != -ENOSPC)
68-
break;
69-
}
67+
if (bits == 0)
68+
return -EINVAL;
69+
70+
spin_lock(&amdgpu_pasid_idr_lock);
71+
pasid = idr_alloc_cyclic(&amdgpu_pasid_idr, NULL, 1,
72+
1U << bits, GFP_KERNEL);
73+
spin_unlock(&amdgpu_pasid_idr_lock);
7074

7175
if (pasid >= 0)
7276
trace_amdgpu_pasid_allocated(pasid);
@@ -81,7 +85,10 @@ int amdgpu_pasid_alloc(unsigned int bits)
8185
void amdgpu_pasid_free(u32 pasid)
8286
{
8387
trace_amdgpu_pasid_freed(pasid);
84-
ida_free(&amdgpu_pasid_ida, pasid);
88+
89+
spin_lock(&amdgpu_pasid_idr_lock);
90+
idr_remove(&amdgpu_pasid_idr, pasid);
91+
spin_unlock(&amdgpu_pasid_idr_lock);
8592
}
8693

8794
static void amdgpu_pasid_free_cb(struct dma_fence *fence,
@@ -616,3 +623,15 @@ void amdgpu_vmid_mgr_fini(struct amdgpu_device *adev)
616623
}
617624
}
618625
}
626+
627+
/**
628+
* amdgpu_pasid_mgr_cleanup - cleanup PASID manager
629+
*
630+
* Cleanup the IDR allocator.
631+
*/
632+
void amdgpu_pasid_mgr_cleanup(void)
633+
{
634+
spin_lock(&amdgpu_pasid_idr_lock);
635+
idr_destroy(&amdgpu_pasid_idr);
636+
spin_unlock(&amdgpu_pasid_idr_lock);
637+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ int amdgpu_pasid_alloc(unsigned int bits);
7474
void amdgpu_pasid_free(u32 pasid);
7575
void amdgpu_pasid_free_delayed(struct dma_resv *resv,
7676
u32 pasid);
77+
void amdgpu_pasid_mgr_cleanup(void);
7778

7879
bool amdgpu_vmid_had_gpu_reset(struct amdgpu_device *adev,
7980
struct amdgpu_vmid *id);

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2898,6 +2898,7 @@ void amdgpu_vm_manager_fini(struct amdgpu_device *adev)
28982898
xa_destroy(&adev->vm_manager.pasids);
28992899

29002900
amdgpu_vmid_mgr_fini(adev);
2901+
amdgpu_pasid_mgr_cleanup();
29012902
}
29022903

29032904
/**
@@ -2973,14 +2974,14 @@ bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid,
29732974
if (!root)
29742975
return false;
29752976

2976-
addr /= AMDGPU_GPU_PAGE_SIZE;
2977-
29782977
if (is_compute_context && !svm_range_restore_pages(adev, pasid, vmid,
2979-
node_id, addr, ts, write_fault)) {
2978+
node_id, addr >> PAGE_SHIFT, ts, write_fault)) {
29802979
amdgpu_bo_unref(&root);
29812980
return true;
29822981
}
29832982

2983+
addr /= AMDGPU_GPU_PAGE_SIZE;
2984+
29842985
r = amdgpu_bo_reserve(root, true);
29852986
if (r)
29862987
goto error_unref;

drivers/gpu/drm/amd/amdkfd/kfd_chardev.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3170,11 +3170,11 @@ static int kfd_ioctl_create_process(struct file *filep, struct kfd_process *p, v
31703170
struct kfd_process *process;
31713171
int ret;
31723172

3173-
/* Each FD owns only one kfd_process */
3174-
if (p->context_id != KFD_CONTEXT_ID_PRIMARY)
3173+
if (!filep->private_data || !p)
31753174
return -EINVAL;
31763175

3177-
if (!filep->private_data || !p)
3176+
/* Each FD owns only one kfd_process */
3177+
if (p->context_id != KFD_CONTEXT_ID_PRIMARY)
31783178
return -EINVAL;
31793179

31803180
mutex_lock(&kfd_processes_mutex);

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3909,8 +3909,9 @@ void amdgpu_dm_update_connector_after_detect(
39093909

39103910
aconnector->dc_sink = sink;
39113911
dc_sink_retain(aconnector->dc_sink);
3912+
drm_edid_free(aconnector->drm_edid);
3913+
aconnector->drm_edid = NULL;
39123914
if (sink->dc_edid.length == 0) {
3913-
aconnector->drm_edid = NULL;
39143915
hdmi_cec_unset_edid(aconnector);
39153916
if (aconnector->dc_link->aux_mode) {
39163917
drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux);
@@ -5422,7 +5423,7 @@ static void setup_backlight_device(struct amdgpu_display_manager *dm,
54225423
caps = &dm->backlight_caps[aconnector->bl_idx];
54235424

54245425
/* Only offer ABM property when non-OLED and user didn't turn off by module parameter */
5425-
if (!caps->ext_caps->bits.oled && amdgpu_dm_abm_level < 0)
5426+
if (caps->ext_caps && !caps->ext_caps->bits.oled && amdgpu_dm_abm_level < 0)
54265427
drm_object_attach_property(&aconnector->base.base,
54275428
dm->adev->mode_info.abm_level_property,
54285429
ABM_SYSFS_CONTROL);
@@ -12523,6 +12524,11 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
1252312524
}
1252412525

1252512526
if (dc_resource_is_dsc_encoding_supported(dc)) {
12527+
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
12528+
dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
12529+
dm_new_crtc_state->mode_changed_independent_from_dsc = new_crtc_state->mode_changed;
12530+
}
12531+
1252612532
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
1252712533
if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
1252812534
ret = add_affected_mst_dsc_crtcs(state, crtc);

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,7 @@ struct dm_crtc_state {
984984

985985
bool freesync_vrr_info_changed;
986986

987+
bool mode_changed_independent_from_dsc;
987988
bool dsc_force_changed;
988989
bool vrr_supported;
989990
struct mod_freesync_config freesync_config;

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1744,9 +1744,11 @@ int pre_validate_dsc(struct drm_atomic_state *state,
17441744
int ind = find_crtc_index_in_state_by_stream(state, stream);
17451745

17461746
if (ind >= 0) {
1747+
struct dm_crtc_state *dm_new_crtc_state = to_dm_crtc_state(state->crtcs[ind].new_state);
1748+
17471749
DRM_INFO_ONCE("%s:%d MST_DSC no mode changed for stream 0x%p\n",
17481750
__func__, __LINE__, stream);
1749-
state->crtcs[ind].new_state->mode_changed = 0;
1751+
dm_new_crtc_state->base.mode_changed = dm_new_crtc_state->mode_changed_independent_from_dsc;
17501752
}
17511753
}
17521754
}

drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -650,9 +650,6 @@ static struct link_encoder *dce100_link_encoder_create(
650650
return &enc110->base;
651651
}
652652

653-
if (enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
654-
return NULL;
655-
656653
link_regs_id =
657654
map_transmitter_id_to_phy_instance(enc_init_data->transmitter);
658655

@@ -661,7 +658,8 @@ static struct link_encoder *dce100_link_encoder_create(
661658
&link_enc_feature,
662659
&link_enc_regs[link_regs_id],
663660
&link_enc_aux_regs[enc_init_data->channel - 1],
664-
&link_enc_hpd_regs[enc_init_data->hpd_source]);
661+
enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs) ?
662+
NULL : &link_enc_hpd_regs[enc_init_data->hpd_source]);
665663
return &enc110->base;
666664
}
667665

0 commit comments

Comments
 (0)