]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/amd/display: fix page fault due to max surface definition mismatch
authorMelissa Wen <mwen@igalia.com>
Tue, 17 Dec 2024 20:45:03 +0000 (17:45 -0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Jan 2025 12:40:51 +0000 (13:40 +0100)
commit 7de8d5c90be9ad9f6575e818a674801db2ada794 upstream.

DC driver is using two different values to define the maximum number of
surfaces: MAX_SURFACES and MAX_SURFACE_NUM. Consolidate MAX_SURFACES as
the unique definition for surface updates across DC.

It fixes page fault faced by Cosmic users on AMD display versions that
support two overlay planes, since the introduction of cursor overlay
mode.

[Nov26 21:33] BUG: unable to handle page fault for address: 0000000051d0f08b
[  +0.000015] #PF: supervisor read access in kernel mode
[  +0.000006] #PF: error_code(0x0000) - not-present page
[  +0.000005] PGD 0 P4D 0
[  +0.000007] Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI
[  +0.000006] CPU: 4 PID: 71 Comm: kworker/u32:6 Not tainted 6.10.0+ #300
[  +0.000006] Hardware name: Valve Jupiter/Jupiter, BIOS F7A0131 01/30/2024
[  +0.000007] Workqueue: events_unbound commit_work [drm_kms_helper]
[  +0.000040] RIP: 0010:copy_stream_update_to_stream.isra.0+0x30d/0x750 [amdgpu]
[  +0.000847] Code: 8b 10 49 89 94 24 f8 00 00 00 48 8b 50 08 49 89 94 24 00 01 00 00 8b 40 10 41 89 84 24 08 01 00 00 49 8b 45 78 48 85 c0 74 0b <0f> b6 00 41 88 84 24 90 64 00 00 49 8b 45 60 48 85 c0 74 3b 48 8b
[  +0.000010] RSP: 0018:ffffc203802f79a0 EFLAGS: 00010206
[  +0.000009] RAX: 0000000051d0f08b RBX: 0000000000000004 RCX: ffff9f964f0a8070
[  +0.000004] RDX: ffff9f9710f90e40 RSI: ffff9f96600c8000 RDI: ffff9f964f000000
[  +0.000004] RBP: ffffc203802f79f8 R08: 0000000000000000 R09: 0000000000000000
[  +0.000005] R10: 0000000000000000 R11: 0000000000000000 R12: ffff9f96600c8000
[  +0.000004] R13: ffff9f9710f90e40 R14: ffff9f964f000000 R15: ffff9f96600c8000
[  +0.000004] FS:  0000000000000000(0000) GS:ffff9f9970000000(0000) knlGS:0000000000000000
[  +0.000005] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  +0.000005] CR2: 0000000051d0f08b CR3: 00000002e6a20000 CR4: 0000000000350ef0
[  +0.000005] Call Trace:
[  +0.000011]  <TASK>
[  +0.000010]  ? __die_body.cold+0x19/0x27
[  +0.000012]  ? page_fault_oops+0x15a/0x2d0
[  +0.000014]  ? exc_page_fault+0x7e/0x180
[  +0.000009]  ? asm_exc_page_fault+0x26/0x30
[  +0.000013]  ? copy_stream_update_to_stream.isra.0+0x30d/0x750 [amdgpu]
[  +0.000739]  ? dc_commit_state_no_check+0xd6c/0xe70 [amdgpu]
[  +0.000470]  update_planes_and_stream_state+0x49b/0x4f0 [amdgpu]
[  +0.000450]  ? srso_return_thunk+0x5/0x5f
[  +0.000009]  ? commit_minimal_transition_state+0x239/0x3d0 [amdgpu]
[  +0.000446]  update_planes_and_stream_v2+0x24a/0x590 [amdgpu]
[  +0.000464]  ? srso_return_thunk+0x5/0x5f
[  +0.000009]  ? sort+0x31/0x50
[  +0.000007]  ? amdgpu_dm_atomic_commit_tail+0x159f/0x3a30 [amdgpu]
[  +0.000508]  ? srso_return_thunk+0x5/0x5f
[  +0.000009]  ? amdgpu_crtc_get_scanout_position+0x28/0x40 [amdgpu]
[  +0.000377]  ? srso_return_thunk+0x5/0x5f
[  +0.000009]  ? drm_crtc_vblank_helper_get_vblank_timestamp_internal+0x160/0x390 [drm]
[  +0.000058]  ? srso_return_thunk+0x5/0x5f
[  +0.000005]  ? dma_fence_default_wait+0x8c/0x260
[  +0.000010]  ? srso_return_thunk+0x5/0x5f
[  +0.000005]  ? wait_for_completion_timeout+0x13b/0x170
[  +0.000006]  ? srso_return_thunk+0x5/0x5f
[  +0.000005]  ? dma_fence_wait_timeout+0x108/0x140
[  +0.000010]  ? commit_tail+0x94/0x130 [drm_kms_helper]
[  +0.000024]  ? process_one_work+0x177/0x330
[  +0.000008]  ? worker_thread+0x266/0x3a0
[  +0.000006]  ? __pfx_worker_thread+0x10/0x10
[  +0.000004]  ? kthread+0xd2/0x100
[  +0.000006]  ? __pfx_kthread+0x10/0x10
[  +0.000006]  ? ret_from_fork+0x34/0x50
[  +0.000004]  ? __pfx_kthread+0x10/0x10
[  +0.000005]  ? ret_from_fork_asm+0x1a/0x30
[  +0.000011]  </TASK>

Fixes: 1b04dcca4fb1 ("drm/amd/display: Introduce overlay cursor mode")
Suggested-by: Leo Li <sunpeng.li@amd.com>
Link: https://gitlab.freedesktop.org/drm/amd/-/issues/3693
Signed-off-by: Melissa Wen <mwen@igalia.com>
Reviewed-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 1c86c81a86c60f9b15d3e3f43af0363cf56063e7)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_state.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dc_stream.h
drivers/gpu/drm/amd/display/dc/dc_types.h
drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c

index 9f570d447c209908720a84aafa797acabfded3a7..6d4ee8fe615c383d07c0609761d0961c4587d6b2 100644 (file)
@@ -4421,7 +4421,7 @@ static bool commit_minimal_transition_based_on_current_context(struct dc *dc,
        struct pipe_split_policy_backup policy;
        struct dc_state *intermediate_context;
        struct dc_state *old_current_state = dc->current_state;
-       struct dc_surface_update srf_updates[MAX_SURFACE_NUM] = {0};
+       struct dc_surface_update srf_updates[MAX_SURFACES] = {0};
        int surface_count;
 
        /*
index e006f816ff2f743d754a3aa775a8b2660bb6c1d5..1b2cce127981d95491d3466ac9a9170842af8c67 100644 (file)
@@ -483,9 +483,9 @@ bool dc_state_add_plane(
        if (stream_status == NULL) {
                dm_error("Existing stream not found; failed to attach surface!\n");
                goto out;
-       } else if (stream_status->plane_count == MAX_SURFACE_NUM) {
+       } else if (stream_status->plane_count == MAX_SURFACES) {
                dm_error("Surface: can not attach plane_state %p! Maximum is: %d\n",
-                               plane_state, MAX_SURFACE_NUM);
+                               plane_state, MAX_SURFACES);
                goto out;
        } else if (!otg_master_pipe) {
                goto out;
@@ -600,7 +600,7 @@ bool dc_state_rem_all_planes_for_stream(
 {
        int i, old_plane_count;
        struct dc_stream_status *stream_status = NULL;
-       struct dc_plane_state *del_planes[MAX_SURFACE_NUM] = { 0 };
+       struct dc_plane_state *del_planes[MAX_SURFACES] = { 0 };
 
        for (i = 0; i < state->stream_count; i++)
                if (state->streams[i] == stream) {
@@ -875,7 +875,7 @@ bool dc_state_rem_all_phantom_planes_for_stream(
 {
        int i, old_plane_count;
        struct dc_stream_status *stream_status = NULL;
-       struct dc_plane_state *del_planes[MAX_SURFACE_NUM] = { 0 };
+       struct dc_plane_state *del_planes[MAX_SURFACES] = { 0 };
 
        for (i = 0; i < state->stream_count; i++)
                if (state->streams[i] == phantom_stream) {
index 7c163aa7e8bd2d0613291066854fdb2a61ebd390..53835e6cf7ad744ce1f2f4ed7e326f92a6826822 100644 (file)
@@ -1390,7 +1390,7 @@ struct dc_scratch_space {
         * store current value in plane states so we can still recover
         * a valid current state during dc update.
         */
-       struct dc_plane_state plane_states[MAX_SURFACE_NUM];
+       struct dc_plane_state plane_states[MAX_SURFACES];
 
        struct dc_stream_state stream_state;
 };
index 14ea47eda0c87353eee2e32787af804b482e1ad5..8b9af1a6a03162fd47545258b1246312cefbfd26 100644 (file)
@@ -56,7 +56,7 @@ struct dc_stream_status {
        int plane_count;
        int audio_inst;
        struct timing_sync_info timing_sync_info;
-       struct dc_plane_state *plane_states[MAX_SURFACE_NUM];
+       struct dc_plane_state *plane_states[MAX_SURFACES];
        bool is_abm_supported;
        struct mall_stream_config mall_stream_config;
        bool fpo_in_use;
index 6d7989b751e2cecbc8f5cbe837f1ce43a20d94d4..c8bdbbba44ef9da90d670f3478b3ec7524bfe344 100644 (file)
@@ -76,7 +76,6 @@ struct dc_perf_trace {
        unsigned long last_entry_write;
 };
 
-#define MAX_SURFACE_NUM 6
 #define NUM_PIXEL_FORMATS 10
 
 enum tiling_mode {
index 3d29169dd6bbf045000242623107c66e03ae7c5c..6b3b8803e0aee2094e6486554e283aac4149d52e 100644 (file)
@@ -813,7 +813,7 @@ static bool remove_all_phantom_planes_for_stream(struct dml2_context *ctx, struc
 {
        int i, old_plane_count;
        struct dc_stream_status *stream_status = NULL;
-       struct dc_plane_state *del_planes[MAX_SURFACE_NUM] = { 0 };
+       struct dc_plane_state *del_planes[MAX_SURFACES] = { 0 };
 
        for (i = 0; i < context->stream_count; i++)
                        if (context->streams[i] == stream) {