From patchwork Fri Jul 25 03:28:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dheeraj Jamwal X-Patchwork-Id: 4708601 Return-Path: X-Original-To: patchwork-ltsi-dev@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4F3289F375 for ; Mon, 11 Aug 2014 18:45:07 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5BE842011E for ; Mon, 11 Aug 2014 18:45:06 +0000 (UTC) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5707D2009C for ; Mon, 11 Aug 2014 18:45:05 +0000 (UTC) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id CA2F1A82; Mon, 11 Aug 2014 18:42:55 +0000 (UTC) X-Original-To: ltsi-dev@lists.linuxfoundation.org Delivered-To: ltsi-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 35551934 for ; Fri, 25 Jul 2014 03:25:59 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id 60E221FB59 for ; Fri, 25 Jul 2014 03:25:58 +0000 (UTC) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 24 Jul 2014 20:25:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.01,727,1400050800"; d="scan'208";a="566985405" Received: from ubuntu-desktop.png.intel.com ([10.221.122.23]) by fmsmga001.fm.intel.com with ESMTP; 24 Jul 2014 20:25:56 -0700 From: Dheeraj Jamwal To: ltsi-dev@lists.linuxfoundation.org Date: Fri, 25 Jul 2014 11:28:11 +0800 Message-Id: <1406258918-18934-24-git-send-email-dheerajx.s.jamwal@intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1406258918-18934-1-git-send-email-dheerajx.s.jamwal@intel.com> References: <1406258918-18934-1-git-send-email-dheerajx.s.jamwal@intel.com> X-Spam-Status: No, score=-4.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Mailman-Approved-At: Mon, 11 Aug 2014 18:42:51 +0000 Subject: [LTSI-dev] [PATCH 23/50] drm/i915: Disable all GEM timers and work on unload X-BeenThere: ltsi-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: "A list to discuss patches, development, and other things related to the LTSI project" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ltsi-dev-bounces@lists.linuxfoundation.org Errors-To: ltsi-dev-bounces@lists.linuxfoundation.org X-Virus-Scanned: ClamAV using ClamSMTP From: Chris Wilson We have two once very similar functions, i915_gpu_idle() and i915_gem_idle(). The former is used as the lower level operation to flush work on the GPU, whereas the latter is the high level interface to flush the GEM bookkeeping in addition to flushing the GPU. As such i915_gem_idle() also clears out the request and activity lists and cancels the delayed work. This is what we need for unloading the driver, unfortunately we called i915_gpu_idle() instead. In the process, make sure that when cancelling the delayed work and timer, which is synchronous, that we do not hold any locks to prevent a deadlock if the work item is already waiting upon the mutex. This requires us to push the mutex down from the caller to i915_gem_idle(). v2: s/i915_gem_idle/i915_gem_suspend/ Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70334 Signed-off-by: Chris Wilson Tested-by: xunx.fang@intel.com [danvet: Only set ums.suspended for !kms as discussed earlier. Chris noticed that this slipped through.] Signed-off-by: Daniel Vetter (cherry picked from commit 45c5f2022c798b2938d4c0d1c14795787f610ccd) Signed-off-by: Dheeraj Jamwal --- drivers/gpu/drm/i915/i915_dma.c | 8 +------ drivers/gpu/drm/i915/i915_drv.c | 4 +--- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gem.c | 45 +++++++++++++++++---------------------- 4 files changed, 23 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1dd3c09..f59c2b4 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1741,15 +1741,9 @@ int i915_driver_unload(struct drm_device *dev) if (dev_priv->mm.inactive_shrinker.shrink) unregister_shrinker(&dev_priv->mm.inactive_shrinker); - mutex_lock(&dev->struct_mutex); - ret = i915_gpu_idle(dev); + ret = i915_gem_suspend(dev); if (ret) DRM_ERROR("failed to idle hardware: %d\n", ret); - i915_gem_retire_requests(dev); - mutex_unlock(&dev->struct_mutex); - - /* Cancel the retire work handler, which should be idle now. */ - cancel_delayed_work_sync(&dev_priv->mm.retire_work); io_mapping_free(dev_priv->gtt.mappable); arch_phys_wc_del(dev_priv->gtt.mtrr); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index bc83851..c0b2a0f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -487,9 +487,7 @@ static int i915_drm_freeze(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) { int error; - mutex_lock(&dev->struct_mutex); - error = i915_gem_idle(dev); - mutex_unlock(&dev->struct_mutex); + error = i915_gem_suspend(dev); if (error) { dev_err(&dev->pdev->dev, "GEM idle failed, resume might fail\n"); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 388223d..0e9042f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2038,7 +2038,7 @@ int i915_gem_l3_remap(struct intel_ring_buffer *ring, int slice); void i915_gem_init_swizzling(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); int __must_check i915_gpu_idle(struct drm_device *dev); -int __must_check i915_gem_idle(struct drm_device *dev); +int __must_check i915_gem_suspend(struct drm_device *dev); int __i915_add_request(struct intel_ring_buffer *ring, struct drm_file *file, struct drm_i915_gem_object *batch_obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index cf2bafa..dbf5aef 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4266,17 +4266,18 @@ void i915_gem_vma_destroy(struct i915_vma *vma) } int -i915_gem_idle(struct drm_device *dev) +i915_gem_suspend(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; - int ret; + int ret = 0; + mutex_lock(&dev->struct_mutex); if (dev_priv->ums.mm_suspended) - return 0; + goto err; ret = i915_gpu_idle(dev); if (ret) - return ret; + goto err; i915_gem_retire_requests(dev); @@ -4284,16 +4285,26 @@ i915_gem_idle(struct drm_device *dev) if (!drm_core_check_feature(dev, DRIVER_MODESET)) i915_gem_evict_everything(dev); - del_timer_sync(&dev_priv->gpu_error.hangcheck_timer); - i915_kernel_lost_context(dev); i915_gem_cleanup_ringbuffer(dev); - /* Cancel the retire work handler, which should be idle now. */ + /* Hack! Don't let anybody do execbuf while we don't control the chip. + * We need to replace this with a semaphore, or something. + * And not confound ums.mm_suspended! + */ + dev_priv->ums.mm_suspended = !drm_core_check_feature(dev, + DRIVER_MODESET); + mutex_unlock(&dev->struct_mutex); + + del_timer_sync(&dev_priv->gpu_error.hangcheck_timer); cancel_delayed_work_sync(&dev_priv->mm.retire_work); cancel_delayed_work_sync(&dev_priv->mm.idle_work); return 0; + +err: + mutex_unlock(&dev->struct_mutex); + return ret; } int i915_gem_l3_remap(struct intel_ring_buffer *ring, int slice) @@ -4546,26 +4557,12 @@ int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - if (drm_core_check_feature(dev, DRIVER_MODESET)) return 0; drm_irq_uninstall(dev); - mutex_lock(&dev->struct_mutex); - ret = i915_gem_idle(dev); - - /* Hack! Don't let anybody do execbuf while we don't control the chip. - * We need to replace this with a semaphore, or something. - * And not confound ums.mm_suspended! - */ - if (ret != 0) - dev_priv->ums.mm_suspended = 1; - mutex_unlock(&dev->struct_mutex); - - return ret; + return i915_gem_suspend(dev); } void @@ -4576,11 +4573,9 @@ i915_gem_lastclose(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) return; - mutex_lock(&dev->struct_mutex); - ret = i915_gem_idle(dev); + ret = i915_gem_suspend(dev); if (ret) DRM_ERROR("failed to idle hardware: %d\n", ret); - mutex_unlock(&dev->struct_mutex); } static void