<div class="__aliyun_email_body_block"><div  style="line-height:1.7;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;"><div  style="clear:both;"><br ></div><div  style="clear:both;">Hi Felix,</div><div  style="clear:both;"><br ></div><div  style="clear:both;">Following your thread, you mentioned many times that SVM API cannot run in virtualization env, I still don't get it why.</div><div  style="clear:both;">Why you often said need a host proxy process? Cannot HW report page fault interrupt per VF via vfid? Isn't it sriov env?</div><div  style="clear:both;"><br ></div><div  style="clear:both;">Regargs,</div><div  style="clear:both;">-Chunming</div><blockquote  style="margin-right:.0px;margin-top:.0px;margin-bottom:.0px;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;"><div  style="clear:both;">------------------------------------------------------------------</div><div  style="clear:both;">发件人:Felix Kuehling <felix.kuehling@amd.com></div><div  style="clear:both;">发送时间:2024年1月30日(星期二) 04:24</div><div  style="clear:both;">收件人:"Christian König" <christian.koenig@amd.com>; Daniel Vetter <daniel@ffwll.ch></div><div  style="clear:both;">抄 送:"Brost, Matthew" <matthew.brost@intel.com>; Thomas.Hellstrom@linux.intel.com <Thomas.Hellstrom@linux.intel.com>; "Welty, Brian" <brian.welty@intel.com>; "Ghimiray, Himal Prasad" <himal.prasad.ghimiray@intel.com>; dri-devel@lists.freedesktop.org <dri-devel@lists.freedesktop.org>; "Gupta, saurabhg" <saurabhg.gupta@intel.com>; Danilo Krummrich <dakr@redhat.com>; "Zeng, Oak" <oak.zeng@intel.com>; "Bommu, Krishnaiah" <krishnaiah.bommu@intel.com>; Dave Airlie <airlied@redhat.com>; "Vishwanathapura, Niranjana" <niranjana.vishwanathapura@intel.com>; intel-xe@lists.freedesktop.org <intel-xe@lists.freedesktop.org></div><div  style="clear:both;">主 题:Re: Making drm_gpuvm work across gpu devices</div><div  style="clear:both;"><br ></div><br >On 2024-01-29 14:03, Christian König wrote:<br >> Am 29.01.24 um 18:52 schrieb Felix Kuehling:<br >>> On 2024-01-29 11:28, Christian König wrote:<br >>>> Am 29.01.24 um 17:24 schrieb Felix Kuehling:<br >>>>> On 2024-01-29 10:33, Christian König wrote:<br >>>>>> Am 29.01.24 um 16:03 schrieb Felix Kuehling:<br >>>>>>> On 2024-01-25 13:32, Daniel Vetter wrote:<br >>>>>>>> On Wed, Jan 24, 2024 at 09:33:12AM +0100, Christian König wrote:<br >>>>>>>>> Am 23.01.24 um 20:37 schrieb Zeng, Oak:<br >>>>>>>>>> [SNIP]<br >>>>>>>>>> Yes most API are per device based.<br >>>>>>>>>><br >>>>>>>>>> One exception I know is actually the kfd SVM API. If you look <br >>>>>>>>>> at the svm_ioctl function, it is per-process based. Each <br >>>>>>>>>> kfd_process represent a process across N gpu devices.<br >>>>>>>>> Yeah and that was a big mistake in my opinion. We should really <br >>>>>>>>> not do that<br >>>>>>>>> ever again.<br >>>>>>>>><br >>>>>>>>>> Need to say, kfd SVM represent a shared virtual address space <br >>>>>>>>>> across CPU and all GPU devices on the system. This is by the <br >>>>>>>>>> definition of SVM (shared virtual memory). This is very <br >>>>>>>>>> different from our legacy gpu *device* driver which works for <br >>>>>>>>>> only one device (i.e., if you want one device to access <br >>>>>>>>>> another device's memory, you will have to use dma-buf <br >>>>>>>>>> export/import etc).<br >>>>>>>>> Exactly that thinking is what we have currently found as <br >>>>>>>>> blocker for a<br >>>>>>>>> virtualization projects. Having SVM as device independent <br >>>>>>>>> feature which<br >>>>>>>>> somehow ties to the process address space turned out to be an <br >>>>>>>>> extremely bad<br >>>>>>>>> idea.<br >>>>>>>>><br >>>>>>>>> The background is that this only works for some use cases but <br >>>>>>>>> not all of<br >>>>>>>>> them.<br >>>>>>>>><br >>>>>>>>> What's working much better is to just have a mirror <br >>>>>>>>> functionality which says<br >>>>>>>>> that a range A..B of the process address space is mapped into a <br >>>>>>>>> range C..D<br >>>>>>>>> of the GPU address space.<br >>>>>>>>><br >>>>>>>>> Those ranges can then be used to implement the SVM feature <br >>>>>>>>> required for<br >>>>>>>>> higher level APIs and not something you need at the UAPI or <br >>>>>>>>> even inside the<br >>>>>>>>> low level kernel memory management.<br >>>>>>>>><br >>>>>>>>> When you talk about migrating memory to a device you also do <br >>>>>>>>> this on a per<br >>>>>>>>> device basis and *not* tied to the process address space. If <br >>>>>>>>> you then get<br >>>>>>>>> crappy performance because userspace gave contradicting <br >>>>>>>>> information where to<br >>>>>>>>> migrate memory then that's a bug in userspace and not something <br >>>>>>>>> the kernel<br >>>>>>>>> should try to prevent somehow.<br >>>>>>>>><br >>>>>>>>> [SNIP]<br >>>>>>>>>>> I think if you start using the same drm_gpuvm for multiple <br >>>>>>>>>>> devices you<br >>>>>>>>>>> will sooner or later start to run into the same mess we have <br >>>>>>>>>>> seen with<br >>>>>>>>>>> KFD, where we moved more and more functionality from the KFD <br >>>>>>>>>>> to the DRM<br >>>>>>>>>>> render node because we found that a lot of the stuff simply <br >>>>>>>>>>> doesn't work<br >>>>>>>>>>> correctly with a single object to maintain the state.<br >>>>>>>>>> As I understand it, KFD is designed to work across devices. A <br >>>>>>>>>> single pseudo /dev/kfd device represent all hardware gpu <br >>>>>>>>>> devices. That is why during kfd open, many pdd (process device <br >>>>>>>>>> data) is created, each for one hardware device for this process.<br >>>>>>>>> Yes, I'm perfectly aware of that. And I can only repeat myself <br >>>>>>>>> that I see<br >>>>>>>>> this design as a rather extreme failure. And I think it's one <br >>>>>>>>> of the reasons<br >>>>>>>>> why NVidia is so dominant with Cuda.<br >>>>>>>>><br >>>>>>>>> This whole approach KFD takes was designed with the idea of <br >>>>>>>>> extending the<br >>>>>>>>> CPU process into the GPUs, but this idea only works for a few <br >>>>>>>>> use cases and<br >>>>>>>>> is not something we should apply to drivers in general.<br >>>>>>>>><br >>>>>>>>> A very good example are virtualization use cases where you end <br >>>>>>>>> up with CPU<br >>>>>>>>> address != GPU address because the VAs are actually coming from <br >>>>>>>>> the guest VM<br >>>>>>>>> and not the host process.<br >>>>>>>>><br >>>>>>>>> SVM is a high level concept of OpenCL, Cuda, ROCm etc.. This <br >>>>>>>>> should not have<br >>>>>>>>> any influence on the design of the kernel UAPI.<br >>>>>>>>><br >>>>>>>>> If you want to do something similar as KFD for Xe I think you <br >>>>>>>>> need to get<br >>>>>>>>> explicit permission to do this from Dave and Daniel and maybe <br >>>>>>>>> even Linus.<br >>>>>>>> I think the one and only one exception where an SVM uapi like in <br >>>>>>>> kfd makes<br >>>>>>>> sense, is if the _hardware_ itself, not the software stack defined<br >>>>>>>> semantics that you've happened to build on top of that hw, <br >>>>>>>> enforces a 1:1<br >>>>>>>> mapping with the cpu process address space.<br >>>>>>>><br >>>>>>>> Which means your hardware is using PASID, IOMMU based <br >>>>>>>> translation, PCI-ATS<br >>>>>>>> (address translation services) or whatever your hw calls it and <br >>>>>>>> has _no_<br >>>>>>>> device-side pagetables on top. Which from what I've seen all <br >>>>>>>> devices with<br >>>>>>>> device-memory have, simply because they need some place to store <br >>>>>>>> whether<br >>>>>>>> that memory is currently in device memory or should be <br >>>>>>>> translated using<br >>>>>>>> PASID. Currently there's no gpu that works with PASID only, but <br >>>>>>>> there are<br >>>>>>>> some on-cpu-die accelerator things that do work like that.<br >>>>>>>><br >>>>>>>> Maybe in the future there will be some accelerators that are <br >>>>>>>> fully cpu<br >>>>>>>> cache coherent (including atomics) with something like CXL, and the<br >>>>>>>> on-device memory is managed as normal system memory with struct <br >>>>>>>> page as<br >>>>>>>> ZONE_DEVICE and accelerator va -> physical address translation <br >>>>>>>> is only<br >>>>>>>> done with PASID ... but for now I haven't seen that, definitely <br >>>>>>>> not in<br >>>>>>>> upstream drivers.<br >>>>>>>><br >>>>>>>> And the moment you have some per-device pagetables or per-device <br >>>>>>>> memory<br >>>>>>>> management of some sort (like using gpuva mgr) then I'm 100% <br >>>>>>>> agreeing with<br >>>>>>>> Christian that the kfd SVM model is too strict and not a great <br >>>>>>>> idea.<br >>>>>>><br >>>>>>> That basically means, without ATS/PRI+PASID you cannot implement <br >>>>>>> a unified memory programming model, where GPUs or accelerators <br >>>>>>> access virtual addresses without pre-registering them with an SVM <br >>>>>>> API call.<br >>>>>>><br >>>>>>> Unified memory is a feature implemented by the KFD SVM API and <br >>>>>>> used by ROCm. This is used e.g. to implement OpenMP USM (unified <br >>>>>>> shared memory). It's implemented with recoverable GPU page <br >>>>>>> faults. If the page fault interrupt handler cannot assume a <br >>>>>>> shared virtual address space, then implementing this feature <br >>>>>>> isn't possible.<br >>>>>><br >>>>>> Why not? As far as I can see the OpenMP USM is just another funky <br >>>>>> way of userptr handling.<br >>>>>><br >>>>>> The difference is that in an userptr we assume that we always need <br >>>>>> to request the whole block A..B from a mapping while for page <br >>>>>> fault based handling it can be just any page in between A and B <br >>>>>> which is requested and made available to the GPU address space.<br >>>>>><br >>>>>> As far as I can see there is absolutely no need for any special <br >>>>>> SVM handling.<br >>>>><br >>>>> It does assume a shared virtual address space between CPU and GPUs. <br >>>>> There are no API calls to tell the driver that address A on the CPU <br >>>>> maps to address B on the GPU1 and address C on GPU2. The KFD SVM <br >>>>> API was designed to work with this programming model, by augmenting <br >>>>> the shared virtual address mappings with virtual address range <br >>>>> attributes that can modify the migration policy and indicate <br >>>>> prefetching, prefaulting, etc. You could think of it as madvise on <br >>>>> steroids.<br >>>><br >>>> Yeah, so what? In this case you just say through an IOCTL that CPU <br >>>> range A..B should map to GPU range C..D and for A/B and C/D you use <br >>>> the maximum of the address space.<br >>><br >>> What I want is that address range A..B on the CPU matches A..B on the <br >>> GPU, because I'm sharing pointers between CPU and GPU. I can't think <br >>> of any sane user mode using a unified memory programming model, that <br >>> would ever ask KFD to map unified memory mappints to a different <br >>> address range on the GPU. Adding such an ioclt is a complete waste of <br >>> time, and can only serve to add unnecessary complexity.<br >><br >> This is exactly the use case which happens when the submitting process <br >> is not the one originally stitching together the command stream.<br >><br >> Basically all native context, virtualization and other proxy use cases <br >> work like this.<br ><br >You cannot use unified memory in this type of environment. A GPU page <br >fault would occur in a GPU virtual address space in the host-side proxy <br >process. That page fault would need to be resolved to map some memory <br >from a process running in a guest? Which guest? Which process? That's <br >anyone's guess. There is no way to annotate that because the pointer in <br >the fault is coming from a shader program that's running in the guest <br >context and competely unaware of the virtualization. There are no API <br >calls from the guest before the fault occurs to establish a meaningful <br >mapping.<br ><br >The way this virtualization of the GPU is implemented, with out proxy <br >multiplexing multiple clients is just fundamentally incompatible with a <br >unified memory programming model that has to assume a shared virtual <br >address space to make sense. You'd need separate proxy processes on the <br >host side to handle that. You can't blame this on bad design decisions <br >in the SVM API. As I see it, it's just a fundamental limitation of the <br >virtualization approach that cannot handle guest applications that want <br >to use a unified shared memory programming model.<br ><br >That's why I suggested to completely disable the SVM API in this <br >virtualization scenario when you create a KFD context that's separate <br >from the process address space. It is not essential for any <br >non-unified-memory functionality. ROCm user mode has fallbacks to work <br >without it, because we also needs to support older kernels and GPUs that <br >didn't support this programming model.<br ><br >Regards,<br >   Felix<br ><br ><br >><br >> So that the CPU address doesn't match the GPU address is an absolutely <br >> real use case and should be able to be handled by the GPU VA interface.<br >><br >> Regards,<br >> Christian.<br >><br >><br >><br >>><br >>> Regards,<br >>>   Felix<br >>><br >>><br >>>><br >>>> There is no restriction that this needs to be accurate in way. It's <br >>>> just the it can be accurate to be more efficient and eventually use <br >>>> only a fraction of the address space instead of all of it for some <br >>>> use cases.<br >>>><br >>>> So this isn't a blocker, it's just one special use case.<br >>>><br >>>> Regards,<br >>>> Christian.<br >>>><br >>>>><br >>>>> Regards,<br >>>>>   Felix<br >>>>><br >>>>><br >>>>>><br >>>>>> Regards,<br >>>>>> Christian.<br >>>>>><br >>>>>>><br >>>>>>> Regards,<br >>>>>>>   Felix<br >>>>>>><br >>>>>>><br >>>>>>>><br >>>>>>>> Cheers, Sima<br >>>>>><br >>>><br >></blockquote></div></div>