From patchwork Thu Oct 29 14:20:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Guido_G=C3=BCnther?= X-Patchwork-Id: 11866497 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC9E6C4363A for ; Thu, 29 Oct 2020 14:21:10 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 5326B20780 for ; Thu, 29 Oct 2020 14:21:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5326B20780 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=sigxcpu.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A95556ECEA; Thu, 29 Oct 2020 14:21:04 +0000 (UTC) Received: from honk.sigxcpu.org (honk.sigxcpu.org [24.134.29.49]) by gabe.freedesktop.org (Postfix) with ESMTPS id A7B096ECE3; Thu, 29 Oct 2020 14:21:02 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by honk.sigxcpu.org (Postfix) with ESMTP id 4475DFB02; Thu, 29 Oct 2020 15:21:01 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at honk.sigxcpu.org Received: from honk.sigxcpu.org ([127.0.0.1]) by localhost (honk.sigxcpu.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Pf59pt3RtFms; Thu, 29 Oct 2020 15:20:58 +0100 (CET) Received: by bogon.sigxcpu.org (Postfix, from userid 1000) id 4F05444639; Thu, 29 Oct 2020 15:20:57 +0100 (CET) From: =?utf-8?q?Guido_G=C3=BCnther?= To: Lucas Stach , Russell King , Christian Gmeiner , David Airlie , Daniel Vetter , etnaviv@lists.freedesktop.org, dri-devel@lists.freedesktop.org Subject: [RFC PATCH 2/2] drm: etnaviv: Unmap gems on gem_close Date: Thu, 29 Oct 2020 15:20:57 +0100 Message-Id: X-Mailer: git-send-email 2.28.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" So far the unmap from gpu address space only happened when dropping the last ref in gem_free_object_unlocked, however that is skipped if there's still multiple handles to the same GEM object. Since userspace (here mesa) in the case of softpin hands back the memory region to the pool of available GPU virtual memory closing the handle via DRM_IOCTL_GEM_CLOSE this can lead to etnaviv_iommu_insert_exact failing later since userspace thinks the vaddr is available while the kernel thinks it isn't making the submit fail like [E] submit failed: -14 (No space left on device) (etna_cmd_stream_flush:244) Fix this by unmapping the memory via the .gem_close_object callback. Signed-off-by: Guido Günther --- drivers/gpu/drm/etnaviv/etnaviv_drv.c | 1 + drivers/gpu/drm/etnaviv/etnaviv_drv.h | 1 + drivers/gpu/drm/etnaviv/etnaviv_gem.c | 32 +++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index a9a3afaef9a1..fdcc6405068c 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -491,6 +491,7 @@ static struct drm_driver etnaviv_drm_driver = { .open = etnaviv_open, .postclose = etnaviv_postclose, .gem_free_object_unlocked = etnaviv_gem_free_object, + .gem_close_object = etnaviv_gem_close_object, .gem_vm_ops = &vm_ops, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index 4d8dc9236e5f..2226a9af0d63 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -65,6 +65,7 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op, struct drm_etnaviv_timespec *timeout); int etnaviv_gem_cpu_fini(struct drm_gem_object *obj); void etnaviv_gem_free_object(struct drm_gem_object *obj); +void etnaviv_gem_close_object(struct drm_gem_object *obj, struct drm_file *file); int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file, u32 size, u32 flags, u32 *handle); int etnaviv_gem_new_userptr(struct drm_device *dev, struct drm_file *file, diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index f06e19e7be04..5aec4a23c77e 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -515,6 +515,38 @@ static const struct etnaviv_gem_ops etnaviv_gem_shmem_ops = { .mmap = etnaviv_gem_mmap_obj, }; +void etnaviv_gem_close_object(struct drm_gem_object *obj, struct drm_file *unused) +{ + struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); + struct etnaviv_vram_mapping *mapping, *tmp; + + /* Handle this via etnaviv_gem_free_object */ + if (obj->handle_count == 1) + return; + + WARN_ON(is_active(etnaviv_obj)); + + /* + * userspace wants to release the handle so we need to remove + * the mapping from the gpu's virtual address space to stay + * in sync. + */ + list_for_each_entry_safe(mapping, tmp, &etnaviv_obj->vram_list, + obj_node) { + struct etnaviv_iommu_context *context = mapping->context; + + WARN_ON(mapping->use); + + if (context) { + etnaviv_iommu_unmap_gem(context, mapping); + etnaviv_iommu_context_put(context); + } + + list_del(&mapping->obj_node); + kfree(mapping); + } +} + void etnaviv_gem_free_object(struct drm_gem_object *obj) { struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);