From patchwork Wed Aug 17 16:12:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mario Kleiner X-Patchwork-Id: 9286117 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id CC97A60574 for ; Wed, 17 Aug 2016 16:13:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BF5352967C for ; Wed, 17 Aug 2016 16:13:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B42D629682; Wed, 17 Aug 2016 16:13:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 451E22967C for ; Wed, 17 Aug 2016 16:13:35 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A86066E8D5; Wed, 17 Aug 2016 16:13:34 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@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 B11B56E8D5 for ; Wed, 17 Aug 2016 16:13:33 +0000 (UTC) Received: by mail-wm0-x244.google.com with SMTP id i5so25695026wmg.2 for ; Wed, 17 Aug 2016 09:13:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=v+ApHedS4SyH1G1fBgvt7ZaT1fuJ7XcqDUxvysyyXWo=; b=UEY5llWjbVVHIuytA3wCQdQ9Qz/is84dDVmjJ0oJXcPfscWnDFQ/xwsPiZ1m+uLGRh pecRvlM7ZK1MkfpxHOcvnuUUpH4PaY69a4FrMP35TiSPARQUH27C5jvPh1s19Mej5jaW 5UBqKt5TCl2wQUScLFJodIAsVdd+oz/AWXCumY8VrRLiomFQsUCReE5bnlbH4d6zIAjZ 5wsNNY+V1FDFNFtYykeSBRHBNfBBjW4oF1+4WHHkIup1mG/sFXbrfL34eJVR1k+pgYPA HgetyTQ7ja0S1cee5pGRJLIElrs9biHxkg9pcGJIoGDupauPNZOiGgivh48Gx09X1ZYb 6kwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=v+ApHedS4SyH1G1fBgvt7ZaT1fuJ7XcqDUxvysyyXWo=; b=mv5GsPcJRpx65Y4YQkwiQAby3RbJ05x9EUrGsidSZUgCp2m4jzPHGibTo7IuMtU4Nk OHmV6+0BuSBUeya66nDRbs7VGBJZleoLlaaghNaYdwUNVzjOdeCNdKo/e2U5HjQOCyfZ EGnfyOatduPf8K/kZ3PgeMbQf9N8TN8F24kRQ8gve+26LtakaC/SQzdPoP+W0AEp+jGj 1A9buZX0rS2Wq293zU16KJgP2MobKDxF2r852lpSQ4ZakCp4dBkg2kIqDhwzmeYr5Nix SmAIWrjsJjidTvBfOFYr0dCpeEoS0+4BFzqVoXGCae3wzg2BPxmDDWavueMt4StpDXFf uSLA== X-Gm-Message-State: AEkoouspQJAk9TZw2u+a3ZQuFkAskHJK2O5a5UxCyNu/7sHr+tnwph210fe/bAGt7uHjDw== X-Received: by 10.194.178.102 with SMTP id cx6mr42488445wjc.58.1471450412232; Wed, 17 Aug 2016 09:13:32 -0700 (PDT) Received: from twisty.fritz.box (x5f70102d.dyn.telefonica.de. [95.112.16.45]) by smtp.gmail.com with ESMTPSA id g67sm27369623wme.5.2016.08.17.09.13.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 17 Aug 2016 09:13:31 -0700 (PDT) From: Mario Kleiner To: dri-devel@lists.freedesktop.org Subject: [PATCH 1/2] drm/nouveau: Fix pageflipping of PRIME imported scanout bo's. Date: Wed, 17 Aug 2016 18:12:56 +0200 Message-Id: <1471450377-12274-2-git-send-email-mario.kleiner.de@gmail.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1471450377-12274-1-git-send-email-mario.kleiner.de@gmail.com> References: <1471450377-12274-1-git-send-email-mario.kleiner.de@gmail.com> Cc: michel.daenzer@amd.com, jglisse@redhat.com, bskeggs@redhat.com, alexander.deucher@amd.com, airlied@redhat.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Scanout bo's which are dmabuf backed in RAM and imported via prime will not update their content with new rendering from the renderoffload gpu once they've been flipped onto the scanout once. The reason is that at preparation of first flip they get pinned into VRAM, then unpinned at some later point, but they stay in the VRAM memory domain, so updates to the system RAM dmabuf object by the exporting render offload gpu don't lead to updates of the content in VRAM - it becomes stale. For prime imported dmabufs we solve this by first pinning the bo into GTT, which will reset the bos domain back to GTT, then unpinning again, so the followup pinning into VRAM will actually upload an up to date display buffer from dmabuf GTT backing store. During the pinning into GTT, we skip the actual data move from VRAM to GTT to avoid a needless bo copy of stale image data. Signed-off-by: Mario Kleiner --- drivers/gpu/drm/nouveau/nouveau_bo.c | 35 +++++++++++++++++++++++++++++-- drivers/gpu/drm/nouveau/nouveau_bo.h | 1 + drivers/gpu/drm/nouveau/nouveau_display.c | 17 +++++++++++++++ drivers/gpu/drm/nouveau/nouveau_prime.c | 1 + 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 6190035..87052e4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -38,6 +38,18 @@ #include "nouveau_ttm.h" #include "nouveau_gem.h" +static inline bool nouveau_dmabuf_skip_op(struct ttm_buffer_object *bo, + struct ttm_mem_reg *new_mem) +{ + struct nouveau_bo *nvbo = nouveau_bo(bo); + + /* + * Return true if a expensive operation as part of a dmabuf + * bo copy from VRAM to GTT can be skipped on this bo. + */ + return nvbo->prime_imported && new_mem && new_mem->mem_type == TTM_PL_TT; +} + /* * NV10-NV40 tiling helpers */ @@ -1026,13 +1038,15 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, struct nouveau_channel *chan = drm->ttm.chan; struct nouveau_cli *cli = (void *)chan->user.client; struct nouveau_fence *fence; + bool skip_prime = !evict && nouveau_dmabuf_skip_op(bo, new_mem); int ret; /* create temporary vmas for the transfer and attach them to the * old nvkm_mem node, these will get cleaned up after ttm has * destroyed the ttm_mem_reg */ - if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { + if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA && + !skip_prime) { ret = nouveau_bo_move_prep(drm, bo, new_mem); if (ret) return ret; @@ -1041,7 +1055,21 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, mutex_lock_nested(&cli->mutex, SINGLE_DEPTH_NESTING); ret = nouveau_fence_sync(nouveau_bo(bo), chan, true, intr); if (ret == 0) { - ret = drm->ttm.move(chan, bo, &bo->mem, new_mem); + /* + * For prime-imported dmabufs which are page-flipped to the + * display as scanout bo's and thereby pinned into VRAM, we + * need to do a pseudo-move back into GTT memory domain once + * they are replaced by a new scanout bo. This to enforce an + * update to the new content from dmabuf storage at next flip, + * otherwise we'd display a stale image. The move back into + * GTT goes through most "administrative moves" of a real + * bo move, but we skip the actual copy of the now stale old + * image data from VRAM back to GTT dmabuf backing to save a + * useless copy. + */ + if (!skip_prime) + ret = drm->ttm.move(chan, bo, &bo->mem, new_mem); + if (ret == 0) { ret = nouveau_fence_new(chan, false, &fence); if (ret == 0) { @@ -1202,6 +1230,9 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem) if (bo->destroy != nouveau_bo_del_ttm) return; + if (nouveau_dmabuf_skip_op(bo, new_mem)) + return; + list_for_each_entry(vma, &nvbo->vma_list, head) { if (new_mem && new_mem->mem_type != TTM_PL_SYSTEM && (new_mem->mem_type == TTM_PL_VRAM || diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h index e423609..4e415e0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.h +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h @@ -39,6 +39,7 @@ struct nouveau_bo { int pin_refcnt; struct ttm_bo_kmap_obj dma_buf_vmap; + bool prime_imported; }; static inline struct nouveau_bo * diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index afbf557..bb49159 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -736,6 +736,22 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, return -ENOMEM; if (new_bo != old_bo) { + /* Is this a scanout buffer from an imported prime dmabuf? */ + if (new_bo->prime_imported && !new_bo->pin_refcnt) { + /* + * Pretend it "moved out" of VRAM, so a fresh copy of + * new dmabuf content from export gpu gets reuploaded + * from GTT backing store when pinning into VRAM. + */ + DRM_DEBUG_PRIME("Flip to prime imported dmabuf %p\n", + new_bo); + if (nouveau_bo_pin(new_bo, TTM_PL_FLAG_TT, false)) + DRM_ERROR("Fail gtt pin imported buf %p\n", + new_bo); + else + nouveau_bo_unpin(new_bo); + } + ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM, true); if (ret) goto fail_free; @@ -808,6 +824,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, ttm_bo_unreserve(&old_bo->bo); if (old_bo != new_bo) nouveau_bo_unpin(old_bo); + nouveau_fence_unref(&fence); return 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c index a0a9704..2bd76f6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_prime.c +++ b/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -75,6 +75,7 @@ struct drm_gem_object *nouveau_gem_prime_import_sg_table(struct drm_device *dev, return ERR_PTR(ret); nvbo->valid_domains = NOUVEAU_GEM_DOMAIN_GART; + nvbo->prime_imported = true; /* Initialize the embedded gem-object. We return a single gem-reference * to the caller, instead of a normal nouveau_bo ttm reference. */