From patchwork Thu Jan 11 22:22:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 859393 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="eEwlsX+F"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zHgPL48kPz9sNw for ; Fri, 12 Jan 2018 09:23:02 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933298AbeAKWXC (ORCPT ); Thu, 11 Jan 2018 17:23:02 -0500 Received: from mail-qk0-f196.google.com ([209.85.220.196]:40479 "EHLO mail-qk0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933287AbeAKWXB (ORCPT ); Thu, 11 Jan 2018 17:23:01 -0500 Received: by mail-qk0-f196.google.com with SMTP id d18so6380753qke.7 for ; Thu, 11 Jan 2018 14:23:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=J9eDB5rgn/OAzUjf6K1NFMpLUqjt/8OQ2/MZwqKRDrs=; b=eEwlsX+FvyHrqA1Y5B84B1DBnYQDYj7iMGeZEK/c3UYufXBPAmQjUF3qQ1A36IswNp B+EdRuaeKw9xbPHeTePn2SAsb9pamK6v2/KLGI3Mhnrxg3NS0Gl4ztOpMUw099MMNf++ Qd9vlQh1JFweXLvMJGyL/arzFef2m212/VanPNxl02qDWTq82qqR+Ez0rC+P0MDx6wbD h9Aofj23ql/LbklltOZoSECYa6w4MJvVffTX5hKK44mqcoXGyk0wZXi37b/9BhYL/vXs ocZ6K/XYJd6ceGJl0ty0yV8fi/O/CZ0OwonkYwLhC+FIHeO6IX26zDnNB6fLrm7JNVJ1 CZVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=J9eDB5rgn/OAzUjf6K1NFMpLUqjt/8OQ2/MZwqKRDrs=; b=mVheb5C2malBj9jG2FV06vd8r2vgwbi0xLSHr0rjbJ9iDtOtZqT8zKtFD3OGre8u3T Bs84AvkYkw0QsYIoLzsrlqwzAcOx+x36yJ+dvIrKkAN6RzE4PfPgA/jbqccDD5qvF1qD 1KIccuREbnSpSH6iKP7+ych62xHtjwTSQyMD+AdAqshUOaQoUuVw5AtR4MZtBkxLhNEO HRiqahNK7m7LujnoDufBfCjhnqR73ektNEYnGoqBkNSgzEnFKeFS/9K6K8mTeRP+nzRF SxnAVnc8ZGqR2Qzrwi2BYzJ7PmOTXct3RhJNPnfAHAinC1r9qFa2wgsvahtskCEpmLKd bNSg== X-Gm-Message-State: AKGB3mKcFJXxceak+BKBLQqhh6sqcnybnKUQD5TdOUJ6RhfXoQz/AjGk NMlOjUhvtDJYLo/lvCehsfs= X-Google-Smtp-Source: ACJfBotSroVncyeii0cmKue1XrxWWKFQFys07KJBc2MdsAxVcX6wIS6SfcS2mhzgy6rgDHEGL+Ugmw== X-Received: by 10.55.149.197 with SMTP id x188mr32272728qkd.37.1515709380395; Thu, 11 Jan 2018 14:23:00 -0800 (PST) Received: from localhost (p200300E41F21CF00227DB10B7BBDB590.dip0.t-ipconnect.de. [2003:e4:1f21:cf00:227d:b10b:7bbd:b590]) by smtp.gmail.com with ESMTPSA id 43sm13442528qtp.28.2018.01.11.14.22.59 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 11 Jan 2018 14:22:59 -0800 (PST) From: Thierry Reding To: Thierry Reding Cc: Mikko Perttunen , dri-devel@lists.freedesktop.org, nouveau@lists.freedesktop.org, linux-tegra@vger.kernel.org Subject: [PATCH 3/3] drm/tegra: Support for sync file-based fences in submit Date: Thu, 11 Jan 2018 23:22:49 +0100 Message-Id: <20180111222249.29105-4-thierry.reding@gmail.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180111222249.29105-1-thierry.reding@gmail.com> References: <20180111222249.29105-1-thierry.reding@gmail.com> Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org From: Mikko Perttunen Add support for sync file-based prefences and postfences to job submission. Fences are passed to the Host1x implementation. Signed-off-by: Mikko Perttunen Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/drm.c | 82 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index d50bddb2e447..c40175c32dd7 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -374,6 +375,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, struct drm_tegra_submit *args, struct drm_device *drm, struct drm_file *file) { + struct host1x *host1x = dev_get_drvdata(drm->dev->parent); unsigned int num_cmdbufs = args->num_cmdbufs; unsigned int num_relocs = args->num_relocs; unsigned int num_waitchks = args->num_waitchks; @@ -382,7 +384,6 @@ int tegra_drm_submit(struct tegra_drm_context *context, struct drm_tegra_waitchk __user *user_waitchks; struct drm_tegra_syncpt __user *user_syncpt; struct drm_tegra_syncpt syncpt; - struct host1x *host1x = dev_get_drvdata(drm->dev->parent); struct drm_gem_object **refs; struct host1x_syncpt *sp; struct host1x_job *job; @@ -402,6 +403,10 @@ int tegra_drm_submit(struct tegra_drm_context *context, if (args->num_waitchks != 0) return -EINVAL; + /* Check for unrecognized flags */ + if (args->flags & ~DRM_TEGRA_SUBMIT_FLAGS) + return -EINVAL; + job = host1x_job_alloc(context->channel, args->num_cmdbufs, args->num_relocs, args->num_waitchks); if (!job) @@ -413,6 +418,14 @@ int tegra_drm_submit(struct tegra_drm_context *context, job->class = context->client->base.class; job->serialize = true; + if (args->flags & DRM_TEGRA_SUBMIT_WAIT_FENCE_FD) { + job->prefence = sync_file_get_fence(args->fence); + if (!job->prefence) { + err = -ENOENT; + goto put; + } + } + /* * Track referenced BOs so that they can be unreferenced after the * submission is complete. @@ -436,7 +449,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, if (copy_from_user(&cmdbuf, user_cmdbufs, sizeof(cmdbuf))) { err = -EFAULT; - goto fail; + goto put_bos; } /* @@ -445,13 +458,13 @@ int tegra_drm_submit(struct tegra_drm_context *context, */ if (cmdbuf.words > CDMA_GATHER_FETCHES_MAX_NB) { err = -EINVAL; - goto fail; + goto put_bos; } bo = host1x_bo_lookup(file, cmdbuf.handle); if (!bo) { err = -ENOENT; - goto fail; + goto put_bos; } offset = (u64)cmdbuf.offset + (u64)cmdbuf.words * sizeof(u32); @@ -465,7 +478,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, */ if (offset & 3 || offset >= obj->gem.size) { err = -EINVAL; - goto fail; + goto put_bos; } host1x_job_add_gather(job, bo, cmdbuf.words, cmdbuf.offset); @@ -482,7 +495,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, &user_relocs[num_relocs], drm, file); if (err < 0) - goto fail; + goto put_bos; reloc = &job->relocarray[num_relocs]; obj = host1x_to_tegra_bo(reloc->cmdbuf.bo); @@ -496,7 +509,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, if (reloc->cmdbuf.offset & 3 || reloc->cmdbuf.offset >= obj->gem.size) { err = -EINVAL; - goto fail; + goto put_bos; } obj = host1x_to_tegra_bo(reloc->target.bo); @@ -504,7 +517,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, if (reloc->target.offset >= obj->gem.size) { err = -EINVAL; - goto fail; + goto put_bos; } } @@ -516,7 +529,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, err = host1x_waitchk_copy_from_user( wait, &user_waitchks[num_waitchks], file); if (err < 0) - goto fail; + goto put_bos; obj = host1x_to_tegra_bo(wait->bo); refs[num_refs++] = &obj->gem; @@ -528,20 +541,20 @@ int tegra_drm_submit(struct tegra_drm_context *context, if (wait->offset & 3 || wait->offset >= obj->gem.size) { err = -EINVAL; - goto fail; + goto put_bos; } } if (copy_from_user(&syncpt, user_syncpt, sizeof(syncpt))) { err = -EFAULT; - goto fail; + goto put_bos; } /* check whether syncpoint ID is valid */ sp = host1x_syncpt_get(host1x, syncpt.id); if (!sp) { err = -ENOENT; - goto fail; + goto put_bos; } job->is_addr_reg = context->client->ops->is_addr_reg; @@ -555,23 +568,60 @@ int tegra_drm_submit(struct tegra_drm_context *context, err = host1x_job_pin(job, context->client->base.dev); if (err) - goto fail; + goto put_bos; err = host1x_job_submit(job); if (err) { host1x_job_unpin(job); - goto fail; + goto put_bos; } - args->fence = job->syncpt_end; + if (args->flags & DRM_TEGRA_SUBMIT_CREATE_FENCE_FD) { + struct host1x_syncpt *syncpt; + struct dma_fence *fence; + struct sync_file *file; + + syncpt = host1x_syncpt_get(host1x, job->syncpt_id); + if (!syncpt) { + err = -EINVAL; + goto put_bos; + } -fail: + fence = host1x_fence_create(host1x, syncpt, job->syncpt_end); + if (!fence) { + err = -ENOMEM; + goto put_bos; + } + + file = sync_file_create(fence); + if (!file) { + dma_fence_put(fence); + err = -ENOMEM; + goto put_bos; + } + + err = get_unused_fd_flags(O_CLOEXEC); + if (err < 0) { + dma_fence_put(fence); + goto put_bos; + } + + fd_install(err, file->file); + args->fence = err; + } else { + args->fence = job->syncpt_end; + } + +put_bos: while (num_refs--) drm_gem_object_put_unlocked(refs[num_refs]); kfree(refs); put: + if (job->prefence) + dma_fence_put(job->prefence); + host1x_job_put(job); return err; }