[PATCH] drm/kms: Add a module parameter to disable polling

Dave Airlie airlied at redhat.com
Thu Aug 19 15:50:40 PDT 2010


On Thu, 2010-08-12 at 20:57 +0100, Chris Wilson wrote:
> Polling for a VGA device on an old system can be quite expensive,
> causing latencies on the order of 600ms. As we hold the mode mutex for
> this time and also need the same mutex to move the cursor, we trigger a
> user-visible stall.

You should rebase this on -rc1 or above since the stuff in the kernel
changed and we don't use the slow work stuff anymore.

Dave.
> 
> The real solution would involve improving the granulatity of the
> locking and so perhaps performing some of the probing not under the lock
> or some other updates can be done under different locks. Also reducing the
> cost of probing for a non-existent monitor would be worthwhile. However,
> exposing a parameter to disable polling is a simple workaround in the
> meantime.
> 
> In order to accommodate users turning polling on and off at runtime, the
> polling is potentially re-enabled on every probe. This is coupled to
> the user calling xrandr, which seems to be a vaild time to reset the
> polling timeout since the information on the connection has just been
> updated. (The presumption being that all connections are probed in a
> single xrandr pass, which is currently valid.)
> 
> References:
> 
>   Bug 29536 - 2.6.35 causes ~600ms latency every 10s
>   https://bugs.freedesktop.org/show_bug.cgi?id=29536
> 
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Reported-and-tested-by: Bruno Prémont <bonbons at linux-vserver.org>
> ---
>  drivers/gpu/drm/drm_crtc_helper.c |   17 +++++++++++++++--
>  1 files changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
> index a0ab1d1..13ba313 100644
> --- a/drivers/gpu/drm/drm_crtc_helper.c
> +++ b/drivers/gpu/drm/drm_crtc_helper.c
> @@ -34,6 +34,9 @@
>  #include "drm_crtc_helper.h"
>  #include "drm_fb_helper.h"
>  
> +static bool drm_kms_helper_poll = true;
> +module_param_named(poll, drm_kms_helper_poll, bool, 0600);
> +
>  static void drm_mode_validate_flag(struct drm_connector *connector,
>  				   int flags)
>  {
> @@ -99,8 +102,10 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
>  			connector->status = connector_status_disconnected;
>  		if (connector->funcs->force)
>  			connector->funcs->force(connector);
> -	} else
> +	} else {
>  		connector->status = connector->funcs->detect(connector);
> +		drm_helper_hpd_irq_event(dev);
> +	}
>  
>  	if (connector->status == connector_status_disconnected) {
>  		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
> @@ -982,6 +987,9 @@ static void output_poll_execute(struct work_struct *work)
>  	enum drm_connector_status old_status, status;
>  	bool repoll = false, changed = false;
>  
> +	if (!drm_kms_helper_poll)
> +		return;
> +
>  	mutex_lock(&dev->mode_config.mutex);
>  	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
>  
> @@ -1032,6 +1040,9 @@ void drm_kms_helper_poll_enable(struct drm_device *dev)
>  	bool poll = false;
>  	struct drm_connector *connector;
>  
> +	if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
> +		return;
> +
>  	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
>  		if (connector->polled)
>  			poll = true;
> @@ -1061,8 +1072,10 @@ void drm_helper_hpd_irq_event(struct drm_device *dev)
>  {
>  	if (!dev->mode_config.poll_enabled)
>  		return;
> +
>  	/* kill timer and schedule immediate execution, this doesn't block */
>  	cancel_delayed_work(&dev->mode_config.output_poll_work);
> -	queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0);
> +	if (drm_kms_helper_poll)
> +		queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0);
>  }
>  EXPORT_SYMBOL(drm_helper_hpd_irq_event);




More information about the dri-devel mailing list