diff mbox

drm/i915: Add a try limit to avoid infinite loops

Message ID 1376613069-15790-3-git-send-email-james.ausmus@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

James Ausmus Aug. 16, 2013, 12:30 a.m. UTC
From: Chris Wolfe <cwolfe@chromium.org>

Unfortunately some combinations of hardware seem to generate successful
communications on the aux channel, which always report deferred. As a
result native_write can wind up in an infinite loop.

This hack adds a large (~10ms) retry limit to avoid a kernel panic,
while hopefully minimizing the impact on working hardware.

Signed-off-by: cwolfe@chromium.org

BUG=chromium-os:34840
TEST=Manually connect DP to VGA adapter to problem system. Added display
     powers up and works normally, rather than black screen and reboot.

Change-Id: Ib1b0001ca8004e65c9c5e353dbdb5e252fd88438
Reviewed-on: https://gerrit.chromium.org/gerrit/34203
Commit-Ready: Chris Wolfe <cwolfe@chromium.org>
Reviewed-by: Chris Wolfe <cwolfe@chromium.org>
Tested-by: Chris Wolfe <cwolfe@chromium.org>
---
 drivers/gpu/drm/i915/intel_dp.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

Chris Wilson Aug. 16, 2013, 8:12 a.m. UTC | #1
On Thu, Aug 15, 2013 at 05:30:27PM -0700, james.ausmus@intel.com wrote:
> From: Chris Wolfe <cwolfe@chromium.org>
> 
> Unfortunately some combinations of hardware seem to generate successful
> communications on the aux channel, which always report deferred. As a
> result native_write can wind up in an infinite loop.
> 
> This hack adds a large (~10ms) retry limit to avoid a kernel panic,
> while hopefully minimizing the impact on working hardware.
> 
> Signed-off-by: cwolfe@chromium.org
> 
> BUG=chromium-os:34840
> TEST=Manually connect DP to VGA adapter to problem system. Added display
>      powers up and works normally, rather than black screen and reboot.
> 
> Change-Id: Ib1b0001ca8004e65c9c5e353dbdb5e252fd88438
> Reviewed-on: https://gerrit.chromium.org/gerrit/34203
> Commit-Ready: Chris Wolfe <cwolfe@chromium.org>
> Reviewed-by: Chris Wolfe <cwolfe@chromium.org>
> Tested-by: Chris Wolfe <cwolfe@chromium.org>
> ---
>  drivers/gpu/drm/i915/intel_dp.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index e5d16bc..ac7d610 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -491,6 +491,7 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp,
>  	uint8_t	msg[20];
>  	int msg_bytes;
>  	uint8_t	ack;
> +	int try;
>  
>  	intel_dp_check_edp(intel_dp);
>  	if (send_bytes > 16)
> @@ -501,7 +502,7 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp,
>  	msg[3] = send_bytes - 1;
>  	memcpy(&msg[4], send, send_bytes);
>  	msg_bytes = send_bytes + 4;
> -	for (;;) {
> +	for (try = 0; try < 100; try++) {
>  		ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1);
>  		if (ret < 0)
>  			return ret;
> @@ -512,6 +513,10 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp,
>  		else
>  			return -EIO;
>  	}
> +	if (try == 100) {
> +		DRM_ERROR("too many retries, giving up\n");
> +		return -EREMOTEIO;
> +	}

If we break out here, we need to reset the hw somewhere as it will still
have the last command in the out queue.
-Chris
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e5d16bc..ac7d610 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -491,6 +491,7 @@  intel_dp_aux_native_write(struct intel_dp *intel_dp,
 	uint8_t	msg[20];
 	int msg_bytes;
 	uint8_t	ack;
+	int try;
 
 	intel_dp_check_edp(intel_dp);
 	if (send_bytes > 16)
@@ -501,7 +502,7 @@  intel_dp_aux_native_write(struct intel_dp *intel_dp,
 	msg[3] = send_bytes - 1;
 	memcpy(&msg[4], send, send_bytes);
 	msg_bytes = send_bytes + 4;
-	for (;;) {
+	for (try = 0; try < 100; try++) {
 		ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1);
 		if (ret < 0)
 			return ret;
@@ -512,6 +513,10 @@  intel_dp_aux_native_write(struct intel_dp *intel_dp,
 		else
 			return -EIO;
 	}
+	if (try == 100) {
+		DRM_ERROR("too many retries, giving up\n");
+		return -EREMOTEIO;
+	}
 	return send_bytes;
 }