Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp452459imu; Mon, 5 Nov 2018 03:42:56 -0800 (PST) X-Google-Smtp-Source: AJdET5esnr3AxLQ8x+cs42NNywRDBQw5eskRiSRif2YrcX9uN3hdO+htLLn+NkCBlCQ6iQxknsLR X-Received: by 2002:a63:8f45:: with SMTP id r5mr336610pgn.222.1541418176237; Mon, 05 Nov 2018 03:42:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1541418176; cv=none; d=google.com; s=arc-20160816; b=xV727lZ3Cxey+JDduTD9nw4yOBUqW7Pb6UbahLY30Imyps5d/IUgl7gCsA2jQr/G8N bOKU9ofZ0PUO1eZrud8oP18CDLwWO3wqP+mpWghOg9izTQb+XxHP+IOBqraCwsqNlB2O Aiybds/E8dKyZFZ7Y5yBy90N0piNLinhMG4IbtIr8CvYnE9+j/glW3+wwa7hSneMa4o8 tRuwVk6pirTpEzYZZJccf4DJYR5sS3V4umZqVI88rhTr6630kIOwfzOcdkW2EAh46Ltf 6X/F3Qv9OMKbjMK8VwtY2V5grsMztMywqwuPES1r8ezxAWXT17pS8tWQktisYjhOrYFT MZQA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=0EHIrDgjNhPpinJd9CBswmYOCgoPtt6uS4CBDYNhJ/w=; b=CHMfBDdSsNq3BWGs1ERgnoa84wec2tW82a+fI809fto/s4aeYbXdDjpYhUz7TL/2q0 pZ6bJjSBbS+xzrhnVDbmzJbRx3ixOQp0nl9sluWMEAjSiwqqm0Ol12SdgB70tcrwb5pB xih6lYKx1Ev3jul88jXO2hFVN033uoztoz1DVYh4BXvzR8323TgH09OtYLqGdIAXGc9B DpASfQ40lv2QGjNIl9crrVRhAs57a8cVcX30YYRARm0lx+ysF7xZiPNCBCXSKdIhjV+5 gQMlRpiD//0H8kp2gVImrLY+rBeOu/lQHtebPeh6CHiWtJ2fnvH8HoApF/rlGQwII0Ux gtyg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r20-v6si43151438pgm.28.2018.11.05.03.42.41; Mon, 05 Nov 2018 03:42:56 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729435AbeKEVB3 (ORCPT + 99 others); Mon, 5 Nov 2018 16:01:29 -0500 Received: from bhuna.collabora.co.uk ([46.235.227.227]:48688 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729004AbeKEVB0 (ORCPT ); Mon, 5 Nov 2018 16:01:26 -0500 Received: from localhost.localdomain (unknown [IPv6:2a02:8109:92c0:207d:59be:d485:5b1c:9e22]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: robertfoss) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 3F98927DF3B; Mon, 5 Nov 2018 11:42:06 +0000 (GMT) From: Robert Foss To: airlied@linux.ie, kraxel@redhat.com, dri-devel@lists.freedesktop.org, virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Rob Herring , Gustavo Padovan , Emil Velikov Cc: Robert Foss Subject: [PATCH v4 3/4] drm/virtio: add in/out fence support for explicit synchronization Date: Mon, 5 Nov 2018 12:41:51 +0100 Message-Id: <20181105114152.2088-4-robert.foss@collabora.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181105114152.2088-1-robert.foss@collabora.com> References: <20181105114152.2088-1-robert.foss@collabora.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When the execbuf call receives an in-fence it will get the dma_fence related to that fence fd and wait on it before submitting the draw call. On the out-fence side we get fence returned by the submitted draw call and attach it to a sync_file and send the sync_file fd to userspace. On error -1 is returned to userspace. Signed-off-by: Gustavo Padovan Signed-off-by: Robert Foss Suggested-by: Rob Herring Reviewed-by: Emil Velikov --- Changes since v3: - Move all in_fence handling to the same VIRTGPU_EXECBUF_FENCE_FD_IN block - Emil: Make sure to always call dma_fence_put() - Emil: Added r-b drivers/gpu/drm/virtio/virtgpu_ioctl.c | 81 ++++++++++++++++++++------ 1 file changed, 64 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 3d497835b0f5..340f2513d829 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "virtgpu_drv.h" @@ -105,7 +106,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_fpriv *vfpriv = drm_file->driver_priv; struct drm_gem_object *gobj; - struct virtio_gpu_fence *fence; + struct virtio_gpu_fence *out_fence; struct virtio_gpu_object *qobj; int ret; uint32_t *bo_handles = NULL; @@ -114,6 +115,9 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, struct ttm_validate_buffer *buflist = NULL; int i; struct ww_acquire_ctx ticket; + struct sync_file *sync_file; + int in_fence_fd = exbuf->fence_fd; + int out_fence_fd = -1; void *buf; if (vgdev->has_virgl_3d == false) @@ -124,6 +128,33 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, exbuf->fence_fd = -1; + if (exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_IN) { + struct dma_fence *in_fence; + + in_fence = sync_file_get_fence(in_fence_fd); + + if (!in_fence) + return -EINVAL; + + /* + * Wait if the fence is from a foreign context, or if the fence + * array contains any fence from a foreign context. + */ + ret = 0; + if (!dma_fence_match_context(in_fence, vgdev->fence_drv.context)) + ret = dma_fence_wait(in_fence, true); + + dma_fence_put(in_fence); + if (ret) + return ret; + } + + if (exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_OUT) { + out_fence_fd = get_unused_fd_flags(O_CLOEXEC); + if (out_fence_fd < 0) + return out_fence_fd; + } + INIT_LIST_HEAD(&validate_list); if (exbuf->num_bo_handles) { @@ -133,26 +164,22 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, sizeof(struct ttm_validate_buffer), GFP_KERNEL | __GFP_ZERO); if (!bo_handles || !buflist) { - kvfree(bo_handles); - kvfree(buflist); - return -ENOMEM; + ret = -ENOMEM; + goto out_unused_fd; } user_bo_handles = (void __user *)(uintptr_t)exbuf->bo_handles; if (copy_from_user(bo_handles, user_bo_handles, exbuf->num_bo_handles * sizeof(uint32_t))) { ret = -EFAULT; - kvfree(bo_handles); - kvfree(buflist); - return ret; + goto out_unused_fd; } for (i = 0; i < exbuf->num_bo_handles; i++) { gobj = drm_gem_object_lookup(drm_file, bo_handles[i]); if (!gobj) { - kvfree(bo_handles); - kvfree(buflist); - return -ENOENT; + ret = -ENOENT; + goto out_unused_fd; } qobj = gem_to_virtio_gpu_obj(gobj); @@ -161,6 +188,7 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, list_add(&buflist[i].head, &validate_list); } kvfree(bo_handles); + bo_handles = NULL; } ret = virtio_gpu_object_list_validate(&ticket, &validate_list); @@ -174,28 +202,47 @@ static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, goto out_unresv; } - fence = virtio_gpu_fence_alloc(vgdev); - if (!fence) { - kfree(buf); + out_fence = virtio_gpu_fence_alloc(vgdev); + if(!out_fence) { ret = -ENOMEM; - goto out_unresv; + goto out_memdup; + } + + if (out_fence_fd >= 0) { + sync_file = sync_file_create(&out_fence->f); + if (!sync_file) { + dma_fence_put(&out_fence->f); + ret = -ENOMEM; + goto out_memdup; + } + + exbuf->fence_fd = out_fence_fd; + fd_install(out_fence_fd, sync_file->file); } + virtio_gpu_cmd_submit(vgdev, buf, exbuf->size, - vfpriv->ctx_id, &fence); + vfpriv->ctx_id, &out_fence); - ttm_eu_fence_buffer_objects(&ticket, &validate_list, &fence->f); + ttm_eu_fence_buffer_objects(&ticket, &validate_list, &out_fence->f); /* fence the command bo */ virtio_gpu_unref_list(&validate_list); kvfree(buflist); - dma_fence_put(&fence->f); return 0; +out_memdup: + kfree(buf); out_unresv: ttm_eu_backoff_reservation(&ticket, &validate_list); out_free: virtio_gpu_unref_list(&validate_list); +out_unused_fd: + kvfree(bo_handles); kvfree(buflist); + + if (out_fence_fd >= 0) + put_unused_fd(out_fence_fd); + return ret; } -- 2.17.1