Skip to contentSkip to conversation

FAILED: patch "[PATCH] drm/radeon: Fix overflow of watermark calcs at > 4k" failed to apply to 4.11-stable tree

PATCH [email protected] 2 participants 2 messages Jun 18, 2017

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 4.11-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

Quoted 1 line

From 55f61a040e1b1ea0ba962e53ae341b4c51915bd1 Mon Sep 17 00:00:00 2001

From: Mario Kleiner <[email protected]>
Date: Tue, 13 Jun 2017 07:17:11 +0200
Subject: [PATCH] drm/radeon: Fix overflow of watermark calcs at > 4k
resolutions.

Commit e6b9a6c84b93
("drm/radeon: Make display watermark calculations more accurate") made watermark calculations more accurate, but not for > 4k resolutions on 32-Bit architectures, as it introduced an integer overflow for those setups and resolutions.

Fix this by proper u64 casting and division.

Fixes e6b9a6c84b93 ("drm/radeon: Make display watermark calculations more accurate")
Cc Ben Hutchings <[email protected]>
Cc Alex Deucher <[email protected]>
drivers/gpu/drm/radeon/cik.c +5 -2
index 008c145b7f29..ca44233ceacc 100644
@@ -9267,8 +9267,11 @@ static void dce8_program_watermarks(struct radeon_device *rdev,
 	u32 tmp, wm_mask;
 
 	if (radeon_crtc->base.enabled && num_heads && mode) {
-		active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
-		line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+		active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
+					    (u32)mode->clock);
+		line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
+					  (u32)mode->clock);
+		line_time = min(line_time, (u32)65535);
 
 		/* watermark for high clocks */
 		if ((rdev->pm.pm_method == PM_METHOD_DPM) &&
drivers/gpu/drm/radeon/evergreen.c +5 -2
index 0bf103536404..534637203e70 100644
@@ -2266,8 +2266,11 @@ static void evergreen_program_watermarks(struct radeon_device *rdev,
 	fixed20_12 a, b, c;
 
 	if (radeon_crtc->base.enabled && num_heads && mode) {
-		active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
-		line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+		active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
+					    (u32)mode->clock);
+		line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
+					  (u32)mode->clock);
+		line_time = min(line_time, (u32)65535);
 		priority_a_cnt = 0;
 		priority_b_cnt = 0;
 		dram_channels = evergreen_get_number_of_dram_channels(rdev);
drivers/gpu/drm/radeon/si.c +5 -2
index 76d1888528e6..5303f25d5280 100644
@@ -2284,8 +2284,11 @@ static void dce6_program_watermarks(struct radeon_device *rdev,
 	fixed20_12 a, b, c;
 
 	if (radeon_crtc->base.enabled && num_heads && mode) {
-		active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
-		line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+		active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
+					    (u32)mode->clock);
+		line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
+					  (u32)mode->clock);
+		line_time = min(line_time, (u32)65535);
 		priority_a_cnt = 0;
 		priority_b_cnt = 0;
 
#1 lore raw

The patch fails because the radeon stable-patch it was supposed to improve upon wasn't included into 4.4, 4.9, 4.11, only its amdgpu counterpart. See the "Fixes" reference for the stable patch that is a dependency of this one.

However, looking at this comment from display line buffer setup code "For display widths larger than 4096, you need use to use 2 display controllers and combine them using the stereo blender.", we might not be doing that well for > 4k horizontal resolutions anyway, with or without this patch, as i don't think that is implemented for radeon-kms.

-mario

Quoted 89 lines · On 06/17/2017 07:36 PM, [email protected] wrote:

The patch below does not apply to the 4.11-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 55f61a040e1b1ea0ba962e53ae341b4c51915bd1 Mon Sep 17 00:00:00 2001
From: Mario Kleiner <[email protected]>
Date: Tue, 13 Jun 2017 07:17:11 +0200
Subject: [PATCH] drm/radeon: Fix overflow of watermark calcs at > 4k
resolutions.

Commit e6b9a6c84b93
("drm/radeon: Make display watermark calculations more accurate") made watermark calculations more accurate, but not for > 4k resolutions on 32-Bit architectures, as it introduced an integer overflow for those setups and resolutions.

Fix this by proper u64 casting and division.

Fixes e6b9a6c84b93 ("drm/radeon: Make display watermark calculations more accurate")
Cc Ben Hutchings <[email protected]>
Cc Alex Deucher <[email protected]>
drivers/gpu/drm/radeon/cik.c +5 -2
index 008c145b7f29..ca44233ceacc 100644
@@ -9267,8 +9267,11 @@ static void dce8_program_watermarks(struct radeon_device *rdev,
  	u32 tmp, wm_mask;
 
  	if (radeon_crtc->base.enabled && num_heads && mode) {
-		active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
-		line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+		active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
+					    (u32)mode->clock);
+		line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
+					  (u32)mode->clock);
+		line_time = min(line_time, (u32)65535);
 
  		/* watermark for high clocks */
  		if ((rdev->pm.pm_method == PM_METHOD_DPM) &&
drivers/gpu/drm/radeon/evergreen.c +5 -2
index 0bf103536404..534637203e70 100644
@@ -2266,8 +2266,11 @@ static void evergreen_program_watermarks(struct radeon_device *rdev,
  	fixed20_12 a, b, c;
 
  	if (radeon_crtc->base.enabled && num_heads && mode) {
-		active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
-		line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+		active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
+					    (u32)mode->clock);
+		line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
+					  (u32)mode->clock);
+		line_time = min(line_time, (u32)65535);
  		priority_a_cnt = 0;
  		priority_b_cnt = 0;
  		dram_channels = evergreen_get_number_of_dram_channels(rdev);
drivers/gpu/drm/radeon/si.c +5 -2
index 76d1888528e6..5303f25d5280 100644
@@ -2284,8 +2284,11 @@ static void dce6_program_watermarks(struct radeon_device *rdev,
  	fixed20_12 a, b, c;
 
  	if (radeon_crtc->base.enabled && num_heads && mode) {
-		active_time = 1000000UL * (u32)mode->crtc_hdisplay / (u32)mode->clock;
-		line_time = min((u32) (1000000UL * (u32)mode->crtc_htotal / (u32)mode->clock), (u32)65535);
+		active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
+					    (u32)mode->clock);
+		line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
+					  (u32)mode->clock);
+		line_time = min(line_time, (u32)65535);
  		priority_a_cnt = 0;
  		priority_b_cnt = 0;