From patchwork Sat Nov 7 08:02:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: ankitprasad.r.sharma@intel.com X-Patchwork-Id: 7574951 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C7CD79F36A for ; Sat, 7 Nov 2015 08:21:46 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CD58B20627 for ; Sat, 7 Nov 2015 08:21:45 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id DE16F20691 for ; Sat, 7 Nov 2015 08:21:44 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5947E6E2EB; Sat, 7 Nov 2015 00:21:44 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTP id 6AD556E2D1 for ; Sat, 7 Nov 2015 00:21:42 -0800 (PST) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga102.jf.intel.com with ESMTP; 07 Nov 2015 00:21:42 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,256,1444719600"; d="scan'208";a="595757616" Received: from ankitprasad-desktop.iind.intel.com ([10.223.82.145]) by FMSMGA003.fm.intel.com with ESMTP; 07 Nov 2015 00:21:40 -0800 From: ankitprasad.r.sharma@intel.com To: intel-gfx@lists.freedesktop.org Date: Sat, 7 Nov 2015 13:32:15 +0530 Message-Id: <1446883335-8772-4-git-send-email-ankitprasad.r.sharma@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1446883335-8772-1-git-send-email-ankitprasad.r.sharma@intel.com> References: <1446883335-8772-1-git-send-email-ankitprasad.r.sharma@intel.com> Cc: Ankitprasad Sharma , akash.goel@intel.com Subject: [Intel-gfx] [PATCH 3/3] drm/i915: Use insert_page for pwrite_fast 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=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_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-Virus-Scanned: ClamAV using ClamSMTP From: Ankitprasad Sharma In pwrite_fast, map an object page by page if obj_ggtt_pin fails. First, we try a nonblocking pin for the whole object (since that is fastest if reused), then failing that we try to grab one page in the mappable aperture. It also allows us to handle objects larger than the mappable aperture (e.g. if we need to pwrite with vGPU restricting the aperture to a measely 8MiB or something like that). v2: Pin pages before starting pwrite, Combined duplicate loops (Chris) Signed-off-by: Ankitprasad Sharma --- drivers/gpu/drm/i915/i915_gem.c | 68 ++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bf5ef7a..2556936 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -766,14 +766,26 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_file *file) { struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_mm_node node; ssize_t remain; loff_t offset, page_base; char __user *user_data; - int page_offset, page_length, ret; + int page_offset, page_length, ret, i = 0; + bool pinned = true; ret = i915_gem_obj_ggtt_pin(obj, 0, PIN_MAPPABLE | PIN_NONBLOCK); - if (ret) - goto out; + if (ret) { + pinned = false; + memset(&node, 0, sizeof(node)); + ret = drm_mm_insert_node_in_range_generic(&dev_priv->gtt.base.mm, + &node, 4096, 0, + I915_CACHE_NONE, 0, + dev_priv->gtt.mappable_end, + DRM_MM_SEARCH_DEFAULT, + DRM_MM_CREATE_DEFAULT); + if (ret) + goto out; + } ret = i915_gem_object_set_to_gtt_domain(obj, true); if (ret) @@ -783,26 +795,41 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, if (ret) goto out_unpin; + i915_gem_object_pin_pages(obj); + user_data = to_user_ptr(args->data_ptr); remain = args->size; - offset = i915_gem_obj_ggtt_offset(obj) + args->offset; - intel_fb_obj_invalidate(obj, ORIGIN_GTT); - while (remain > 0) { - /* Operation in this page - * - * page_base = page offset within aperture - * page_offset = offset within page - * page_length = bytes to copy for this page - */ + if (pinned) { + offset = i915_gem_obj_ggtt_offset(obj) + args->offset; + /* page_base = page offset within aperture */ page_base = offset & PAGE_MASK; - page_offset = offset_in_page(offset); + } else { + offset = args->offset; + page_base = node.start; + i = args->offset / PAGE_SIZE; + } + + /* page_offset = offset within page */ + page_offset = offset_in_page(offset); + while (remain > 0) { + /* page_length = bytes to copy for the page */ page_length = remain; if ((page_offset + remain) > PAGE_SIZE) page_length = PAGE_SIZE - page_offset; + if (!pinned) { + wmb(); + dev_priv->gtt.base.insert_page(&dev_priv->gtt.base, + i915_gem_object_get_dma_address(obj, i), + node.start, + I915_CACHE_NONE, + 0); + wmb(); + i++; + } /* If we get a fault while copying data, then (presumably) our * source page isn't available. Return the error and we'll * retry in the slow path. @@ -815,13 +842,24 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, remain -= page_length; user_data += page_length; - offset += page_length; + page_offset = 0; } out_flush: + if (!pinned) { + wmb(); + dev_priv->gtt.base.clear_range(&dev_priv->gtt.base, + node.start, node.size, + true); + } + + i915_gem_object_unpin_pages(obj); intel_fb_obj_flush(obj, false, ORIGIN_GTT); out_unpin: - i915_gem_object_ggtt_unpin(obj); + if (pinned) + i915_gem_object_ggtt_unpin(obj); + else + drm_mm_remove_node(&node); out: return ret; }