From patchwork Wed Apr 11 13:39:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christian_K=C3=B6nig?= X-Patchwork-Id: 10335489 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 5870960134 for ; Wed, 11 Apr 2018 13:40:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5528F28971 for ; Wed, 11 Apr 2018 13:40:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4770428974; Wed, 11 Apr 2018 13:40:12 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A608F28971 for ; Wed, 11 Apr 2018 13:40:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753229AbeDKNkK (ORCPT ); Wed, 11 Apr 2018 09:40:10 -0400 Received: from mail-wr0-f195.google.com ([209.85.128.195]:46572 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751961AbeDKNkG (ORCPT ); Wed, 11 Apr 2018 09:40:06 -0400 Received: by mail-wr0-f195.google.com with SMTP id d1so1820306wrj.13 for ; Wed, 11 Apr 2018 06:40:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=XmkjijR5CB+4AUy+cg2ybjPzF50Bb8U0iCvFP2BH2Dg=; b=VsTmfUes+QMpoTFlHMZyviEVOeDaxWkprK8Qs7zokqETP7PM1mgKD+FIa611JObR57 S9FFQfAOaEBwPU8PFCFz8jhIdQRxhJFUU6vhuWOMKrLmHUSpdq2IxIrHykbrjsuy19dH fMjbIhNBQoSlaNCKcAB1Ajuo4IxVnwQCHoJUIBspIeEUMbeNXyW7gbNr9k7Fs7StkAdW uE1CrP30jAUKzLkbGcRh2ouiM4s3jalWFDrOgXBrY2NdjTFXbvYPK70vEOD8cyHCSP0w FhBQ0F2b07tb7yxU/Awz6B8Gyzk/6ZxgkMZvl3q2KeH3rLJfu/tXmPj0BWcsTfTu9iVk 73xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XmkjijR5CB+4AUy+cg2ybjPzF50Bb8U0iCvFP2BH2Dg=; b=nhLVc0Qxp4eJsIWcKEHxZIGMyjyhVkmzvX5dN4QxCbzGFI8oMIq1bB3Nw8PnlVb5Ik 43O5KSn8OusAqCvesPUzHnZv+lv5q4sDyWD4uSjBLc7P0/gmvXqoVzr4zc4fdjAUWok2 D0VYqkCqQCZ3AOFhoInrXD/Pk9OvzE89t3mZY0XB2HFqiDRmB4zTd04z6SxmhNW+eq/d FRplYwZ1KLmSjKLWDZYY3tOgw1I6y8zGtOCXsaZ8FJKIT/2oRrkp7rybXLGeTZ+kEjN+ 0kUadcIAFn4M4Nor1VPqDCvwdZ0LP/nDevUnOUUjNH8nVqc+i5Z+Z1QpeYlWxHPcW8nP 2Z/g== X-Gm-Message-State: ALQs6tD6DF/hfFYdkM/W6Pq9sF6AiWlFypSO7Yq3T4lbwfBU1zLV1Lz/ Z7t2K5UP0GCApMrYLwxJCjU= X-Google-Smtp-Source: AIpwx49vX/NbOweSXf0NONZS7u0BkzmgSMC4KDG1jysAKCuz7YfABtf4TAQZn+H0tmpocMScpMdbWg== X-Received: by 10.223.150.161 with SMTP id u30mr3401029wrb.151.1523454005576; Wed, 11 Apr 2018 06:40:05 -0700 (PDT) Received: from baker.fritz.box ([2a02:908:1257:4460:d034:7875:b3e9:a4a6]) by smtp.gmail.com with ESMTPSA id r28sm1420572wra.78.2018.04.11.06.40.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Apr 2018 06:40:05 -0700 (PDT) From: "=?UTF-8?q?Christian=20K=C3=B6nig?=" X-Google-Original-From: =?UTF-8?q?Christian=20K=C3=B6nig?= To: linaro-mm-sig@lists.linaro.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org Subject: [PATCH 5/5] drm/amdgpu: add independent DMA-buf import v3 Date: Wed, 11 Apr 2018 15:39:59 +0200 Message-Id: <20180411133959.4257-5-christian.koenig@amd.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180411133959.4257-1-christian.koenig@amd.com> References: <20180411133959.4257-1-christian.koenig@amd.com> MIME-Version: 1.0 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Instead of relying on the DRM functions just implement our own import functions. This adds support for taking care of unpinned DMA-buf. v2: enable for all exporters, not just amdgpu, fix invalidation handling, lock reservation object while setting callback v3: change to new dma_buf attach interface Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c | 72 ++++++++++++++++++++++++++----- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 32 +++++++++++--- 2 files changed, 89 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c index 7fef95f0fed1..58dcfba0225a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c @@ -86,28 +86,24 @@ int amdgpu_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma return ret; } -struct drm_gem_object * -amdgpu_gem_prime_import_sg_table(struct drm_device *dev, - struct dma_buf_attachment *attach, - struct sg_table *sg) +static struct drm_gem_object * +amdgpu_gem_prime_create_obj(struct drm_device *dev, struct dma_buf *dma_buf) { - struct reservation_object *resv = attach->dmabuf->resv; + struct reservation_object *resv = dma_buf->resv; struct amdgpu_device *adev = dev->dev_private; struct amdgpu_bo *bo; int ret; ww_mutex_lock(&resv->lock, NULL); - ret = amdgpu_bo_create(adev, attach->dmabuf->size, PAGE_SIZE, + ret = amdgpu_bo_create(adev, dma_buf->size, PAGE_SIZE, AMDGPU_GEM_DOMAIN_CPU, 0, ttm_bo_type_sg, resv, &bo); if (ret) goto error; - bo->tbo.sg = sg; - bo->tbo.ttm->sg = sg; bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT; bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT; - if (attach->dmabuf->ops != &amdgpu_dmabuf_ops) + if (dma_buf->ops != &amdgpu_dmabuf_ops) bo->prime_shared_count = 1; ww_mutex_unlock(&resv->lock); @@ -118,6 +114,26 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev, return ERR_PTR(ret); } +struct drm_gem_object * +amdgpu_gem_prime_import_sg_table(struct drm_device *dev, + struct dma_buf_attachment *attach, + struct sg_table *sg) +{ + struct drm_gem_object *obj; + struct amdgpu_bo *bo; + + obj = amdgpu_gem_prime_create_obj(dev, attach->dmabuf); + if (IS_ERR(obj)) + return obj; + + bo = gem_to_amdgpu_bo(obj); + amdgpu_bo_reserve(bo, true); + bo->tbo.sg = sg; + bo->tbo.ttm->sg = sg; + amdgpu_bo_unreserve(bo); + return obj; +} + static struct sg_table * amdgpu_gem_map_dma_buf(struct dma_buf_attachment *attach, enum dma_data_direction dir) @@ -293,9 +309,29 @@ struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev, return buf; } +static void +amdgpu_gem_prime_invalidate_mappings(struct dma_buf_attachment *attach) +{ + struct ttm_operation_ctx ctx = { false, false }; + struct drm_gem_object *obj = attach->priv; + struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); + struct ttm_placement placement = {}; + int r; + + r = ttm_bo_validate(&bo->tbo, &placement, &ctx); + if (r) + DRM_ERROR("Failed to unmap DMA-buf import (%d))\n", r); +} + struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf) { + struct dma_buf_attach_info attach_info = { + .dev = dev->dev, + .dmabuf = dma_buf, + .invalidate = amdgpu_gem_prime_invalidate_mappings + }; + struct dma_buf_attachment *attach; struct drm_gem_object *obj; if (dma_buf->ops == &amdgpu_dmabuf_ops) { @@ -310,5 +346,21 @@ struct drm_gem_object *amdgpu_gem_prime_import(struct drm_device *dev, } } - return drm_gem_prime_import(dev, dma_buf); + if (!dma_buf->invalidation_supported) + return drm_gem_prime_import(dev, dma_buf); + + obj = amdgpu_gem_prime_create_obj(dev, dma_buf); + if (IS_ERR(obj)) + return obj; + + attach_info.importer_priv = obj; + attach = dma_buf_attach(&attach_info); + if (IS_ERR(attach)) { + drm_gem_object_put(obj); + return ERR_CAST(attach); + } + + get_dma_buf(dma_buf); + obj->import_attach = attach; + return obj; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index ab73300e6c7f..2a8f328918cb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "amdgpu.h" #include "amdgpu_object.h" #include "amdgpu_trace.h" @@ -680,6 +681,7 @@ struct amdgpu_ttm_gup_task_list { struct amdgpu_ttm_tt { struct ttm_dma_tt ttm; + struct amdgpu_bo *bo; u64 offset; uint64_t userptr; struct mm_struct *usermm; @@ -988,6 +990,7 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo, return NULL; } gtt->ttm.ttm.func = &amdgpu_backend_func; + gtt->bo = ttm_to_amdgpu_bo(bo); if (ttm_sg_tt_init(>t->ttm, bo, page_flags)) { kfree(gtt); return NULL; @@ -1000,7 +1003,6 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm, { struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev); struct amdgpu_ttm_tt *gtt = (void *)ttm; - bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); if (gtt && gtt->userptr) { ttm->sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL); @@ -1012,7 +1014,19 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm, return 0; } - if (slave && ttm->sg) { + if (ttm->page_flags & TTM_PAGE_FLAG_SG) { + if (!ttm->sg) { + struct dma_buf_attachment *attach; + struct sg_table *sgt; + + attach = gtt->bo->gem_base.import_attach; + sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) + return PTR_ERR(sgt); + + ttm->sg = sgt; + } + drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, gtt->ttm.dma_address, ttm->num_pages); @@ -1031,9 +1045,8 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm, static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) { - struct amdgpu_device *adev; struct amdgpu_ttm_tt *gtt = (void *)ttm; - bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); + struct amdgpu_device *adev; if (gtt && gtt->userptr) { amdgpu_ttm_tt_set_user_pages(ttm, NULL); @@ -1042,7 +1055,16 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) return; } - if (slave) + if (ttm->sg && !gtt->bo->tbo.sg) { + struct dma_buf_attachment *attach; + + attach = gtt->bo->gem_base.import_attach; + dma_buf_unmap_attachment(attach, ttm->sg, DMA_BIDIRECTIONAL); + ttm->sg = NULL; + return; + } + + if (ttm->page_flags & TTM_PAGE_FLAG_SG) return; adev = amdgpu_ttm_adev(ttm->bdev);