Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp721725pxb; Fri, 14 Jan 2022 15:01:10 -0800 (PST) X-Google-Smtp-Source: ABdhPJwPWxBnt5bVJY5HIEcQRqUwq8w4Q+Dctq3DdgjMiYxj6v7544mz4fxj7uHw83CVfA8iSMez X-Received: by 2002:a17:906:3e8a:: with SMTP id a10mr8718599ejj.612.1642201269734; Fri, 14 Jan 2022 15:01:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1642201269; cv=none; d=google.com; s=arc-20160816; b=TBa062CHAGW7JA9WqOj5tUq8ttx4Ann/Ck4M5Y5cx6HPrAygycMKzbzQt5uZKFgOXK VUCTQnb901GgtVt4l32LCnJyWdKib7vdh0PnVOeMKbMrkw1t4BKiY+VgJaMYPW7Gp48v Vi7LbJRWjKTuzx4/EkR2CuOZFYCTcmoOBcQcL5YCXznpbaDBt2nFSwXr3c8C35vrRrsy dl5+2P4aDVkj1WgyrI2sbVvf0L0ibU9Ej9hMOqFV6PBo0s9G3mC4QE45VFYnDpW2gGC3 Y8/JLp25Wa/8oTxLfxMKuIz+tp33HRN2A6UBolXcvOiHY9hRYzroVCtP5Zd8kLOsnE40 g+cQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:mail-followup-to:message-id:subject:cc:to:from:date :dkim-signature; bh=U38RVxiG3sOh0MWzSEGRMLdXOoM3QqR6IHHi0QfBZi8=; b=mCUfPcvLM5taZHRWjMU6Cf9Pb4p1Uqbrt2OZSBoG0llarwYMefH8em97FVYgKZLT2H HyrHRZqYwHwrkKSzIaa98jxiLG/zs9f+OXRkSTkVtFBoO8kYqIIPpftOID2XgOD/MogF c2hwdBsAJdeswzx7wbdijceEpChjRATjorme+8/Z23tXs00vQB8PhtbmwIx6VWJxkqVt T1TS/WxClkM1bXJWqIvoQofNlINWretpkD0au5HxY0GQK35BdlLXb+zgMWK/7uLl3SL4 3Bcd0N4eFWvQakTI1+LOtVUVrqAZrTK/cLFe8cMENx/G5cJKohIKcJmLrZ+4YE+Ztcya tWWA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ffwll.ch header.s=google header.b=kpWl9tiT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ho19si4017148ejc.270.2022.01.14.15.00.45; Fri, 14 Jan 2022 15:01:09 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@ffwll.ch header.s=google header.b=kpWl9tiT; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244042AbiANSDm (ORCPT + 99 others); Fri, 14 Jan 2022 13:03:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44356 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243990AbiANSDl (ORCPT ); Fri, 14 Jan 2022 13:03:41 -0500 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BAF48C06161C for ; Fri, 14 Jan 2022 10:03:40 -0800 (PST) Received: by mail-wm1-x329.google.com with SMTP id p18so7496051wmg.4 for ; Fri, 14 Jan 2022 10:03:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=date:from:to:cc:subject:message-id:mail-followup-to:references :mime-version:content-disposition:in-reply-to; bh=U38RVxiG3sOh0MWzSEGRMLdXOoM3QqR6IHHi0QfBZi8=; b=kpWl9tiTaB9Y667+lup71x1J3yMu5ghjvQoCzOOh+q4D5IZ7zGM8zg/+N28TScTQ0g anXQOGW/wgm+xoWtCuWtpzWQH5OjTX3fBjNdmthHBM9IdXHwaPS3iarQ25LnNF54nfuk zccvVoDGoZrIQhhlFFrJZC3FFkyIBY/cx44eA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id :mail-followup-to:references:mime-version:content-disposition :in-reply-to; bh=U38RVxiG3sOh0MWzSEGRMLdXOoM3QqR6IHHi0QfBZi8=; b=qjm3HirEYU8CniFhsT61VXiriji0vH/XznK4YMA7ReM3k2OUay2/ocNNd9pu0oNr2P +udn8h7unSIMQDeFZzL098azbJA9W25IeD8gGxsre0X0SpguE9BeWPOSseIbcHJEeSuD Su3xULB1Yq0zKtojkW1kHjOcfgWL2tKf+ilre5ppd6b+bFqUnNwqJfa3lm8/J20+Z9W7 hkIHlQrFE4d9E82nVDRS2Q7Z9GO/dwMvWsxVYnR+Ya4FwF2jWK2Nb3hol6wmRzsQS45v QpwoJAxbEvl70zyFgQJemsTIiV7ee1kjLjF2GXIMYx2iJTpPk0MIB+Fp4xpLL63et6r7 3lvg== X-Gm-Message-State: AOAM53120NNjaPiX5obxSlV7/ML9feT30De4PnOnLCdmw69rimAqNnux SE/Qq1QAT/raprWpEcd7dwgq8g== X-Received: by 2002:a05:600c:3790:: with SMTP id o16mr11384843wmr.174.1642183419143; Fri, 14 Jan 2022 10:03:39 -0800 (PST) Received: from phenom.ffwll.local ([2a02:168:57f4:0:efd0:b9e5:5ae6:c2fa]) by smtp.gmail.com with ESMTPSA id bg19sm12113937wmb.47.2022.01.14.10.03.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jan 2022 10:03:38 -0800 (PST) Date: Fri, 14 Jan 2022 19:03:36 +0100 From: Daniel Vetter To: Iouri Tarassov Cc: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, spronovo@microsoft.com, gregkh@linuxfoundation.org, DRI Development , jenatali@microsoft.com Subject: Re: [PATCH v1 9/9] drivers: hv: dxgkrnl: Implement DXGSYNCFILE Message-ID: Mail-Followup-To: Iouri Tarassov , kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com, wei.liu@kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, spronovo@microsoft.com, gregkh@linuxfoundation.org, DRI Development , jenatali@microsoft.com References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Operating-System: Linux phenom 5.10.0-8-amd64 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi all, On Wed, Jan 12, 2022 at 11:55:14AM -0800, Iouri Tarassov wrote: > Implement the LX_DXCREATESYNCFILE IOCTL (D3DKMTCreateSyncFile). > > dxgsyncfile is built on top of the Linux sync_file object and > provides a way for the user mode to synchronize with the execution > of the device DMA packets. > > The IOCTL creates a dxgsyncfile object for the given GPU synchronization > object and a fence value. A sync_object file descriptor is returned to > the caller. The caller could wait for the object by using poll(). > When the GPU synchronization object is signaled on the host, the host > sends a message to the virtual machine and the sync_file object is > signaled. > > Signed-off-by: Iouri Tarassov Adding dri-devel, which get_maintainers.pl should have done automatically with the dma_fence wildcard match. Not sure why that didn't happen. > +struct dxgsyncpoint { > + struct dxghostevent hdr; > + struct dma_fence base; This doesn't work unfortuntately. For better or worse memory fences like monitored fences from wddm have completely different semantics from dma_fence. You could probably hack this to be self-consistent for hyper-v, but the problem is that then hv would have incompatible locking/nesting rules compared to everything else, and dma_fence matter for memory management so this includes whether you're allowed to kmalloc(GFP_KERNEL) or not, and that's just a bit too much. I discussed this quickly with Jesse on irc and it sounds like the reason you want the dma_fence is just to emulate the sync_file interface for android. I think the correct solution here is to create a hv_dxg_sync_file fd, which emulates the exact ioctls that Android needs, but with a wddm monitored fence underneath instead of a dma_fence underneath. This way we guarantee that no one ever accidentally mixes these incompatible concepts up in the kernel, and Android should still be able to happily run under hyperv. Thoughts? Also pls cc me on this sync work since even if you drop dma_fence use completely I'd like to follow this a bit. Cheers, Daniel > + u64 fence_value; > + u64 context; > + spinlock_t lock; > + u64 u64; > +}; > + > +#endif /* _DXGSYNCFILE_H */ > diff --git a/drivers/hv/dxgkrnl/dxgvmbus.c b/drivers/hv/dxgkrnl/dxgvmbus.c > index 773d8f364b34..185fb7e38c21 100644 > --- a/drivers/hv/dxgkrnl/dxgvmbus.c > +++ b/drivers/hv/dxgkrnl/dxgvmbus.c > @@ -1311,15 +1311,18 @@ int create_existing_sysmem(struct dxgdevice *device, > void *kmem = NULL; > int ret = 0; > struct dxgkvmb_command_setexistingsysmemstore *set_store_command; > + struct dxgkvmb_command_setexistingsysmempages *set_pages_command; > u64 alloc_size = host_alloc->allocation_size; > u32 npages = alloc_size >> PAGE_SHIFT; > struct dxgvmbusmsg msg = {.hdr = NULL}; > - > - ret = init_message(&msg, device->adapter, device->process, > - sizeof(*set_store_command)); > - if (ret) > - goto cleanup; > - set_store_command = (void *)msg.msg; > + const u32 max_pfns_in_message = > + (DXG_MAX_VM_BUS_PACKET_SIZE - sizeof(*set_pages_command) - > + PAGE_SIZE) / sizeof(__u64); > + u32 alloc_offset_in_pages = 0; > + struct page **page_in; > + u64 *pfn; > + u32 pages_to_send; > + u32 i; > > /* > * Create a guest physical address list and set it as the allocation > @@ -1330,6 +1333,7 @@ int create_existing_sysmem(struct dxgdevice *device, > dev_dbg(dxgglobaldev, " Alloc size: %lld", alloc_size); > > dxgalloc->cpu_address = (void *)sysmem; > + > dxgalloc->pages = vzalloc(npages * sizeof(void *)); > if (dxgalloc->pages == NULL) { > pr_err("failed to allocate pages"); > @@ -1347,31 +1351,80 @@ int create_existing_sysmem(struct dxgdevice *device, > ret = -ENOMEM; > goto cleanup; > } > - kmem = vmap(dxgalloc->pages, npages, VM_MAP, PAGE_KERNEL); > - if (kmem == NULL) { > - pr_err("vmap failed"); > - ret = -ENOMEM; > - goto cleanup; > - } > - ret1 = vmbus_establish_gpadl(dxgglobal_get_vmbus(), kmem, > - alloc_size, &dxgalloc->gpadl); > - if (ret1) { > - pr_err("establish_gpadl failed: %d", ret1); > - ret = -ENOMEM; > - goto cleanup; > - } > - dev_dbg(dxgglobaldev, "New gpadl %d", dxgalloc->gpadl.gpadl_handle); > + if (!dxgglobal->map_guest_pages_enabled) { > + ret = init_message(&msg, device->adapter, device->process, > + sizeof(*set_store_command)); > + if (ret) > + goto cleanup; > + set_store_command = (void *)msg.msg; > > - command_vgpu_to_host_init2(&set_store_command->hdr, > - DXGK_VMBCOMMAND_SETEXISTINGSYSMEMSTORE, > - device->process->host_handle); > - set_store_command->device = device->handle; > - set_store_command->device = device->handle; > - set_store_command->allocation = host_alloc->allocation; > - set_store_command->gpadl = dxgalloc->gpadl.gpadl_handle; > - ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); > - if (ret < 0) > - pr_err("failed to set existing store: %x", ret); > + kmem = vmap(dxgalloc->pages, npages, VM_MAP, PAGE_KERNEL); > + if (kmem == NULL) { > + pr_err("vmap failed"); > + ret = -ENOMEM; > + goto cleanup; > + } > + ret1 = vmbus_establish_gpadl(dxgglobal_get_vmbus(), kmem, > + alloc_size, &dxgalloc->gpadl); > + if (ret1) { > + pr_err("establish_gpadl failed: %d", ret1); > + ret = -ENOMEM; > + goto cleanup; > + } > + dev_dbg(dxgglobaldev, "New gpadl %d", > + dxgalloc->gpadl.gpadl_handle); > + > + command_vgpu_to_host_init2(&set_store_command->hdr, > + DXGK_VMBCOMMAND_SETEXISTINGSYSMEMSTORE, > + device->process->host_handle); > + set_store_command->device = device->handle; > + set_store_command->allocation = host_alloc->allocation; > + set_store_command->gpadl = dxgalloc->gpadl.gpadl_handle; > + ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, > + msg.size); > + if (ret < 0) > + pr_err("failed to set existing store: %x", ret); > + } else { > + /* > + * Send the list of the allocation PFNs to the host. The host > + * will map the pages for GPU access. > + */ > + > + ret = init_message(&msg, device->adapter, device->process, > + sizeof(*set_pages_command) + > + max_pfns_in_message * sizeof(u64)); > + if (ret) > + goto cleanup; > + set_pages_command = (void *)msg.msg; > + command_vgpu_to_host_init2(&set_pages_command->hdr, > + DXGK_VMBCOMMAND_SETEXISTINGSYSMEMPAGES, > + device->process->host_handle); > + set_pages_command->device = device->handle; > + set_pages_command->allocation = host_alloc->allocation; > + > + page_in = dxgalloc->pages; > + while (alloc_offset_in_pages < npages) { > + pfn = (u64 *)((char *)msg.msg + > + sizeof(*set_pages_command)); > + pages_to_send = min(npages - alloc_offset_in_pages, > + max_pfns_in_message); > + set_pages_command->num_pages = pages_to_send; > + set_pages_command->alloc_offset_in_pages = > + alloc_offset_in_pages; > + > + for (i = 0; i < pages_to_send; i++) > + *pfn++ = page_to_pfn(*page_in++); > + > + ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, > + msg.hdr, > + msg.size); > + if (ret < 0) { > + pr_err("failed to set existing pages: %x", ret); > + break; > + } > + alloc_offset_in_pages += pages_to_send; > + } > + } > > cleanup: > if (kmem) > @@ -2685,6 +2738,7 @@ int dxgvmb_send_wait_sync_object_cpu(struct dxgprocess *process, > struct > d3dkmt_waitforsynchronizationobjectfromcpu > *args, > + bool user_address, > u64 cpu_event) > { > int ret = -EINVAL; > @@ -2708,18 +2762,25 @@ int dxgvmb_send_wait_sync_object_cpu(struct dxgprocess *process, > command->object_count = args->object_count; > command->guest_event_pointer = (u64) cpu_event; > current_pos = (u8 *) &command[1]; > - ret = copy_from_user(current_pos, args->objects, object_size); > - if (ret) { > - pr_err("%s failed to copy objects", __func__); > - ret = -EINVAL; > - goto cleanup; > - } > - current_pos += object_size; > - ret = copy_from_user(current_pos, args->fence_values, fence_size); > - if (ret) { > - pr_err("%s failed to copy fences", __func__); > - ret = -EINVAL; > - goto cleanup; > + if (user_address) { > + ret = copy_from_user(current_pos, args->objects, object_size); > + if (ret) { > + pr_err("%s failed to copy objects", __func__); > + ret = -EINVAL; > + goto cleanup; > + } > + current_pos += object_size; > + ret = copy_from_user(current_pos, args->fence_values, > + fence_size); > + if (ret) { > + pr_err("%s failed to copy fences", __func__); > + ret = -EINVAL; > + goto cleanup; > + } > + } else { > + memcpy(current_pos, args->objects, object_size); > + current_pos += object_size; > + memcpy(current_pos, args->fence_values, fence_size); > } > > ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size); > diff --git a/drivers/hv/dxgkrnl/dxgvmbus.h b/drivers/hv/dxgkrnl/dxgvmbus.h > index a19ac804a320..dc766d95a0c4 100644 > --- a/drivers/hv/dxgkrnl/dxgvmbus.h > +++ b/drivers/hv/dxgkrnl/dxgvmbus.h > @@ -139,6 +139,8 @@ enum dxgkvmb_commandtype { > DXGK_VMBCOMMAND_GETCONTEXTSCHEDULINGPRIORITY = 61, > DXGK_VMBCOMMAND_QUERYCLOCKCALIBRATION = 62, > DXGK_VMBCOMMAND_QUERYRESOURCEINFO = 64, > + DXGK_VMBCOMMAND_LOGEVENT = 65, > + DXGK_VMBCOMMAND_SETEXISTINGSYSMEMPAGES = 66, > DXGK_VMBCOMMAND_INVALID > }; > > @@ -245,6 +247,16 @@ struct dxgkvmb_command_setexistingsysmemstore { > u32 gpadl; > }; > > +/* Returns ntstatus */ > +struct dxgkvmb_command_setexistingsysmempages { > + struct dxgkvmb_command_vgpu_to_host hdr; > + struct d3dkmthandle device; > + struct d3dkmthandle allocation; > + u32 num_pages; > + u32 alloc_offset_in_pages; > + /* u64 pfn_array[num_pages] */ > +}; > + > struct dxgkvmb_command_createprocess { > struct dxgkvmb_command_vm_to_host hdr; > void *process; > diff --git a/drivers/hv/dxgkrnl/ioctl.c b/drivers/hv/dxgkrnl/ioctl.c > index 9770fabf163e..9236b6b95973 100644 > --- a/drivers/hv/dxgkrnl/ioctl.c > +++ b/drivers/hv/dxgkrnl/ioctl.c > @@ -19,6 +19,7 @@ > > #include "dxgkrnl.h" > #include "dxgvmbus.h" > +#include "dxgsyncfile.h" > > #undef pr_fmt > #define pr_fmt(fmt) "dxgk:err: " fmt > @@ -32,11 +33,6 @@ struct ioctl_desc { > }; > static struct ioctl_desc ioctls[LX_IO_MAX + 1]; > > -static char *errorstr(int ret) > -{ > - return ret < 0 ? "err" : ""; > -} > - > static int dxgsyncobj_release(struct inode *inode, struct file *file) > { > struct dxgsharedsyncobject *syncobj = file->private_data; > @@ -3561,7 +3557,7 @@ dxgk_wait_sync_object_cpu(struct dxgprocess *process, void *__user inargs) > } > > ret = dxgvmb_send_wait_sync_object_cpu(process, adapter, > - &args, event_id); > + &args, true, event_id); > if (ret < 0) > goto cleanup; > > @@ -5457,4 +5453,6 @@ void init_ioctls(void) > LX_DXQUERYSTATISTICS); > SET_IOCTL(/*0x44 */ dxgk_share_object_with_host, > LX_DXSHAREOBJECTWITHHOST); > + SET_IOCTL(/*0x45 */ dxgk_create_sync_file, > + LX_DXCREATESYNCFILE); > } > diff --git a/drivers/hv/dxgkrnl/misc.c b/drivers/hv/dxgkrnl/misc.c > index ffb491641836..1b152c269265 100644 > --- a/drivers/hv/dxgkrnl/misc.c > +++ b/drivers/hv/dxgkrnl/misc.c > @@ -35,3 +35,9 @@ u16 *wcsncpy(u16 *dest, const u16 *src, size_t n) > dest[i - 1] = 0; > return dest; > } > + > +char *errorstr(int ret) > +{ > + return ret < 0 ? "err" : ""; > +} > + > diff --git a/drivers/hv/dxgkrnl/misc.h b/drivers/hv/dxgkrnl/misc.h > index 7fe3fc45b67c..3079dd55c7a4 100644 > --- a/drivers/hv/dxgkrnl/misc.h > +++ b/drivers/hv/dxgkrnl/misc.h > @@ -44,6 +44,7 @@ extern const struct d3dkmthandle zerohandle; > */ > > u16 *wcsncpy(u16 *dest, const u16 *src, size_t n); > +char *errorstr(int ret); > > enum dxglockstate { > DXGLOCK_SHARED, > -- > 2.32.0 > -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch