From patchwork Tue Apr 5 09:22:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 8748971 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2716EC0553 for ; Tue, 5 Apr 2016 09:22:38 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 00F4C2035D for ; Tue, 5 Apr 2016 09:22:37 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id EF2E120351 for ; Tue, 5 Apr 2016 09:22:35 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 73CB96E17E; Tue, 5 Apr 2016 09:22:35 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-wm0-x244.google.com (mail-wm0-x244.google.com [IPv6:2a00:1450:400c:c09::244]) by gabe.freedesktop.org (Postfix) with ESMTPS id 04BC76E17E for ; Tue, 5 Apr 2016 09:22:34 +0000 (UTC) Received: by mail-wm0-x244.google.com with SMTP id 20so2481987wmh.3 for ; Tue, 05 Apr 2016 02:22:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=a1J4FKUpmHr2pxLfvkATt5diT+LSjnt9EngfWl0tz7o=; b=rA9Hbm4QbUCIRke45YZwk+o/ZrzcYQSvbTA4EI1vX8x0wKVY5+uDObf+Hant8S7Ksp JKP/L3J5MOm3xs7wJaG7Kh3irv7ZVrpRzLh0bE7r2ExR14ciht3R2oaGxkr0WGXUhMj7 mpLarTVjnO6S4q6NvYtUIqMrWY9xWAAVJXrAHp2JW4O+tw+SZtq9BZkPjntmGjyMqwAZ uRUkD9SAm/9KrHhLyUhrBvva6zT8qZfxBHpobdmFrrK05rBIcUGBrbpCILHgo9y74lfC hIf0/evD6+QcodUaUUSqsLnKyzOojwJ+XZv3EFkih5PV9r2sPgDfcm6qQwKkX+U/4iJ1 nIsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=a1J4FKUpmHr2pxLfvkATt5diT+LSjnt9EngfWl0tz7o=; b=KFRyxffimLCDrThctzFpqVIkVTBsprmlakCOieEQSUOykzO6AVDfdc6AcPP2ayKWmN NqCI/M6721p3av+0XXpaMyH2BWbb5iiXwdUMVTN1vGGoqBGiPso1sG00Ol224wTpD1ST OWyA2QTzCPej1FbUSFV7TOJOrFtgc9DY8r+wr7GJ1YMv2Ez41XKLfNz0dMJdr8aIvHp2 Kq94gLN+Z81Sf6F2LIisQMYaO2Y78fkkLWjG6v4Oe04QYcqJk5n6dIoJf7nWPK65LlFa LCVBiPbmHDkCdJs0CPM+PRewfP3NuGAAg2uGfXlhIRUAMj/YbqiejFlJ+gntuhuv/BOU Y3rw== X-Gm-Message-State: AD7BkJLhN96ELezUetttUR3pjrG1CPyXviFWi/4jMbsqsRFuqbMcffCTnA423i5kb5RieQ== X-Received: by 10.28.23.75 with SMTP id 72mr16712198wmx.50.1459848152714; Tue, 05 Apr 2016 02:22:32 -0700 (PDT) Received: from haswell.alporthouse.com ([78.156.65.138]) by smtp.gmail.com with ESMTPSA id e190sm18508711wma.15.2016.04.05.02.22.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Apr 2016 02:22:31 -0700 (PDT) From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Tue, 5 Apr 2016 10:22:25 +0100 Message-Id: <1459848145-24042-1-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.8.0.rc3 In-Reply-To: <1459844378.5564.12.camel@linux.intel.com> References: <1459844378.5564.12.camel@linux.intel.com> Subject: [Intel-gfx] [PATCH] drm/i915/shrinker: Refactor common uninterruptible locking X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-5.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Both the oom and vmap notifier callbacks have a loop to acquire the struct_mutex and set the device as uninterruptible, within a certain time. Refactor the common code into a pair of functions. Suggested-by: Joonas Lahtinen Signed-off-by: Chris Wilson Cc: Joonas Lahtinen Cc: Tvrtko Ursulin Reviewed-by: Joonas Lahtinen --- drivers/gpu/drm/i915/i915_gem_shrinker.c | 79 +++++++++++++++++--------------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c index be7501afb59e..39943793edcc 100644 --- a/drivers/gpu/drm/i915/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c @@ -289,35 +289,56 @@ i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) return freed; } +struct shrinker_lock_uninterruptible { + bool was_interruptible; + bool unlock; +}; + +static bool +i915_gem_shrinker_lock_uninterruptible(struct drm_i915_private *dev_priv, + struct shrinker_lock_uninterruptible *slu, + int timeout_ms) +{ + unsigned long timeout = msecs_to_jiffies(timeout_ms) + 1; + + while (!i915_gem_shrinker_lock(dev_priv->dev, &slu->unlock)) { + schedule_timeout_killable(1); + if (fatal_signal_pending(current)) + return false; + if (--timeout == 0) { + pr_err("Unable to lock GPU to purge memory.\n"); + return false; + } + } + + slu->was_interruptible = dev_priv->mm.interruptible; + dev_priv->mm.interruptible = false; + return true; +} + +static void +i915_gem_shrinker_unlock_uninterruptible(struct drm_i915_private *dev_priv, + struct shrinker_lock_uninterruptible *slu) +{ + dev_priv->mm.interruptible = slu->was_interruptible; + if (slu->unlock) + mutex_unlock(&dev_priv->dev->struct_mutex); +} + static int i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) { struct drm_i915_private *dev_priv = container_of(nb, struct drm_i915_private, mm.oom_notifier); - struct drm_device *dev = dev_priv->dev; + struct shrinker_lock_uninterruptible slu; struct drm_i915_gem_object *obj; - unsigned long timeout = msecs_to_jiffies(5000) + 1; unsigned long pinned, bound, unbound, freed_pages; - bool was_interruptible; - bool unlock; - while (!i915_gem_shrinker_lock(dev, &unlock) && --timeout) { - schedule_timeout_killable(1); - if (fatal_signal_pending(current)) - return NOTIFY_DONE; - } - if (timeout == 0) { - pr_err("Unable to purge GPU memory due lock contention.\n"); + if (!i915_gem_shrinker_lock_uninterruptible(dev_priv, &slu, 5000)) return NOTIFY_DONE; - } - - was_interruptible = dev_priv->mm.interruptible; - dev_priv->mm.interruptible = false; freed_pages = i915_gem_shrink_all(dev_priv); - dev_priv->mm.interruptible = was_interruptible; - /* Because we may be allocating inside our own driver, we cannot * assert that there are no objects with pinned pages that are not * being pointed to by hardware. @@ -342,8 +363,7 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) bound += obj->base.size; } - if (unlock) - mutex_unlock(&dev->struct_mutex); + i915_gem_shrinker_unlock_uninterruptible(dev_priv, &slu); if (freed_pages || unbound || bound) pr_info("Purging GPU memory, %lu bytes freed, %lu bytes still pinned.\n", @@ -362,30 +382,15 @@ i915_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr { struct drm_i915_private *dev_priv = container_of(nb, struct drm_i915_private, mm.vmap_notifier); - struct drm_device *dev = dev_priv->dev; - unsigned long timeout = msecs_to_jiffies(5000) + 1; + struct shrinker_lock_uninterruptible slu; unsigned long freed_pages; - bool was_interruptible; - bool unlock; - while (!i915_gem_shrinker_lock(dev, &unlock) && --timeout) { - schedule_timeout_killable(1); - if (fatal_signal_pending(current)) - return NOTIFY_DONE; - } - if (timeout == 0) { - pr_err("Unable to purge GPU vmaps due to lock contention.\n"); + if (!i915_gem_shrinker_lock_uninterruptible(dev_priv, &slu, 5000)) return NOTIFY_DONE; - } - - was_interruptible = dev_priv->mm.interruptible; - dev_priv->mm.interruptible = false; freed_pages = i915_gem_shrink_all(dev_priv); - dev_priv->mm.interruptible = was_interruptible; - if (unlock) - mutex_unlock(&dev->struct_mutex); + i915_gem_shrinker_unlock_uninterruptible(dev_priv, &slu); *(unsigned long *)ptr += freed_pages; return NOTIFY_DONE;