Re: [Nouveau] [PATCH v7 6/8] PCI/VGA: Introduce is_boot_device function callback to vga_client_register
Hi, On 2023/6/30 01:44, Limonciello, Mario wrote: I think what you can do is pick up all the tags in your next version. Once the whole series has tags we can discuss how it merges. Yes, you are right. I will prepare the next version. But I think, I should only gather the reverent part together. I means that I probably should divide the 8 patches in V7 into 4 + 4. The first four patch form a group, and the last four patch form another group. Certainly, I will pick up the precious tags I got in the next version. Thanks you!
Re: [Nouveau] [PATCH v7 6/8] PCI/VGA: Introduce is_boot_device function callback to vga_client_register
Hi, On 2023/6/30 01:44, Limonciello, Mario wrote: [Public] -Original Message- From: 15330273...@189.cn <15330273...@189.cn> Sent: Thursday, June 29, 2023 12:00 PM To: Bjorn Helgaas ; Sui Jingfeng Cc: Bjorn Helgaas ; linux-fb...@vger.kernel.org; Cornelia Huck ; Karol Herbst ; nouveau@lists.freedesktop.org; Joonas Lahtinen ; dri-de...@lists.freedesktop.org; Chai, Thomas ; Limonciello, Mario ; Gao, Likun ; David Airlie ; Ville Syrjala ; Yi Liu ; k...@vger.kernel.org; amd-...@lists.freedesktop.org; Jason Gunthorpe ; Ben Skeggs ; linux- p...@vger.kernel.org; Kevin Tian ; Lazar, Lijo ; Thomas Zimmermann ; Zhang, Bokun ; intel-...@lists.freedesktop.org; Maarten Lankhorst ; Jani Nikula ; Alex Williamson ; Abhishek Sahu ; Maxime Ripard ; Rodrigo Vivi ; Tvrtko Ursulin ; Yishai Hadas ; Pan, Xinhui ; linux- ker...@vger.kernel.org; Daniel Vetter ; Deucher, Alexander ; Koenig, Christian ; Zhang, Hawking Subject: Re: [PATCH v7 6/8] PCI/VGA: Introduce is_boot_device function callback to vga_client_register Hi, On 2023/6/29 23:54, Bjorn Helgaas wrote: On Thu, Jun 22, 2023 at 01:08:15PM +0800, Sui Jingfeng wrote: Hi, A nouveau developer(Lyude) from redhat send me a R-B, Thanks for the developers of nouveau project. Please allow me add a link[1] here. [1] https://lore.kernel.org/all/0afadc69f99a36bc9d03ecf54ff25859dbc10e28.ca m...@redhat.com/ 1) Thanks for this. If you post another version of this series, please pick up Lyude's Reviewed-by and include it in the relevant patches (as long as you haven't made significant changes to the code Lyude reviewed). Yes, no significant changes. Just fix typo. I also would like to add support for other DRM drivers. But I think this deserve another patch. Whoever applies this should automatically pick up Reviewed-by/Ack/etc that are replies to the version being applied, but they won't go through previous revisions to find them. 2) Please mention the commit to which the series applies. I tried to apply this on v6.4-rc1, but it doesn't apply cleanly. Since I'm a graphic driver developer, I'm using drm-tip. I just have already pulled, it still apply cleanly on drm-tip. 3) Thanks for including cover letters in your postings. Please include a little changelog in the cover letter so we know what changed between v6 and v7, etc. No change between v6 and v7, it seems that it is because the mailbox don't allow me to sending too many mails a day. so some of the patch is failed to delivery because out of quota. 4) Right now we're in the middle of the v6.5 merge window, so new content, e.g., this series, is too late for v6.5. Most maintainers, including me, wait to merge new content until the merge window closes and a new -rc1 is tagged. This merge window should close on July 9, and people will start merging content for v6.6, typically based on v6.5-rc1. I'm wondering Would you will merge all of the patches in this series (e.g. including the patch for drm/amdgpu(7/8) and drm/radeon(8/8)) ? Or just part of them? Emm, I don't know because my patch seems across different subsystem of Linux kernel. There is also a developer for AMDGPU (Mario) give me a R-B for the patch-0002 of this series. So, at least, PATCH-0001, PATCH-0002, PATCH-0003, PATCH-0004, PATCH- 0006 are already OK(got reviewed by). Those 5 patch are already qualified to be merged, I think. I think what you can do is pick up all the tags in your next version. Once the whole series has tags we can discuss how it merges. Thanks a lot, Mario. Is it possible to merge the PCI/VGA part as fast as possible, especially the PATCH-0006 PCI/VGA: Introduce is_boot_device function callback to vga_client_register As this patch is fundamental, it introduce no functional change, as long as the drm driver side don't introduce a callback. I'm not hurry, but drm driver-side's patch have a dependency on this patch, I think it is better the PCI/VGA-side's patch got merge first. At least for get the first four cleanup(0001 ~ 0004) patch merged first, so that I don't have to send so much on the next version on one series. Being exposed so far, there no obvious objection. It saying that other people also want it got merged. Bjorn, is this OK ? I means that if you could merge those 5 patch first, then there no need to send another version again. I will refine the rest patch with more details and description. I'm fear of making too much noise. Bjorn
[Nouveau] [PATCH drm-next v6 13/13] drm/nouveau: debugfs: implement DRM GPU VA debugfs
Provide the driver indirection iterating over all DRM GPU VA spaces to enable the common 'gpuvas' debugfs file for dumping DRM GPU VA spaces. Signed-off-by: Danilo Krummrich --- drivers/gpu/drm/nouveau/nouveau_debugfs.c | 39 +++ 1 file changed, 39 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index 99d022a91afc..053f703f2f68 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c @@ -203,6 +203,44 @@ nouveau_debugfs_pstate_open(struct inode *inode, struct file *file) return single_open(file, nouveau_debugfs_pstate_get, inode->i_private); } +static void +nouveau_debugfs_gpuva_regions(struct seq_file *m, struct nouveau_uvmm *uvmm) +{ + MA_STATE(mas, >region_mt, 0, 0); + struct nouveau_uvma_region *reg; + + seq_puts (m, " VA regions | start | range | end\n"); + seq_puts (m, "\n"); + mas_for_each(, reg, ULONG_MAX) + seq_printf(m, " | 0x%016llx | 0x%016llx | 0x%016llx\n", + reg->va.addr, reg->va.range, reg->va.addr + reg->va.range); +} + +static int +nouveau_debugfs_gpuva(struct seq_file *m, void *data) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct nouveau_drm *drm = nouveau_drm(node->minor->dev); + struct nouveau_cli *cli; + + mutex_lock(>clients_lock); + list_for_each_entry(cli, >clients, head) { + struct nouveau_uvmm *uvmm = nouveau_cli_uvmm(cli); + + if (!uvmm) + continue; + + nouveau_uvmm_lock(uvmm); + drm_debugfs_gpuva_info(m, >umgr); + seq_puts(m, "\n"); + nouveau_debugfs_gpuva_regions(m, uvmm); + nouveau_uvmm_unlock(uvmm); + } + mutex_unlock(>clients_lock); + + return 0; +} + static const struct file_operations nouveau_pstate_fops = { .owner = THIS_MODULE, .open = nouveau_debugfs_pstate_open, @@ -214,6 +252,7 @@ static const struct file_operations nouveau_pstate_fops = { static struct drm_info_list nouveau_debugfs_list[] = { { "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL }, { "strap_peek", nouveau_debugfs_strap_peek, 0, NULL }, + DRM_DEBUGFS_GPUVA_INFO(nouveau_debugfs_gpuva, NULL), }; #define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list) -- 2.41.0
[Nouveau] [PATCH drm-next v6 12/13] drm/nouveau: implement new VM_BIND uAPI
This commit provides the implementation for the new uapi motivated by the Vulkan API. It allows user mode drivers (UMDs) to: 1) Initialize a GPU virtual address (VA) space via the new DRM_IOCTL_NOUVEAU_VM_INIT ioctl for UMDs to specify the portion of VA space managed by the kernel and userspace, respectively. 2) Allocate and free a VA space region as well as bind and unbind memory to the GPUs VA space via the new DRM_IOCTL_NOUVEAU_VM_BIND ioctl. UMDs can request the named operations to be processed either synchronously or asynchronously. It supports DRM syncobjs (incl. timelines) as synchronization mechanism. The management of the GPU VA mappings is implemented with the DRM GPU VA manager. 3) Execute push buffers with the new DRM_IOCTL_NOUVEAU_EXEC ioctl. The execution happens asynchronously. It supports DRM syncobj (incl. timelines) as synchronization mechanism. DRM GEM object locking is handled with drm_exec. Both, DRM_IOCTL_NOUVEAU_VM_BIND and DRM_IOCTL_NOUVEAU_EXEC, use the DRM GPU scheduler for the asynchronous paths. Signed-off-by: Danilo Krummrich --- Documentation/gpu/driver-uapi.rst |3 + drivers/gpu/drm/nouveau/Kbuild |3 + drivers/gpu/drm/nouveau/Kconfig |2 + drivers/gpu/drm/nouveau/nouveau_abi16.c | 24 + drivers/gpu/drm/nouveau/nouveau_abi16.h |1 + drivers/gpu/drm/nouveau/nouveau_bo.c| 147 +- drivers/gpu/drm/nouveau/nouveau_bo.h|2 +- drivers/gpu/drm/nouveau/nouveau_drm.c | 27 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 59 +- drivers/gpu/drm/nouveau/nouveau_exec.c | 414 + drivers/gpu/drm/nouveau/nouveau_exec.h | 54 + drivers/gpu/drm/nouveau/nouveau_gem.c | 25 +- drivers/gpu/drm/nouveau/nouveau_mem.h |5 + drivers/gpu/drm/nouveau/nouveau_prime.c |2 +- drivers/gpu/drm/nouveau/nouveau_sched.c | 462 ++ drivers/gpu/drm/nouveau/nouveau_sched.h | 123 ++ drivers/gpu/drm/nouveau/nouveau_uvmm.c | 1970 +++ drivers/gpu/drm/nouveau/nouveau_uvmm.h | 107 ++ 18 files changed, 3365 insertions(+), 65 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nouveau_exec.c create mode 100644 drivers/gpu/drm/nouveau/nouveau_exec.h create mode 100644 drivers/gpu/drm/nouveau/nouveau_sched.c create mode 100644 drivers/gpu/drm/nouveau/nouveau_sched.h create mode 100644 drivers/gpu/drm/nouveau/nouveau_uvmm.c create mode 100644 drivers/gpu/drm/nouveau/nouveau_uvmm.h diff --git a/Documentation/gpu/driver-uapi.rst b/Documentation/gpu/driver-uapi.rst index 9c7ca6e33a68..c08bcbb95fb3 100644 --- a/Documentation/gpu/driver-uapi.rst +++ b/Documentation/gpu/driver-uapi.rst @@ -13,4 +13,7 @@ drm/nouveau uAPI VM_BIND / EXEC uAPI --- +.. kernel-doc:: drivers/gpu/drm/nouveau/nouveau_exec.c +:doc: Overview + .. kernel-doc:: include/uapi/drm/nouveau_drm.h diff --git a/drivers/gpu/drm/nouveau/Kbuild b/drivers/gpu/drm/nouveau/Kbuild index 5e5617006da5..cf6b3a80c0c8 100644 --- a/drivers/gpu/drm/nouveau/Kbuild +++ b/drivers/gpu/drm/nouveau/Kbuild @@ -47,6 +47,9 @@ nouveau-y += nouveau_prime.o nouveau-y += nouveau_sgdma.o nouveau-y += nouveau_ttm.o nouveau-y += nouveau_vmm.o +nouveau-y += nouveau_exec.o +nouveau-y += nouveau_sched.o +nouveau-y += nouveau_uvmm.o # DRM - modesetting nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index a70bd65e1400..c52e8096cca4 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -10,6 +10,8 @@ config DRM_NOUVEAU select DRM_KMS_HELPER select DRM_TTM select DRM_TTM_HELPER + select DRM_EXEC + select DRM_SCHED select I2C select I2C_ALGOBIT select BACKLIGHT_CLASS_DEVICE if DRM_NOUVEAU_BACKLIGHT diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 82dab51d8aeb..a112f28681d3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -35,6 +35,7 @@ #include "nouveau_chan.h" #include "nouveau_abi16.h" #include "nouveau_vmm.h" +#include "nouveau_sched.h" static struct nouveau_abi16 * nouveau_abi16(struct drm_file *file_priv) @@ -125,6 +126,17 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16, { struct nouveau_abi16_ntfy *ntfy, *temp; + /* When a client exits without waiting for it's queued up jobs to +* finish it might happen that we fault the channel. This is due to +* drm_file_free() calling drm_gem_release() before the postclose() +* callback. Hence, we can't tear down this scheduler entity before +* uvmm mappings are unmapped. Currently, we can't detect this case. +* +* However, this should be rare and harmless, since the channel isn't +* needed anymore. +*/ + nouveau_sched_entity_fini(>sched_entity); + /* wait for all activity to
[Nouveau] [PATCH drm-next v6 11/13] drm/nouveau: nvkm/vmm: implement raw ops to manage uvmm
The new VM_BIND UAPI uses the DRM GPU VA manager to manage the VA space. Hence, we a need a way to manipulate the MMUs page tables without going through the internal range allocator implemented by nvkm/vmm. This patch adds a raw interface for nvkm/vmm to pass the resposibility for managing the address space and the corresponding map/unmap/sparse operations to the upper layers. Signed-off-by: Danilo Krummrich --- drivers/gpu/drm/nouveau/include/nvif/if000c.h | 26 ++- drivers/gpu/drm/nouveau/include/nvif/vmm.h| 19 +- .../gpu/drm/nouveau/include/nvkm/subdev/mmu.h | 20 +- drivers/gpu/drm/nouveau/nouveau_svm.c | 2 +- drivers/gpu/drm/nouveau/nouveau_vmm.c | 4 +- drivers/gpu/drm/nouveau/nvif/vmm.c| 100 +++- .../gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c| 213 -- drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 197 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 25 ++ .../drm/nouveau/nvkm/subdev/mmu/vmmgf100.c| 16 +- .../drm/nouveau/nvkm/subdev/mmu/vmmgp100.c| 16 +- .../gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c | 27 ++- 12 files changed, 566 insertions(+), 99 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvif/if000c.h b/drivers/gpu/drm/nouveau/include/nvif/if000c.h index 9c7ff56831c5..a5a182b3c28d 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/if000c.h +++ b/drivers/gpu/drm/nouveau/include/nvif/if000c.h @@ -3,7 +3,10 @@ struct nvif_vmm_v0 { __u8 version; __u8 page_nr; - __u8 managed; +#define NVIF_VMM_V0_TYPE_UNMANAGED 0x00 +#define NVIF_VMM_V0_TYPE_MANAGED 0x01 +#define NVIF_VMM_V0_TYPE_RAW 0x02 + __u8 type; __u8 pad03[5]; __u64 addr; __u64 size; @@ -17,6 +20,7 @@ struct nvif_vmm_v0 { #define NVIF_VMM_V0_UNMAP 0x04 #define NVIF_VMM_V0_PFNMAP 0x05 #define NVIF_VMM_V0_PFNCLR 0x06 +#define NVIF_VMM_V0_RAW0x07 #define NVIF_VMM_V0_MTHD(i) ((i) + 0x80) struct nvif_vmm_page_v0 { @@ -66,6 +70,26 @@ struct nvif_vmm_unmap_v0 { __u64 addr; }; +struct nvif_vmm_raw_v0 { + __u8 version; +#define NVIF_VMM_RAW_V0_GET0x0 +#define NVIF_VMM_RAW_V0_PUT0x1 +#define NVIF_VMM_RAW_V0_MAP0x2 +#define NVIF_VMM_RAW_V0_UNMAP 0x3 +#define NVIF_VMM_RAW_V0_SPARSE 0x4 + __u8 op; + __u8 sparse; + __u8 ref; + __u8 shift; + __u32 argc; + __u8 pad01[7]; + __u64 addr; + __u64 size; + __u64 offset; + __u64 memory; + __u64 argv; +}; + struct nvif_vmm_pfnmap_v0 { __u8 version; __u8 page; diff --git a/drivers/gpu/drm/nouveau/include/nvif/vmm.h b/drivers/gpu/drm/nouveau/include/nvif/vmm.h index a2ee92201ace..0ecedd0ee0a5 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/vmm.h +++ b/drivers/gpu/drm/nouveau/include/nvif/vmm.h @@ -4,6 +4,12 @@ struct nvif_mem; struct nvif_mmu; +enum nvif_vmm_type { + UNMANAGED, + MANAGED, + RAW, +}; + enum nvif_vmm_get { ADDR, PTES, @@ -30,8 +36,9 @@ struct nvif_vmm { int page_nr; }; -int nvif_vmm_ctor(struct nvif_mmu *, const char *name, s32 oclass, bool managed, - u64 addr, u64 size, void *argv, u32 argc, struct nvif_vmm *); +int nvif_vmm_ctor(struct nvif_mmu *, const char *name, s32 oclass, + enum nvif_vmm_type, u64 addr, u64 size, void *argv, u32 argc, + struct nvif_vmm *); void nvif_vmm_dtor(struct nvif_vmm *); int nvif_vmm_get(struct nvif_vmm *, enum nvif_vmm_get, bool sparse, u8 page, u8 align, u64 size, struct nvif_vma *); @@ -39,4 +46,12 @@ void nvif_vmm_put(struct nvif_vmm *, struct nvif_vma *); int nvif_vmm_map(struct nvif_vmm *, u64 addr, u64 size, void *argv, u32 argc, struct nvif_mem *, u64 offset); int nvif_vmm_unmap(struct nvif_vmm *, u64); + +int nvif_vmm_raw_get(struct nvif_vmm *vmm, u64 addr, u64 size, u8 shift); +int nvif_vmm_raw_put(struct nvif_vmm *vmm, u64 addr, u64 size, u8 shift); +int nvif_vmm_raw_map(struct nvif_vmm *vmm, u64 addr, u64 size, u8 shift, +void *argv, u32 argc, struct nvif_mem *mem, u64 offset); +int nvif_vmm_raw_unmap(struct nvif_vmm *vmm, u64 addr, u64 size, + u8 shift, bool sparse); +int nvif_vmm_raw_sparse(struct nvif_vmm *vmm, u64 addr, u64 size, bool ref); #endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h index 70e7887ef4b4..2fd2f2433fc7 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mmu.h @@ -17,6 +17,7 @@
[Nouveau] [PATCH drm-next v6 08/13] drm/nouveau: fence: separate fence alloc and emit
The new (VM_BIND) UAPI exports DMA fences through DRM syncobjs. Hence, in order to emit fences within DMA fence signalling critical sections (e.g. as typically done in the DRM GPU schedulers run_job() callback) we need to separate fence allocation and fence emitting. Signed-off-by: Danilo Krummrich --- drivers/gpu/drm/nouveau/dispnv04/crtc.c | 9 - drivers/gpu/drm/nouveau/nouveau_bo.c| 52 +++-- drivers/gpu/drm/nouveau/nouveau_chan.c | 6 ++- drivers/gpu/drm/nouveau/nouveau_dmem.c | 9 +++-- drivers/gpu/drm/nouveau/nouveau_fence.c | 16 +++- drivers/gpu/drm/nouveau/nouveau_fence.h | 3 +- drivers/gpu/drm/nouveau/nouveau_gem.c | 5 ++- 7 files changed, 59 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index a6f2e681bde9..a34924523133 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -1122,11 +1122,18 @@ nv04_page_flip_emit(struct nouveau_channel *chan, PUSH_NVSQ(push, NV_SW, NV_SW_PAGE_FLIP, 0x); PUSH_KICK(push); - ret = nouveau_fence_new(chan, false, pfence); + ret = nouveau_fence_new(pfence); if (ret) goto fail; + ret = nouveau_fence_emit(*pfence, chan); + if (ret) + goto fail_fence_unref; + return 0; + +fail_fence_unref: + nouveau_fence_unref(pfence); fail: spin_lock_irqsave(>event_lock, flags); list_del(>head); diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 057bc995f19b..e9cbbf594e6f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -820,29 +820,39 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, mutex_lock(>mutex); else mutex_lock_nested(>mutex, SINGLE_DEPTH_NESTING); + ret = nouveau_fence_sync(nouveau_bo(bo), chan, true, ctx->interruptible); - if (ret == 0) { - ret = drm->ttm.move(chan, bo, bo->resource, new_reg); - if (ret == 0) { - ret = nouveau_fence_new(chan, false, ); - if (ret == 0) { - /* TODO: figure out a better solution here -* -* wait on the fence here explicitly as going through -* ttm_bo_move_accel_cleanup somehow doesn't seem to do it. -* -* Without this the operation can timeout and we'll fallback to a -* software copy, which might take several minutes to finish. -*/ - nouveau_fence_wait(fence, false, false); - ret = ttm_bo_move_accel_cleanup(bo, - >base, - evict, false, - new_reg); - nouveau_fence_unref(); - } - } + if (ret) + goto out_unlock; + + ret = drm->ttm.move(chan, bo, bo->resource, new_reg); + if (ret) + goto out_unlock; + + ret = nouveau_fence_new(); + if (ret) + goto out_unlock; + + ret = nouveau_fence_emit(fence, chan); + if (ret) { + nouveau_fence_unref(); + goto out_unlock; } + + /* TODO: figure out a better solution here +* +* wait on the fence here explicitly as going through +* ttm_bo_move_accel_cleanup somehow doesn't seem to do it. +* +* Without this the operation can timeout and we'll fallback to a +* software copy, which might take several minutes to finish. +*/ + nouveau_fence_wait(fence, false, false); + ret = ttm_bo_move_accel_cleanup(bo, >base, evict, false, + new_reg); + nouveau_fence_unref(); + +out_unlock: mutex_unlock(>mutex); return ret; } diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 1068abe41024..f47c0363683c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -62,9 +62,11 @@ nouveau_channel_idle(struct nouveau_channel *chan) struct nouveau_fence *fence = NULL; int ret; - ret = nouveau_fence_new(chan, false, ); + ret = nouveau_fence_new(); if (!ret) { - ret = nouveau_fence_wait(fence, false, false); + ret = nouveau_fence_emit(fence, chan); + if (!ret) +
[Nouveau] [PATCH drm-next v6 10/13] drm/nouveau: chan: provide nouveau_channel_kill()
The new VM_BIND UAPI implementation introduced in subsequent commits will allow asynchronous jobs processing push buffers and emitting fences. If a job times out, we need a way to recover from this situation. For now, simply kill the channel to unblock all hung up jobs and signal userspace that the device is dead on the next EXEC or VM_BIND ioctl. Signed-off-by: Danilo Krummrich --- drivers/gpu/drm/nouveau/nouveau_chan.c | 14 +++--- drivers/gpu/drm/nouveau/nouveau_chan.h | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index f47c0363683c..a975f8b0e0e5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -40,6 +40,14 @@ MODULE_PARM_DESC(vram_pushbuf, "Create DMA push buffers in VRAM"); int nouveau_vram_pushbuf; module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400); +void +nouveau_channel_kill(struct nouveau_channel *chan) +{ + atomic_set(>killed, 1); + if (chan->fence) + nouveau_fence_context_kill(chan->fence, -ENODEV); +} + static int nouveau_channel_killed(struct nvif_event *event, void *repv, u32 repc) { @@ -47,9 +55,9 @@ nouveau_channel_killed(struct nvif_event *event, void *repv, u32 repc) struct nouveau_cli *cli = (void *)chan->user.client; NV_PRINTK(warn, cli, "channel %d killed!\n", chan->chid); - atomic_set(>killed, 1); - if (chan->fence) - nouveau_fence_context_kill(chan->fence, -ENODEV); + + if (unlikely(!atomic_read(>killed))) + nouveau_channel_kill(chan); return NVIF_EVENT_DROP; } diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h index e06a8ffed31a..e483f4a254da 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.h +++ b/drivers/gpu/drm/nouveau/nouveau_chan.h @@ -65,6 +65,7 @@ int nouveau_channel_new(struct nouveau_drm *, struct nvif_device *, bool priv, u32 vram, u32 gart, struct nouveau_channel **); void nouveau_channel_del(struct nouveau_channel **); int nouveau_channel_idle(struct nouveau_channel *); +void nouveau_channel_kill(struct nouveau_channel *); extern int nouveau_vram_pushbuf; -- 2.41.0
[Nouveau] [PATCH drm-next v6 09/13] drm/nouveau: fence: fail to emit when fence context is killed
The new VM_BIND UAPI implementation introduced in subsequent commits will allow asynchronous jobs processing push buffers and emitting fences. If a fence context is killed, e.g. due to a channel fault, jobs which are already queued for execution might still emit new fences. In such a case a job would hang forever. To fix that, fail to emit a new fence on a killed fence context with -ENODEV to unblock the job. Signed-off-by: Danilo Krummrich --- drivers/gpu/drm/nouveau/nouveau_fence.c | 7 +++ drivers/gpu/drm/nouveau/nouveau_fence.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index e946408f945b..77c739a55b19 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -96,6 +96,7 @@ nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error) if (nouveau_fence_signal(fence)) nvif_event_block(>event); } + fctx->killed = 1; spin_unlock_irqrestore(>lock, flags); } @@ -229,6 +230,12 @@ nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan) dma_fence_get(>base); spin_lock_irq(>lock); + if (unlikely(fctx->killed)) { + spin_unlock_irq(>lock); + dma_fence_put(>base); + return -ENODEV; + } + if (nouveau_fence_update(chan, fctx)) nvif_event_block(>event); diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h index 7c73c7c9834a..2c72d96ef17d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h @@ -44,7 +44,7 @@ struct nouveau_fence_chan { char name[32]; struct nvif_event event; - int notify_ref, dead; + int notify_ref, dead, killed; }; struct nouveau_fence_priv { -- 2.41.0
[Nouveau] [PATCH drm-next v6 07/13] drm/nouveau: move usercopy helpers to nouveau_drv.h
Move the usercopy helpers to a common driver header file to make it usable for the new API added in subsequent commits. Signed-off-by: Danilo Krummrich --- drivers/gpu/drm/nouveau/nouveau_drv.h | 26 ++ drivers/gpu/drm/nouveau/nouveau_gem.c | 26 -- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 81350e685b50..20a7f31b9082 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -130,6 +130,32 @@ nouveau_cli(struct drm_file *fpriv) return fpriv ? fpriv->driver_priv : NULL; } +static inline void +u_free(void *addr) +{ + kvfree(addr); +} + +static inline void * +u_memcpya(uint64_t user, unsigned nmemb, unsigned size) +{ + void *mem; + void __user *userptr = (void __force __user *)(uintptr_t)user; + + size *= nmemb; + + mem = kvmalloc(size, GFP_KERNEL); + if (!mem) + return ERR_PTR(-ENOMEM); + + if (copy_from_user(mem, userptr, size)) { + u_free(mem); + return ERR_PTR(-EFAULT); + } + + return mem; +} + #include #include diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 45ca4eb98f54..a48f42aaeab9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -613,32 +613,6 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, return 0; } -static inline void -u_free(void *addr) -{ - kvfree(addr); -} - -static inline void * -u_memcpya(uint64_t user, unsigned nmemb, unsigned size) -{ - void *mem; - void __user *userptr = (void __force __user *)(uintptr_t)user; - - size *= nmemb; - - mem = kvmalloc(size, GFP_KERNEL); - if (!mem) - return ERR_PTR(-ENOMEM); - - if (copy_from_user(mem, userptr, size)) { - u_free(mem); - return ERR_PTR(-EFAULT); - } - - return mem; -} - static int nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, struct drm_nouveau_gem_pushbuf *req, -- 2.41.0
[Nouveau] [PATCH drm-next v6 05/13] drm/nouveau: get vmm via nouveau_cli_vmm()
Provide a getter function for the client's current vmm context. Since we'll add a new (u)vmm context for UMD bindings in subsequent commits, this will keep the code clean. Signed-off-by: Danilo Krummrich --- drivers/gpu/drm/nouveau/nouveau_bo.c | 2 +- drivers/gpu/drm/nouveau/nouveau_chan.c | 2 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 9 + drivers/gpu/drm/nouveau/nouveau_gem.c | 6 +++--- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index c2ec91cc845d..7724fe63067d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -204,7 +204,7 @@ nouveau_bo_alloc(struct nouveau_cli *cli, u64 *size, int *align, u32 domain, struct nouveau_drm *drm = cli->drm; struct nouveau_bo *nvbo; struct nvif_mmu *mmu = >mmu; - struct nvif_vmm *vmm = cli->svm.cli ? >svm.vmm : >vmm.vmm; + struct nvif_vmm *vmm = _cli_vmm(cli)->vmm; int i, pi = -1; if (!*size) { diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index e648ecd0c1a0..1068abe41024 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -148,7 +148,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, chan->device = device; chan->drm = drm; - chan->vmm = cli->svm.cli ? >svm : >vmm; + chan->vmm = nouveau_cli_vmm(cli); atomic_set(>killed, 0); /* allocate memory for dma push buffer */ diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index b5de312a523f..81350e685b50 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -112,6 +112,15 @@ struct nouveau_cli_work { struct dma_fence_cb cb; }; +static inline struct nouveau_vmm * +nouveau_cli_vmm(struct nouveau_cli *cli) +{ + if (cli->svm.cli) + return >svm; + + return >vmm; +} + void nouveau_cli_work_queue(struct nouveau_cli *, struct dma_fence *, struct nouveau_cli_work *); diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index ab9062e50977..45ca4eb98f54 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -103,7 +103,7 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) struct nouveau_bo *nvbo = nouveau_gem_object(gem); struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); struct device *dev = drm->dev->dev; - struct nouveau_vmm *vmm = cli->svm.cli ? >svm : >vmm; + struct nouveau_vmm *vmm = nouveau_cli_vmm(cli); struct nouveau_vma *vma; int ret; @@ -180,7 +180,7 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) struct nouveau_bo *nvbo = nouveau_gem_object(gem); struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); struct device *dev = drm->dev->dev; - struct nouveau_vmm *vmm = cli->svm.cli ? >svm : & cli->vmm; + struct nouveau_vmm *vmm = nouveau_cli_vmm(cli); struct nouveau_vma *vma; int ret; @@ -269,7 +269,7 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem, { struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_bo *nvbo = nouveau_gem_object(gem); - struct nouveau_vmm *vmm = cli->svm.cli ? >svm : >vmm; + struct nouveau_vmm *vmm = nouveau_cli_vmm(cli); struct nouveau_vma *vma; if (is_power_of_2(nvbo->valid_domains)) -- 2.41.0
[Nouveau] [PATCH drm-next v6 06/13] drm/nouveau: bo: initialize GEM GPU VA interface
Initialize the GEM's DRM GPU VA manager interface in preparation for the (u)vmm implementation, provided by subsequent commits, to make use of it. Signed-off-by: Danilo Krummrich --- drivers/gpu/drm/nouveau/nouveau_bo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 7724fe63067d..057bc995f19b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -215,11 +215,14 @@ nouveau_bo_alloc(struct nouveau_cli *cli, u64 *size, int *align, u32 domain, nvbo = kzalloc(sizeof(struct nouveau_bo), GFP_KERNEL); if (!nvbo) return ERR_PTR(-ENOMEM); + INIT_LIST_HEAD(>head); INIT_LIST_HEAD(>entry); INIT_LIST_HEAD(>vma_list); nvbo->bo.bdev = >ttm.bdev; + drm_gem_gpuva_init(>bo.base); + /* This is confusing, and doesn't actually mean we want an uncached * mapping, but is what NOUVEAU_GEM_DOMAIN_COHERENT gets translated * into in nouveau_gem_new(). -- 2.41.0
[Nouveau] [PATCH drm-next v6 03/13] drm: debugfs: provide infrastructure to dump a DRM GPU VA space
This commit adds a function to dump a DRM GPU VA space and a macro for drivers to register the struct drm_info_list 'gpuvas' entry. Most likely, most drivers might maintain one DRM GPU VA space per struct drm_file, but there might also be drivers not having a fixed relation between DRM GPU VA spaces and a DRM core infrastructure, hence we need the indirection via the driver iterating it's maintained DRM GPU VA spaces. Reviewed-by: Boris Brezillon Signed-off-by: Danilo Krummrich --- drivers/gpu/drm/drm_debugfs.c | 40 +++ include/drm/drm_debugfs.h | 25 ++ 2 files changed, 65 insertions(+) diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 4855230ba2c6..c90dbcffa0dc 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "drm_crtc_internal.h" #include "drm_internal.h" @@ -175,6 +176,45 @@ static const struct file_operations drm_debugfs_fops = { .release = single_release, }; +/** + * drm_debugfs_gpuva_info - dump the given DRM GPU VA space + * @m: pointer to the _file to write + * @mgr: the _gpuva_manager representing the GPU VA space + * + * Dumps the GPU VA mappings of a given DRM GPU VA manager. + * + * For each DRM GPU VA space drivers should call this function from their + * _info_list's show callback. + * + * Returns: 0 on success, -ENODEV if the is not initialized + */ +int drm_debugfs_gpuva_info(struct seq_file *m, + struct drm_gpuva_manager *mgr) +{ + struct drm_gpuva *va, *kva = >kernel_alloc_node; + + if (!mgr->name) + return -ENODEV; + + seq_printf(m, "DRM GPU VA space (%s) [0x%016llx;0x%016llx]\n", + mgr->name, mgr->mm_start, mgr->mm_start + mgr->mm_range); + seq_printf(m, "Kernel reserved node [0x%016llx;0x%016llx]\n", + kva->va.addr, kva->va.addr + kva->va.range); + seq_puts(m, "\n"); + seq_puts(m, " VAs | start | range | end | object | object offset\n"); + seq_puts(m, "-\n"); + drm_gpuva_for_each_va(va, mgr) { + if (unlikely(va == kva)) + continue; + + seq_printf(m, " | 0x%016llx | 0x%016llx | 0x%016llx | 0x%016llx | 0x%016llx\n", + va->va.addr, va->va.range, va->va.addr + va->va.range, + (u64)va->gem.obj, va->gem.offset); + } + + return 0; +} +EXPORT_SYMBOL(drm_debugfs_gpuva_info); /** * drm_debugfs_create_files - Initialize a given set of debugfs files for DRM diff --git a/include/drm/drm_debugfs.h b/include/drm/drm_debugfs.h index 7616f457ce70..cb2c1956a214 100644 --- a/include/drm/drm_debugfs.h +++ b/include/drm/drm_debugfs.h @@ -34,6 +34,22 @@ #include #include + +#include + +/** + * DRM_DEBUGFS_GPUVA_INFO - _info_list entry to dump a GPU VA space + * @show: the _info_list's show callback + * @data: driver private data + * + * Drivers should use this macro to define a _info_list entry to provide a + * debugfs file for dumping the GPU VA space regions and mappings. + * + * For each DRM GPU VA space drivers should call drm_debugfs_gpuva_info() from + * their @show callback. + */ +#define DRM_DEBUGFS_GPUVA_INFO(show, data) {"gpuvas", show, DRIVER_GEM_GPUVA, data} + /** * struct drm_info_list - debugfs info list entry * @@ -134,6 +150,9 @@ void drm_debugfs_add_file(struct drm_device *dev, const char *name, void drm_debugfs_add_files(struct drm_device *dev, const struct drm_debugfs_info *files, int count); + +int drm_debugfs_gpuva_info(struct seq_file *m, + struct drm_gpuva_manager *mgr); #else static inline void drm_debugfs_create_files(const struct drm_info_list *files, int count, struct dentry *root, @@ -155,6 +174,12 @@ static inline void drm_debugfs_add_files(struct drm_device *dev, const struct drm_debugfs_info *files, int count) {} + +static inline int drm_debugfs_gpuva_info(struct seq_file *m, +struct drm_gpuva_manager *mgr) +{ + return 0; +} #endif #endif /* _DRM_DEBUGFS_H_ */ -- 2.41.0
[Nouveau] [PATCH drm-next v6 04/13] drm/nouveau: new VM_BIND uapi interfaces
This commit provides the interfaces for the new UAPI motivated by the Vulkan API. It allows user mode drivers (UMDs) to: 1) Initialize a GPU virtual address (VA) space via the new DRM_IOCTL_NOUVEAU_VM_INIT ioctl. UMDs can provide a kernel reserved VA area. 2) Bind and unbind GPU VA space mappings via the new DRM_IOCTL_NOUVEAU_VM_BIND ioctl. 3) Execute push buffers with the new DRM_IOCTL_NOUVEAU_EXEC ioctl. Both, DRM_IOCTL_NOUVEAU_VM_BIND and DRM_IOCTL_NOUVEAU_EXEC support asynchronous processing with DRM syncobjs as synchronization mechanism. The default DRM_IOCTL_NOUVEAU_VM_BIND is synchronous processing, DRM_IOCTL_NOUVEAU_EXEC supports asynchronous processing only. Co-authored-by: Dave Airlie Signed-off-by: Danilo Krummrich --- Documentation/gpu/driver-uapi.rst | 8 ++ include/uapi/drm/nouveau_drm.h| 209 ++ 2 files changed, 217 insertions(+) diff --git a/Documentation/gpu/driver-uapi.rst b/Documentation/gpu/driver-uapi.rst index 4411e6919a3d..9c7ca6e33a68 100644 --- a/Documentation/gpu/driver-uapi.rst +++ b/Documentation/gpu/driver-uapi.rst @@ -6,3 +6,11 @@ drm/i915 uAPI = .. kernel-doc:: include/uapi/drm/i915_drm.h + +drm/nouveau uAPI + + +VM_BIND / EXEC uAPI +--- + +.. kernel-doc:: include/uapi/drm/nouveau_drm.h diff --git a/include/uapi/drm/nouveau_drm.h b/include/uapi/drm/nouveau_drm.h index 853a327433d3..4d3a70529637 100644 --- a/include/uapi/drm/nouveau_drm.h +++ b/include/uapi/drm/nouveau_drm.h @@ -126,6 +126,209 @@ struct drm_nouveau_gem_cpu_fini { __u32 handle; }; +/** + * struct drm_nouveau_sync - sync object + * + * This structure serves as synchronization mechanism for (potentially) + * asynchronous operations such as EXEC or VM_BIND. + */ +struct drm_nouveau_sync { + /** +* @flags: the flags for a sync object +* +* The first 8 bits are used to determine the type of the sync object. +*/ + __u32 flags; +#define DRM_NOUVEAU_SYNC_SYNCOBJ 0x0 +#define DRM_NOUVEAU_SYNC_TIMELINE_SYNCOBJ 0x1 +#define DRM_NOUVEAU_SYNC_TYPE_MASK 0xf + /** +* @handle: the handle of the sync object +*/ + __u32 handle; + /** +* @timeline_value: +* +* The timeline point of the sync object in case the syncobj is of +* type DRM_NOUVEAU_SYNC_TIMELINE_SYNCOBJ. +*/ + __u64 timeline_value; +}; + +/** + * struct drm_nouveau_vm_init - GPU VA space init structure + * + * Used to initialize the GPU's VA space for a user client, telling the kernel + * which portion of the VA space is managed by the UMD and kernel respectively. + */ +struct drm_nouveau_vm_init { + /** +* @unmanaged_addr: start address of the kernel managed VA space region +*/ + __u64 unmanaged_addr; + /** +* @unmanaged_size: size of the kernel managed VA space region in bytes +*/ + __u64 unmanaged_size; +}; + +/** + * struct drm_nouveau_vm_bind_op - VM_BIND operation + * + * This structure represents a single VM_BIND operation. UMDs should pass + * an array of this structure via struct drm_nouveau_vm_bind's _ptr field. + */ +struct drm_nouveau_vm_bind_op { + /** +* @op: the operation type +*/ + __u32 op; +/** + * @DRM_NOUVEAU_VM_BIND_OP_MAP: + * + * Map a GEM object to the GPU's VA space. Optionally, the + * _NOUVEAU_VM_BIND_SPARSE flag can be passed to instruct the kernel to + * create sparse mappings for the given range. + */ +#define DRM_NOUVEAU_VM_BIND_OP_MAP 0x0 +/** + * @DRM_NOUVEAU_VM_BIND_OP_UNMAP: + * + * Unmap an existing mapping in the GPU's VA space. If the region the mapping + * is located in is a sparse region, new sparse mappings are created where the + * unmapped (memory backed) mapping was mapped previously. To remove a sparse + * region the _NOUVEAU_VM_BIND_SPARSE must be set. + */ +#define DRM_NOUVEAU_VM_BIND_OP_UNMAP 0x1 + /** +* @flags: the flags for a _nouveau_vm_bind_op +*/ + __u32 flags; +/** + * @DRM_NOUVEAU_VM_BIND_SPARSE: + * + * Indicates that an allocated VA space region should be sparse. + */ +#define DRM_NOUVEAU_VM_BIND_SPARSE (1 << 8) + /** +* @handle: the handle of the DRM GEM object to map +*/ + __u32 handle; + /** +* @pad: 32 bit padding, should be 0 +*/ + __u32 pad; + /** +* @addr: +* +* the address the VA space region or (memory backed) mapping should be mapped to +*/ + __u64 addr; + /** +* @bo_offset: the offset within the BO backing the mapping +*/ + __u64 bo_offset; + /** +* @range: the size of the requested mapping in bytes +*/ + __u64 range; +}; + +/** + * struct drm_nouveau_vm_bind - structure for DRM_IOCTL_NOUVEAU_VM_BIND + */ +struct drm_nouveau_vm_bind { + /** +* @op_count: the number of _nouveau_vm_bind_op +
[Nouveau] [PATCH drm-next v6 02/13] drm: manager to keep track of GPUs VA mappings
Add infrastructure to keep track of GPU virtual address (VA) mappings with a decicated VA space manager implementation. New UAPIs, motivated by Vulkan sparse memory bindings graphics drivers start implementing, allow userspace applications to request multiple and arbitrary GPU VA mappings of buffer objects. The DRM GPU VA manager is intended to serve the following purposes in this context. 1) Provide infrastructure to track GPU VA allocations and mappings, making use of the maple_tree. 2) Generically connect GPU VA mappings to their backing buffers, in particular DRM GEM objects. 3) Provide a common implementation to perform more complex mapping operations on the GPU VA space. In particular splitting and merging of GPU VA mappings, e.g. for intersecting mapping requests or partial unmap requests. Tested-by: Donald Robson Reviewed-by: Boris Brezillon Suggested-by: Dave Airlie Signed-off-by: Danilo Krummrich --- Documentation/gpu/drm-mm.rst| 36 + drivers/gpu/drm/Makefile|1 + drivers/gpu/drm/drm_gem.c |3 + drivers/gpu/drm/drm_gpuva_mgr.c | 1743 +++ include/drm/drm_drv.h |6 + include/drm/drm_gem.h | 52 + include/drm/drm_gpuva_mgr.h | 756 ++ 7 files changed, 2597 insertions(+) create mode 100644 drivers/gpu/drm/drm_gpuva_mgr.c create mode 100644 include/drm/drm_gpuva_mgr.h diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index a52e6f4117d6..3d5dc9dc1bfe 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -466,6 +466,42 @@ DRM MM Range Allocator Function References .. kernel-doc:: drivers/gpu/drm/drm_mm.c :export: +DRM GPU VA Manager +== + +Overview + + +.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c + :doc: Overview + +Split and Merge +--- + +.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c + :doc: Split and Merge + +Locking +--- + +.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c + :doc: Locking + +Examples + + +.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c + :doc: Examples + +DRM GPU VA Manager Function References +-- + +.. kernel-doc:: include/drm/drm_gpuva_mgr.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c + :export: + DRM Buddy Allocator === diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 414855e2a463..6d6c9dec66e8 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -45,6 +45,7 @@ drm-y := \ drm_vblank.o \ drm_vblank_work.o \ drm_vma_manager.o \ + drm_gpuva_mgr.o \ drm_writeback.o drm-$(CONFIG_DRM_LEGACY) += \ drm_agpsupport.o \ diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 1a5a2cd0d4ec..cd878ebddbd0 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -164,6 +164,9 @@ void drm_gem_private_object_init(struct drm_device *dev, if (!obj->resv) obj->resv = >_resv; + if (drm_core_check_feature(dev, DRIVER_GEM_GPUVA)) + drm_gem_gpuva_init(obj); + drm_vma_node_reset(>vma_node); INIT_LIST_HEAD(>lru_node); } diff --git a/drivers/gpu/drm/drm_gpuva_mgr.c b/drivers/gpu/drm/drm_gpuva_mgr.c new file mode 100644 index ..4414990c05cc --- /dev/null +++ b/drivers/gpu/drm/drm_gpuva_mgr.c @@ -0,0 +1,1743 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Red Hat. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Danilo Krummrich + * + */ + +#include + +#include +#include + +/** + * DOC: Overview + * + * The DRM GPU VA Manager, represented by struct drm_gpuva_manager keeps track + * of a GPU's virtual address (VA) space and manages the corresponding virtual + * mappings represented by _gpuva objects. It also keeps track of
[Nouveau] [PATCH drm-next v6 01/13] drm: execution context for GEM buffers v5
From: Christian König This adds the infrastructure for an execution context for GEM buffers which is similar to the existing TTMs execbuf util and intended to replace it in the long term. The basic functionality is that we abstracts the necessary loop to lock many different GEM buffers with automated deadlock and duplicate handling. v2: drop xarray and use dynamic resized array instead, the locking overhead is unecessary and measurable. v3: drop duplicate tracking, radeon is really the only one needing that. v4: fixes issues pointed out by Danilo, some typos in comments and a helper for lock arrays of GEM objects. v5: some suggestions by Boris Brezillon, especially just use one retry macro, drop loop in prepare_array, use flags instead of bool Signed-off-by: Christian König --- Documentation/gpu/drm-mm.rst | 12 ++ drivers/gpu/drm/Kconfig | 6 + drivers/gpu/drm/Makefile | 2 + drivers/gpu/drm/drm_exec.c | 330 +++ include/drm/drm_exec.h | 120 + 5 files changed, 470 insertions(+) create mode 100644 drivers/gpu/drm/drm_exec.c create mode 100644 include/drm/drm_exec.h diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst index a79fd3549ff8..a52e6f4117d6 100644 --- a/Documentation/gpu/drm-mm.rst +++ b/Documentation/gpu/drm-mm.rst @@ -493,6 +493,18 @@ DRM Sync Objects .. kernel-doc:: drivers/gpu/drm/drm_syncobj.c :export: +DRM Execution context += + +.. kernel-doc:: drivers/gpu/drm/drm_exec.c + :doc: Overview + +.. kernel-doc:: include/drm/drm_exec.h + :internal: + +.. kernel-doc:: drivers/gpu/drm/drm_exec.c + :export: + GPU Scheduler = diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index afb3b2f5f425..c2f3d234c89e 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -194,6 +194,12 @@ config DRM_TTM GPU memory types. Will be enabled automatically if a device driver uses it. +config DRM_EXEC + tristate + depends on DRM + help + Execution context for command submissions + config DRM_BUDDY tristate depends on DRM diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 7a09a89b493b..414855e2a463 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -78,6 +78,8 @@ obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o # # Memory-management helpers # +# +obj-$(CONFIG_DRM_EXEC) += drm_exec.o obj-$(CONFIG_DRM_BUDDY) += drm_buddy.o diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c new file mode 100644 index ..285bf80740b5 --- /dev/null +++ b/drivers/gpu/drm/drm_exec.c @@ -0,0 +1,330 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ + +#include +#include +#include + +/** + * DOC: Overview + * + * This component mainly abstracts the retry loop necessary for locking + * multiple GEM objects while preparing hardware operations (e.g. command + * submissions, page table updates etc..). + * + * If a contention is detected while locking a GEM object the cleanup procedure + * unlocks all previously locked GEM objects and locks the contended one first + * before locking any further objects. + * + * After an object is locked fences slots can optionally be reserved on the + * dma_resv object inside the GEM object. + * + * A typical usage pattern should look like this:: + * + * struct drm_gem_object *obj; + * struct drm_exec exec; + * unsigned long index; + * int ret; + * + * drm_exec_init(, DRM_EXEC_INTERRUPTIBLE_WAIT); + * drm_exec_until_all_locked() { + * ret = drm_exec_prepare_obj(, boA, 1); + * drm_exec_retry_on_contention(); + * if (ret) + * goto error; + * + * ret = drm_exec_prepare_obj(, boB, 1); + * drm_exec_retry_on_contention(); + * if (ret) + * goto error; + * } + * + * drm_exec_for_each_locked_object(, index, obj) { + * dma_resv_add_fence(obj->resv, fence, DMA_RESV_USAGE_READ); + * ... + * } + * drm_exec_fini(); + * + * See struct dma_exec for more details. + */ + +/* Dummy value used to initially enter the retry loop */ +#define DRM_EXEC_DUMMY (void*)~0 + +/* Unlock all objects and drop references */ +static void drm_exec_unlock_all(struct drm_exec *exec) +{ + struct drm_gem_object *obj; + unsigned long index; + + drm_exec_for_each_locked_object(exec, index, obj) { + dma_resv_unlock(obj->resv); + drm_gem_object_put(obj); + } + + drm_gem_object_put(exec->prelocked); + exec->prelocked = NULL; +} + +/** + * drm_exec_init - initialize a drm_exec object + * @exec: the drm_exec object to initialize + * @flags: controls locking behavior, see DRM_EXEC_* defines + * + * Initialize the object and make sure that we can track locked objects. + */
[Nouveau] [PATCH drm-next v6 00/13] [RFC] DRM GPUVA Manager & Nouveau VM_BIND UAPI
This patch series provides a new UAPI for the Nouveau driver in order to support Vulkan features, such as sparse bindings and sparse residency. Furthermore, with the DRM GPUVA manager it provides a new DRM core feature to keep track of GPU virtual address (VA) mappings in a more generic way. The DRM GPUVA manager is indented to help drivers implement userspace-manageable GPU VA spaces in reference to the Vulkan API. In order to achieve this goal it serves the following purposes in this context. 1) Provide infrastructure to track GPU VA allocations and mappings, making use of the maple_tree. 2) Generically connect GPU VA mappings to their backing buffers, in particular DRM GEM objects. 3) Provide a common implementation to perform more complex mapping operations on the GPU VA space. In particular splitting and merging of GPU VA mappings, e.g. for intersecting mapping requests or partial unmap requests. The new VM_BIND Nouveau UAPI build on top of the DRM GPUVA manager, itself providing the following new interfaces. 1) Initialize a GPU VA space via the new DRM_IOCTL_NOUVEAU_VM_INIT ioctl for UMDs to specify the portion of VA space managed by the kernel and userspace, respectively. 2) Allocate and free a VA space region as well as bind and unbind memory to the GPUs VA space via the new DRM_IOCTL_NOUVEAU_VM_BIND ioctl. 3) Execute push buffers with the new DRM_IOCTL_NOUVEAU_EXEC ioctl. Both, DRM_IOCTL_NOUVEAU_VM_BIND and DRM_IOCTL_NOUVEAU_EXEC, make use of the DRM scheduler to queue jobs and support asynchronous processing with DRM syncobjs as synchronization mechanism. By default DRM_IOCTL_NOUVEAU_VM_BIND does synchronous processing, DRM_IOCTL_NOUVEAU_EXEC supports asynchronous processing only. The new VM_BIND UAPI for Nouveau makes also use of drm_exec (execution context for GEM buffers) by Christian König. Since the patch implementing drm_exec was not yet merged into drm-next it is part of this series, as well as a small fix for this patch, which was found while testing this series. This patch series is also available at [1]. There is a Mesa NVK merge request by Dave Airlie [2] implementing the corresponding userspace parts for this series. The Vulkan CTS test suite passes the sparse binding and sparse residency test cases for the new UAPI together with Dave's Mesa work. There are also some test cases in the igt-gpu-tools project [3] for the new UAPI and hence the DRM GPU VA manager. However, most of them are testing the DRM GPU VA manager's logic through Nouveau's new UAPI and should be considered just as helper for implementation. However, I absolutely intend to change those test cases to proper kunit test cases for the DRM GPUVA manager, once and if we agree on it's usefulness and design. [1] https://gitlab.freedesktop.org/nouvelles/kernel/-/tree/new-uapi-drm-next / https://gitlab.freedesktop.org/nouvelles/kernel/-/merge_requests/1 [2] https://gitlab.freedesktop.org/nouveau/mesa/-/merge_requests/150/ [3] https://gitlab.freedesktop.org/dakr/igt-gpu-tools/-/tree/wip_nouveau_vm_bind Changes in V2: == Nouveau: - Reworked the Nouveau VM_BIND UAPI to avoid memory allocations in fence signalling critical sections. Updates to the VA space are split up in three separate stages, where only the 2. stage executes in a fence signalling critical section: 1. update the VA space, allocate new structures and page tables 2. (un-)map the requested memory bindings 3. free structures and page tables - Separated generic job scheduler code from specific job implementations. - Separated the EXEC and VM_BIND implementation of the UAPI. - Reworked the locking parts of the nvkm/vmm RAW interface, such that (un-)map operations can be executed in fence signalling critical sections. GPUVA Manager: - made drm_gpuva_regions optional for users of the GPUVA manager - allow NULL GEMs for drm_gpuva entries - swichted from drm_mm to maple_tree for track drm_gpuva / drm_gpuva_region entries - provide callbacks for users to allocate custom drm_gpuva_op structures to allow inheritance - added user bits to drm_gpuva_flags - added a prefetch operation type in order to support generating prefetch operations in the same way other operations generated - hand the responsibility for mutual exclusion for a GEM's drm_gpuva list to the user; simplified corresponding (un-)link functions Maple Tree: - I added two maple tree patches to the series, one to support custom tree walk macros and one to hand the locking responsibility to the user of the GPUVA manager without pre-defined lockdep checks. Changes in V3: == Nouveau: - Reworked the Nouveau VM_BIND UAPI to do the job cleanup (including page table cleanup) within a workqueue rather than the job_free() callback of the
Re: [Nouveau] [PATCH v7 6/8] PCI/VGA: Introduce is_boot_device function callback to vga_client_register
[Public] > -Original Message- > From: 15330273...@189.cn <15330273...@189.cn> > Sent: Thursday, June 29, 2023 12:00 PM > To: Bjorn Helgaas ; Sui Jingfeng > > Cc: Bjorn Helgaas ; linux-fb...@vger.kernel.org; > Cornelia Huck ; Karol Herbst ; > nouveau@lists.freedesktop.org; Joonas Lahtinen > ; dri-de...@lists.freedesktop.org; Chai, > Thomas ; Limonciello, Mario > ; Gao, Likun ; David > Airlie ; Ville Syrjala ; Yi > Liu > ; k...@vger.kernel.org; amd-...@lists.freedesktop.org; > Jason Gunthorpe ; Ben Skeggs ; linux- > p...@vger.kernel.org; Kevin Tian ; Lazar, Lijo > ; Thomas Zimmermann ; > Zhang, Bokun ; intel-...@lists.freedesktop.org; > Maarten Lankhorst ; Jani Nikula > ; Alex Williamson > ; Abhishek Sahu ; > Maxime Ripard ; Rodrigo Vivi ; > Tvrtko Ursulin ; Yishai Hadas > ; Pan, Xinhui ; linux- > ker...@vger.kernel.org; Daniel Vetter ; Deucher, Alexander > ; Koenig, Christian > ; Zhang, Hawking > Subject: Re: [PATCH v7 6/8] PCI/VGA: Introduce is_boot_device function > callback to vga_client_register > > Hi, > > On 2023/6/29 23:54, Bjorn Helgaas wrote: > > On Thu, Jun 22, 2023 at 01:08:15PM +0800, Sui Jingfeng wrote: > >> Hi, > >> > >> > >> A nouveau developer(Lyude) from redhat send me a R-B, > >> > >> Thanks for the developers of nouveau project. > >> > >> > >> Please allow me add a link[1] here. > >> > >> > >> [1] > https://lore.kernel.org/all/0afadc69f99a36bc9d03ecf54ff25859dbc10e28.ca > m...@redhat.com/ > > 1) Thanks for this. If you post another version of this series, > > please pick up Lyude's Reviewed-by and include it in the relevant > > patches (as long as you haven't made significant changes to the > > code Lyude reviewed). > > Yes, no significant changes. Just fix typo. > > I also would like to add support for other DRM drivers. > > But I think this deserve another patch. > > > Whoever applies this should automatically > > pick up Reviewed-by/Ack/etc that are replies to the version being > > applied, but they won't go through previous revisions to find them. > > > > 2) Please mention the commit to which the series applies. I tried to > > apply this on v6.4-rc1, but it doesn't apply cleanly. > > Since I'm a graphic driver developer, I'm using drm-tip. > > I just have already pulled, it still apply cleanly on drm-tip. > > > 3) Thanks for including cover letters in your postings. Please > > include a little changelog in the cover letter so we know what > > changed between v6 and v7, etc. > > No change between v6 and v7, > > it seems that it is because the mailbox don't allow me to sending too > many mails a day. > > so some of the patch is failed to delivery because out of quota. > > > > 4) Right now we're in the middle of the v6.5 merge window, so new > > content, e.g., this series, is too late for v6.5. Most > > maintainers, including me, wait to merge new content until the > > merge window closes and a new -rc1 is tagged. This merge window > > should close on July 9, and people will start merging content for > > v6.6, typically based on v6.5-rc1. > > I'm wondering > > Would you will merge all of the patches in this series (e.g. including > the patch for drm/amdgpu(7/8) and drm/radeon(8/8)) ? > > Or just part of them? > > Emm, I don't know because my patch seems across different subsystem of > Linux kernel. > > There is also a developer for AMDGPU (Mario) give me a R-B for the > patch-0002 of this series. > > So, at least, PATCH-0001, PATCH-0002, PATCH-0003, PATCH-0004, PATCH- > 0006 > are already OK(got reviewed by). > > Those 5 patch are already qualified to be merged, I think. I think what you can do is pick up all the tags in your next version. Once the whole series has tags we can discuss how it merges. > > I means that if you could merge those 5 patch first, then there no need > to send another version again. > > I will refine the rest patch with more details and description. > > I'm fear of making too much noise. > > > Bjorn
Re: [Nouveau] [PATCH v7 6/8] PCI/VGA: Introduce is_boot_device function callback to vga_client_register
Hi, On 2023/6/29 23:54, Bjorn Helgaas wrote: On Thu, Jun 22, 2023 at 01:08:15PM +0800, Sui Jingfeng wrote: Hi, A nouveau developer(Lyude) from redhat send me a R-B, Thanks for the developers of nouveau project. Please allow me add a link[1] here. [1] https://lore.kernel.org/all/0afadc69f99a36bc9d03ecf54ff25859dbc10e28.ca...@redhat.com/ 1) Thanks for this. If you post another version of this series, please pick up Lyude's Reviewed-by and include it in the relevant patches (as long as you haven't made significant changes to the code Lyude reviewed). Yes, no significant changes. Just fix typo. I also would like to add support for other DRM drivers. But I think this deserve another patch. Whoever applies this should automatically pick up Reviewed-by/Ack/etc that are replies to the version being applied, but they won't go through previous revisions to find them. 2) Please mention the commit to which the series applies. I tried to apply this on v6.4-rc1, but it doesn't apply cleanly. Since I'm a graphic driver developer, I'm using drm-tip. I just have already pulled, it still apply cleanly on drm-tip. 3) Thanks for including cover letters in your postings. Please include a little changelog in the cover letter so we know what changed between v6 and v7, etc. No change between v6 and v7, it seems that it is because the mailbox don't allow me to sending too many mails a day. so some of the patch is failed to delivery because out of quota. 4) Right now we're in the middle of the v6.5 merge window, so new content, e.g., this series, is too late for v6.5. Most maintainers, including me, wait to merge new content until the merge window closes and a new -rc1 is tagged. This merge window should close on July 9, and people will start merging content for v6.6, typically based on v6.5-rc1. I'm wondering Would you will merge all of the patches in this series (e.g. including the patch for drm/amdgpu(7/8) and drm/radeon(8/8)) ? Or just part of them? Emm, I don't know because my patch seems across different subsystem of Linux kernel. There is also a developer for AMDGPU (Mario) give me a R-B for the patch-0002 of this series. So, at least, PATCH-0001, PATCH-0002, PATCH-0003, PATCH-0004, PATCH-0006 are already OK(got reviewed by). Those 5 patch are already qualified to be merged, I think. I means that if you could merge those 5 patch first, then there no need to send another version again. I will refine the rest patch with more details and description. I'm fear of making too much noise. Bjorn
Re: [Nouveau] [PATCH v7 6/8] PCI/VGA: Introduce is_boot_device function callback to vga_client_register
On Thu, Jun 22, 2023 at 01:08:15PM +0800, Sui Jingfeng wrote: > Hi, > > > A nouveau developer(Lyude) from redhat send me a R-B, > > Thanks for the developers of nouveau project. > > > Please allow me add a link[1] here. > > > [1] > https://lore.kernel.org/all/0afadc69f99a36bc9d03ecf54ff25859dbc10e28.ca...@redhat.com/ 1) Thanks for this. If you post another version of this series, please pick up Lyude's Reviewed-by and include it in the relevant patches (as long as you haven't made significant changes to the code Lyude reviewed). Whoever applies this should automatically pick up Reviewed-by/Ack/etc that are replies to the version being applied, but they won't go through previous revisions to find them. 2) Please mention the commit to which the series applies. I tried to apply this on v6.4-rc1, but it doesn't apply cleanly. 3) Thanks for including cover letters in your postings. Please include a little changelog in the cover letter so we know what changed between v6 and v7, etc. 4) Right now we're in the middle of the v6.5 merge window, so new content, e.g., this series, is too late for v6.5. Most maintainers, including me, wait to merge new content until the merge window closes and a new -rc1 is tagged. This merge window should close on July 9, and people will start merging content for v6.6, typically based on v6.5-rc1. Bjorn
Re: [Nouveau] [PATCH v7 6/8] PCI/VGA: Introduce is_boot_device function callback to vga_client_register
Hi, Humble ping ! Please share some bandwidth to help reviewing this series, OK ? As this series is useful for all architecture, I have tested on my X86, mips and LoongArch computer. Questions and comments is also welcome. If no one response within three days, I'm going to send a updated version with another trivial improvement, OK? On 2023/6/13 11:01, Sui Jingfeng wrote: From: Sui Jingfeng The vga_is_firmware_default() function is arch-dependent, it's probably wrong if we simply remove the arch guard. As the VRAM BAR which contains firmware framebuffer may move, while the lfb_base and lfb_size members of the screen_info does not change accordingly. In short, it should take the re-allocation of the PCI BAR into consideration. With the observation that device drivers or video aperture helpers may have better knowledge about which PCI bar contains the firmware fb, which could avoid the need to iterate all of the PCI BARs. But as a PCI function at pci/vgaarb.c, vga_is_firmware_default() is not suitable to make such an optimization since it is loaded too early. There are PCI display controllers that don't have a dedicated VRAM bar, this function will lose its effectiveness in such a case. Luckily, the device driver can provide an accurate workaround. Therefore, this patch introduces a callback that allows the device driver to tell the VGAARB if the device is the default boot device. This patch only intends to introduce the mechanism, while the implementation is left to the device driver authors. Also honor the comment: "Clients have two callback mechanisms they can use" Cc: Alex Deucher Cc: Christian Konig Cc: Pan Xinhui Cc: David Airlie Cc: Daniel Vetter Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Cc: Ben Skeggs Cc: Karol Herbst Cc: Lyude Paul Cc: Bjorn Helgaas Cc: Alex Williamson Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: Hawking Zhang Cc: Mario Limonciello Cc: Lijo Lazar Cc: YiPeng Chai Cc: Bokun Zhang Cc: Likun Gao Cc: Ville Syrjala Cc: Jason Gunthorpe CC: Kevin Tian Cc: Cornelia Huck Cc: Yishai Hadas Cc: Abhishek Sahu Cc: Yi Liu Signed-off-by: Sui Jingfeng --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- drivers/gpu/drm/i915/display/intel_vga.c | 3 +-- drivers/gpu/drm/nouveau/nouveau_vga.c | 2 +- drivers/gpu/drm/radeon/radeon_device.c | 2 +- drivers/pci/vgaarb.c | 21 - drivers/vfio/pci/vfio_pci_core.c | 2 +- include/linux/vgaarb.h | 8 +--- 7 files changed, 30 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 5c7d40873ee2..7a096f2d5c16 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -3960,7 +3960,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, /* this will fail for cards that aren't VGA class devices, just * ignore it */ if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA) - vga_client_register(adev->pdev, amdgpu_device_vga_set_decode); + vga_client_register(adev->pdev, amdgpu_device_vga_set_decode, NULL); px = amdgpu_device_supports_px(ddev); diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c index 286a0bdd28c6..98d7d4dffe9f 100644 --- a/drivers/gpu/drm/i915/display/intel_vga.c +++ b/drivers/gpu/drm/i915/display/intel_vga.c @@ -115,7 +115,6 @@ intel_vga_set_decode(struct pci_dev *pdev, bool enable_decode) int intel_vga_register(struct drm_i915_private *i915) { - struct pci_dev *pdev = to_pci_dev(i915->drm.dev); int ret; @@ -127,7 +126,7 @@ int intel_vga_register(struct drm_i915_private *i915) * then we do not take part in VGA arbitration and the * vga_client_register() fails with -ENODEV. */ - ret = vga_client_register(pdev, intel_vga_set_decode); + ret = vga_client_register(pdev, intel_vga_set_decode, NULL); if (ret && ret != -ENODEV) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c index f8bf0ec26844..162b4f4676c7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vga.c +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c @@ -92,7 +92,7 @@ nouveau_vga_init(struct nouveau_drm *drm) return; pdev = to_pci_dev(dev->dev); - vga_client_register(pdev, nouveau_vga_set_decode); + vga_client_register(pdev, nouveau_vga_set_decode, NULL); /* don't register Thunderbolt eGPU with vga_switcheroo */ if (pci_is_thunderbolt_attached(pdev)) diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index afbb3a80c0c6..71f2ff39d6a1 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@