Patch "drm/amdgpu: Avoid overflows/divide-by-zero in latency_watermark calculations." has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
drm/amdgpu: Avoid overflows/divide-by-zero in latency_watermark calculations.
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
e190ed1ea7458e446230de4113cc5d53b8dc4ec8Mon Sep 17 00:00:00 2001
From: Mario Kleiner <[email protected]>
Date: Wed, 29 Mar 2017 22:09:12 +0200
Subject: drm/amdgpu: Avoid overflows/divide-by-zero in latency_watermark calculations.
From: Mario Kleiner <[email protected]>
commit e190ed1ea7458e446230de4113cc5d53b8dc4ec8 upstream.
At dot clocks > approx. 250 Mhz, some of these calcs will overflow and cause miscalculation of latency watermarks, and for some overflows also divide-by-zero driver crash ("divide error: 0000 [#1] PREEMPT SMP" in "dce_v10_0_latency_watermark+0x12d/0x190").
This zero-divide happened, e.g., on AMD Tonga Pro under DCE-10, on a Displayport panel when trying to set a video mode of 2560x1440 at 165 Hz vrefresh with a dot clock of 635.540 Mhz.
Refine calculations to avoid the overflows.
Tested for DCE-10 with R9 380 Tonga + ASUS ROG PG279 panel.
--- drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 19 +++---------------- drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 19 +++---------------- drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 19 +++---------------- drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 19 +++---------------- 4 files changed, 12 insertions(+), 64 deletions(-)
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +3 -16
@@ -1173,23 +1173,10 @@ static u32 dce_v10_0_latency_watermark(s a.full =dfixed_const (available_bandwidth); b.full =dfixed_const (wm->num_heads); a.full =dfixed_div (a, b); + tmp =div_u64 ((u64 ) dmif_size * (u64 ) wm->disp_clk, mc_latency +512 ); + tmp =min (dfixed_trunc (a), tmp); - b.full =dfixed_const (mc_latency +512 ); - c.full =dfixed_const (wm->disp_clk); - b.full =dfixed_div (b, c); - - c.full =dfixed_const (dmif_size); - b.full =dfixed_div (c, b); - - tmp =min (dfixed_trunc (a),dfixed_trunc (b)); - - b.full =dfixed_const (1000 ); - c.full =dfixed_const (wm->disp_clk); - b.full =dfixed_div (c, b); - c.full =dfixed_const (wm->bytes_per_pixel); - b.full =dfixed_mul (b, c); - - lb_fill_bw =min (tmp,dfixed_trunc (b)); + lb_fill_bw =min (tmp, wm->disp_clk * wm->bytes_per_pixel /1000 ); a.full =dfixed_const (max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel); b.full =dfixed_const (1000 );
drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +3 -16
@@ -1140,23 +1140,10 @@ static u32 dce_v11_0_latency_watermark(s a.full =dfixed_const (available_bandwidth); b.full =dfixed_const (wm->num_heads); a.full =dfixed_div (a, b); + tmp =div_u64 ((u64 ) dmif_size * (u64 ) wm->disp_clk, mc_latency +512 ); + tmp =min (dfixed_trunc (a), tmp); - b.full =dfixed_const (mc_latency +512 ); - c.full =dfixed_const (wm->disp_clk); - b.full =dfixed_div (b, c); - - c.full =dfixed_const (dmif_size); - b.full =dfixed_div (c, b); - - tmp =min (dfixed_trunc (a),dfixed_trunc (b)); - - b.full =dfixed_const (1000 ); - c.full =dfixed_const (wm->disp_clk); - b.full =dfixed_div (c, b); - c.full =dfixed_const (wm->bytes_per_pixel); - b.full =dfixed_mul (b, c); - - lb_fill_bw =min (tmp,dfixed_trunc (b)); + lb_fill_bw =min (tmp, wm->disp_clk * wm->bytes_per_pixel /1000 ); a.full =dfixed_const (max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel); b.full =dfixed_const (1000 );
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +3 -16
@@ -932,23 +932,10 @@ static u32 dce_v6_0_latency_watermark(st a.full =dfixed_const (available_bandwidth); b.full =dfixed_const (wm->num_heads); a.full =dfixed_div (a, b); + tmp =div_u64 ((u64 ) dmif_size * (u64 ) wm->disp_clk, mc_latency +512 ); + tmp =min (dfixed_trunc (a), tmp); - b.full =dfixed_const (mc_latency +512 ); - c.full =dfixed_const (wm->disp_clk); - b.full =dfixed_div (b, c); - - c.full =dfixed_const (dmif_size); - b.full =dfixed_div (c, b); - - tmp =min (dfixed_trunc (a),dfixed_trunc (b)); - - b.full =dfixed_const (1000 ); - c.full =dfixed_const (wm->disp_clk); - b.full =dfixed_div (c, b); - c.full =dfixed_const (wm->bytes_per_pixel); - b.full =dfixed_mul (b, c); - - lb_fill_bw =min (tmp,dfixed_trunc (b)); + lb_fill_bw =min (tmp, wm->disp_clk * wm->bytes_per_pixel /1000 ); a.full =dfixed_const (max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel); b.full =dfixed_const (1000 );
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +3 -16
@@ -1094,23 +1094,10 @@ static u32 dce_v8_0_latency_watermark(st a.full =dfixed_const (available_bandwidth); b.full =dfixed_const (wm->num_heads); a.full =dfixed_div (a, b); + tmp =div_u64 ((u64 ) dmif_size * (u64 ) wm->disp_clk, mc_latency +512 ); + tmp =min (dfixed_trunc (a), tmp); - b.full =dfixed_const (mc_latency +512 ); - c.full =dfixed_const (wm->disp_clk); - b.full =dfixed_div (b, c); - - c.full =dfixed_const (dmif_size); - b.full =dfixed_div (c, b); - - tmp =min (dfixed_trunc (a),dfixed_trunc (b)); - - b.full =dfixed_const (1000 ); - c.full =dfixed_const (wm->disp_clk); - b.full =dfixed_div (c, b); - c.full =dfixed_const (wm->bytes_per_pixel); - b.full =dfixed_mul (b, c); - - lb_fill_bw =min (tmp,dfixed_trunc (b)); + lb_fill_bw =min (tmp, wm->disp_clk * wm->bytes_per_pixel /1000 ); a.full =dfixed_const (max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel); b.full =dfixed_const (1000 );
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/drm-amdgpu-add-missing-lb_vblank_lead_lines-setup-to-dce-6-path.patch queue-4.9/drm-amdgpu-avoid-overflows-divide-by-zero-in-latency_watermark-calculations.patch queue-4.9/drm-amdgpu-make-display-watermark-calculations-more-accurate.patch