From patchwork Tue Jan 12 08:45:42 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhenyu Wang X-Patchwork-Id: 72338 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter.kernel.org (8.14.3/8.14.2) with ESMTP id o0C8jlCI006767 for ; Tue, 12 Jan 2010 08:45:47 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 93DB49EB17; Tue, 12 Jan 2010 00:45:46 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fmsmga101.fm.intel.com (mga05.intel.com [192.55.52.89]) by gabe.freedesktop.org (Postfix) with ESMTP id 0BCB99E829 for ; Tue, 12 Jan 2010 00:45:44 -0800 (PST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 12 Jan 2010 00:45:33 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.49,259,1262592000"; d="asc'?scan'208,223";a="763451177" Received: from zhen-devel.sh.intel.com (HELO zhen-devel) ([10.239.13.159]) by fmsmga001.fm.intel.com with ESMTP; 12 Jan 2010 00:45:44 -0800 Date: Tue, 12 Jan 2010 16:45:42 +0800 From: Zhenyu Wang To: Eric Anholt Message-ID: <20100112084542.GA11945@zhen-devel.sh.intel.com> Mail-Followup-To: Eric Anholt , intel-gfx@lists.freedesktop.org References: <1259125779-20634-1-git-send-email-zhenyuw@linux.intel.com> <1259125779-20634-2-git-send-email-zhenyuw@linux.intel.com> <1259125779-20634-3-git-send-email-zhenyuw@linux.intel.com> MIME-Version: 1.0 In-Reply-To: <1259125779-20634-3-git-send-email-zhenyuw@linux.intel.com> User-Agent: Mutt/1.5.20 (2009-06-14) Cc: intel-gfx@lists.freedesktop.org Subject: Re: [Intel-gfx] [PATCH 3/3] drm/i915: Don't wait interruptible for possible plane buffer flush X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.9 Precedence: list Reply-To: Zhenyu Wang List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Mime-version: 1.0 Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org From 9b1157fcba7c521d39c9b50f21f31a8c38341b5b Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Tue, 24 Nov 2009 14:17:55 +0800 Subject: [PATCH] drm/i915: Don't wait interruptible for possible plane buffer flush When we setup buffer for display plane, we'll check any pending required GPU flush and possible make interruptible wait for flush complete. But that wait would be most possibly to fail in case of signals received for X process, which will then fail modeset process and put display engine in unconsistent state. The result could be blank screen or CPU hang, and DDX driver would always turn on outputs DPMS after whatever modeset fails or not. So this one creates new helper for setup display plane buffer, and when needing flush using uninterruptible wait for that. This one should fix bug like https://bugs.freedesktop.org/show_bug.cgi?id=24009. Also fixing mode switch stress test on Ironlake. Signed-off-by: Zhenyu Wang --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 51 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 2 +- 3 files changed, 53 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a9e571f..bb414c2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -865,6 +865,7 @@ int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptib int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write); +int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj); int i915_gem_attach_phys_object(struct drm_device *dev, struct drm_gem_object *obj, int id); void i915_gem_detach_phys_object(struct drm_device *dev, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0b259bd..d55541c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2837,6 +2837,57 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) return 0; } +/* + * Prepare buffer for display plane. Use uninterruptible for possible flush + * wait, as in modesetting process we're not supposed to be interrupted. + */ +int +i915_gem_object_set_to_display_plane(struct drm_gem_object *obj) +{ + struct drm_device *dev = obj->dev; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + uint32_t old_write_domain, old_read_domains; + int ret; + + /* Not valid to be called on unbound objects. */ + if (obj_priv->gtt_space == NULL) + return -EINVAL; + + i915_gem_object_flush_gpu_write_domain(obj); + + /* Wait on any GPU rendering and flushing to occur. */ + if (obj_priv->active) { +#if WATCH_BUF + DRM_INFO("%s: object %p wait for seqno %08x\n", + __func__, obj, obj_priv->last_rendering_seqno); +#endif + ret = i915_do_wait_request(dev, obj_priv->last_rendering_seqno, 0); + if (ret != 0) + return ret; + } + + old_write_domain = obj->write_domain; + old_read_domains = obj->read_domains; + + obj->read_domains &= I915_GEM_DOMAIN_GTT; + + i915_gem_object_flush_cpu_write_domain(obj); + + /* It should now be out of any other write domains, and we can update + * the domain values for our changes. + */ + BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); + obj->read_domains |= I915_GEM_DOMAIN_GTT; + obj->write_domain = I915_GEM_DOMAIN_GTT; + obj_priv->dirty = 1; + + trace_i915_gem_object_change_domain(obj, + old_read_domains, + old_write_domain); + + return 0; +} + /** * Moves a single object to the CPU read, and possibly write domain. * diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 42e8c03..4b96a54 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1207,7 +1207,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, return ret; } - ret = i915_gem_object_set_to_gtt_domain(obj, 1); + ret = i915_gem_object_set_to_display_plane(obj); if (ret != 0) { i915_gem_object_unpin(obj); mutex_unlock(&dev->struct_mutex); -- 1.6.3.3