From 17cdb54644e7d92b62cff1c4d1bd3d1486515f68 Mon Sep 17 00:00:00 2001 From: "Rob Herring (Arm)" Date: Sat, 23 May 2026 10:37:22 +0200 Subject: accel: ethosu: Add performance counter support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Arm Ethos-U NPUs have a PMU with performance counters. The PMU h/w supports up to 4 (U65) or 8 (U85) counters which can be programmed for different events. There is also a dedicated cycle counter. The ABI and implementation are copied from the V3D driver. The main difference in the ABI is there is no query API for the event list. The events differ between the U65 and U85, so the events lists are maintained in userspace along with other differences between the U65 and U85. The cycle counter is always enabled when the PMU is enabled. When the user requests N events, reading the counters will return the N events plus the cycle counter. Signed-off-by: Rob Herring (Arm) Signed-off-by: Tomeu Vizoso Reviewed-by: Maíra Canal Link: https://patch.msgid.link/20260601173814.250071-1-tomeu@tomeuvizoso.net --- v2: - Use XArray instead of idr - Rework locking to use per device spinlock to protect modifying active perfmon. Based on pending V3D changes: https://lore.kernel.org/all/20260508-v3d-perfmon-lifetime-v1-1-f5b5642c085f@igalia.com/ - Add missing perfmon puts in ethosu_ioctl_perfmon_set_global() and ethosu_ioctl_perfmon_get_values() error paths. - Fix reading number of counters on U85. - Add defines NPU_REG_PMCCNTR_CFG v3: - Add explicit padding to drm_ethosu_perfmon_destroy - Fix SPDX license expression - Fix comment typos - Convert perfmon lock from spinlock to mutex - Simplify switch_perfmon condition check - Remove unused ethosu_perfmon_init - Add lockdep_assert_held to ethosu_perfmon_stop_locked v4: - Use drmm_mutex_init() for perfmon lock - Add lockdep_assert_held() to ethosu_perfmon_start() - Fix a few style issues reported by Maíra --- include/uapi/drm/ethosu_accel.h | 60 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'include/uapi') diff --git a/include/uapi/drm/ethosu_accel.h b/include/uapi/drm/ethosu_accel.h index af78bb4686d7..5b97d59a7806 100644 --- a/include/uapi/drm/ethosu_accel.h +++ b/include/uapi/drm/ethosu_accel.h @@ -43,6 +43,11 @@ enum drm_ethosu_ioctl_id { /** @DRM_ETHOSU_SUBMIT: Submit a job and BOs to run. */ DRM_ETHOSU_SUBMIT, + + DRM_ETHOSU_PERFMON_CREATE, + DRM_ETHOSU_PERFMON_DESTROY, + DRM_ETHOSU_PERFMON_GET_VALUES, + DRM_ETHOSU_PERFMON_SET_GLOBAL, }; /** @@ -79,6 +84,7 @@ struct drm_ethosu_npu_info { __u32 config; __u32 sram_size; + __u32 pmu_counters; }; /** @@ -220,10 +226,54 @@ struct drm_ethosu_submit { /** Input: Number of jobs passed in. */ __u32 job_count; - /** Reserved, must be zero. */ + /** Input: Id returned by DRM_ETHOSU_PERFMON_CREATE */ + __u32 perfmon_id; +}; + +#define DRM_ETHOSU_MAX_PERF_EVENT_COUNTERS 8 +#define DRM_ETHOSU_MAX_PERF_COUNTERS \ + (DRM_ETHOSU_MAX_PERF_EVENT_COUNTERS + 1) + +struct drm_ethosu_perfmon_create { + __u32 id; + __u32 ncounters; + __u16 counters[DRM_ETHOSU_MAX_PERF_EVENT_COUNTERS]; +}; + +struct drm_ethosu_perfmon_destroy { + __u32 id; __u32 pad; }; +/* + * Returns the values of the performance counters tracked by this + * perfmon (as an array of (ncounters + 1) u64 values). + * + * No implicit synchronization is performed, so the user has to + * guarantee that any jobs using this perfmon have already been + * completed. + */ +struct drm_ethosu_perfmon_get_values { + __u32 id; + __u32 pad; + __u64 values_ptr; +}; + +#define DRM_ETHOSU_PERFMON_CLEAR_GLOBAL 0x0001 + +/** + * struct drm_ethosu_perfmon_set_global - ioctl to define a global performance + * monitor + * + * The global performance monitor will be used for all jobs. If a global + * performance monitor is defined, jobs with a self-defined performance + * monitor won't be allowed. + */ +struct drm_ethosu_perfmon_set_global { + __u32 flags; + __u32 id; +}; + /** * DRM_IOCTL_ETHOSU() - Build a ethosu IOCTL number * @__access: Access type. Must be R, W or RW. @@ -252,6 +302,14 @@ enum { DRM_IOCTL_ETHOSU(WR, CMDSTREAM_BO_CREATE, cmdstream_bo_create), DRM_IOCTL_ETHOSU_SUBMIT = DRM_IOCTL_ETHOSU(WR, SUBMIT, submit), + DRM_IOCTL_ETHOSU_PERFMON_CREATE = + DRM_IOCTL_ETHOSU(WR, PERFMON_CREATE, perfmon_create), + DRM_IOCTL_ETHOSU_PERFMON_DESTROY = + DRM_IOCTL_ETHOSU(WR, PERFMON_DESTROY, perfmon_destroy), + DRM_IOCTL_ETHOSU_PERFMON_GET_VALUES = + DRM_IOCTL_ETHOSU(WR, PERFMON_GET_VALUES, perfmon_get_values), + DRM_IOCTL_ETHOSU_PERFMON_SET_GLOBAL = + DRM_IOCTL_ETHOSU(WR, PERFMON_SET_GLOBAL, perfmon_set_global), }; #if defined(__cplusplus) -- cgit From 6c1427fd03d8c30be810592523c5ba8fe864c2b0 Mon Sep 17 00:00:00 2001 From: Adrián Larumbe Date: Fri, 22 May 2026 19:51:55 +0100 Subject: drm/panthor: Expose GPU page sizes to UM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In future commits that will implement repeated mappings, only repeat values multiple of GPU page sizes will be tolerated. That means these values must be made known to UM. Do it through a queriable GPU info value. Reviewed-by: Steven Price Reviewed-by: Boris Brezillon Signed-off-by: Adrián Larumbe Link: https://patch.msgid.link/20260522185206.2798288-2-adrian.larumbe@collabora.com Signed-off-by: Steven Price --- drivers/gpu/drm/panthor/panthor_device.h | 3 +++ drivers/gpu/drm/panthor/panthor_drv.c | 8 ++++++++ drivers/gpu/drm/panthor/panthor_mmu.c | 9 ++++++++- include/uapi/drm/panthor_drm.h | 13 +++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h index a412a50eec76..35679bfa1f3a 100644 --- a/drivers/gpu/drm/panthor/panthor_device.h +++ b/drivers/gpu/drm/panthor/panthor_device.h @@ -161,6 +161,9 @@ struct panthor_device { /** @csif_info: Command stream interface information. */ struct drm_panthor_csif_info csif_info; + /** @mmu_info: MMU info */ + struct drm_panthor_mmu_info mmu_info; + /** @hw: GPU-specific data. */ struct panthor_hw *hw; diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c index 1b8f5d5c2ee9..557e1bfddfd7 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -175,6 +175,7 @@ panthor_get_uobj_array(const struct drm_panthor_obj_array *in, u32 min_stride, _Generic(_obj_name, \ PANTHOR_UOBJ_DECL(struct drm_panthor_gpu_info, tiler_present), \ PANTHOR_UOBJ_DECL(struct drm_panthor_csif_info, pad), \ + PANTHOR_UOBJ_DECL(struct drm_panthor_mmu_info, page_size_bitmap), \ PANTHOR_UOBJ_DECL(struct drm_panthor_timestamp_info, current_timestamp), \ PANTHOR_UOBJ_DECL(struct drm_panthor_group_priorities_info, pad), \ PANTHOR_UOBJ_DECL(struct drm_panthor_sync_op, timeline_value), \ @@ -954,6 +955,10 @@ static int panthor_ioctl_dev_query(struct drm_device *ddev, void *data, struct d args->size = sizeof(priorities_info); return 0; + case DRM_PANTHOR_DEV_QUERY_MMU_INFO: + args->size = sizeof(ptdev->mmu_info); + return 0; + default: return -EINVAL; } @@ -984,6 +989,9 @@ static int panthor_ioctl_dev_query(struct drm_device *ddev, void *data, struct d panthor_query_group_priorities_info(file, &priorities_info); return PANTHOR_UOBJ_SET(args->pointer, args->size, priorities_info); + case DRM_PANTHOR_DEV_QUERY_MMU_INFO: + return PANTHOR_UOBJ_SET(args->pointer, args->size, ptdev->mmu_info); + default: return -EINVAL; } diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c index 9d4500850561..271a3ea55b61 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -2782,7 +2782,7 @@ panthor_vm_create(struct panthor_device *ptdev, bool for_mcu, refcount_set(&vm->as.active_cnt, 0); pgtbl_cfg = (struct io_pgtable_cfg) { - .pgsize_bitmap = SZ_4K | SZ_2M, + .pgsize_bitmap = ptdev->mmu_info.page_size_bitmap, .ias = va_bits, .oas = pa_bits, .coherent_walk = ptdev->coherent, @@ -3228,6 +3228,11 @@ static void panthor_mmu_release_wq(struct drm_device *ddev, void *res) destroy_workqueue(res); } +static void panthor_mmu_info_init(struct panthor_device *ptdev) +{ + ptdev->mmu_info.page_size_bitmap = SZ_4K | SZ_2M; +} + /** * panthor_mmu_init() - Initialize the MMU logic. * @ptdev: Device. @@ -3240,6 +3245,8 @@ int panthor_mmu_init(struct panthor_device *ptdev) struct panthor_mmu *mmu; int ret, irq; + panthor_mmu_info_init(ptdev); + mmu = drmm_kzalloc(&ptdev->base, sizeof(*mmu), GFP_KERNEL); if (!mmu) return -ENOMEM; diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h index 0e455d91e77d..b462752c793d 100644 --- a/include/uapi/drm/panthor_drm.h +++ b/include/uapi/drm/panthor_drm.h @@ -253,6 +253,9 @@ enum drm_panthor_dev_query_type { * @DRM_PANTHOR_DEV_QUERY_GROUP_PRIORITIES_INFO: Query allowed group priorities information. */ DRM_PANTHOR_DEV_QUERY_GROUP_PRIORITIES_INFO, + + /** @DRM_PANTHOR_DEV_QUERY_MMU_INFO: Query MMU information. */ + DRM_PANTHOR_DEV_QUERY_MMU_INFO, }; /** @@ -487,6 +490,16 @@ struct drm_panthor_timestamp_info { __u64 cpu_timestamp_nsec; }; +/** + * struct drm_panthor_mmu_info - MMU information + * + * Structure grouping all queryable information relating to the MMU. + */ +struct drm_panthor_mmu_info { + /** @page_size_bitmap: Allowed page sizes */ + __u64 page_size_bitmap; +}; + /** * struct drm_panthor_group_priorities_info - Group priorities information * -- cgit From 8e54aac5af6a3712a72678f7585eb605e40b89e8 Mon Sep 17 00:00:00 2001 From: Adrián Larumbe Date: Fri, 22 May 2026 19:51:57 +0100 Subject: drm/panthor: Delete spurious whitespace from uAPI header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no extra blank line after the last member of any other uAPI structures, so delete it. Reviewed-by: Steven Price Reviewed-by: Boris Brezillon Signed-off-by: Adrián Larumbe Link: https://patch.msgid.link/20260522185206.2798288-4-adrian.larumbe@collabora.com Signed-off-by: Steven Price --- include/uapi/drm/panthor_drm.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/uapi') diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h index b462752c793d..14a93a4ef6ff 100644 --- a/include/uapi/drm/panthor_drm.h +++ b/include/uapi/drm/panthor_drm.h @@ -677,7 +677,6 @@ struct drm_panthor_vm_bind_op { * This array shall not be empty for sync-only operations. */ struct drm_panthor_obj_array syncs; - }; /** -- cgit From 12cf826bf1dd9275773cbef02c81ec1c67def7c3 Mon Sep 17 00:00:00 2001 From: Adrián Larumbe Date: Fri, 22 May 2026 19:51:59 +0100 Subject: drm/panthor: Support sparse mappings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow UM to bind sparsely populated memory regions by cyclically mapping virtual ranges over a kernel-allocated dummy BO. This alternative is preferable to the old method of handling sparseness in the UMD, because it relied on the creation of a buffer object to the same end, despite the fact Vulkan sparse resources don't need to be backed by a driver BO. The choice of backing sparsely-bound regions with a Panthor BO was made so as to profit from the existing shrinker reclaim code. That way no special treatment must be given to the dummy sparse BOs when reclaiming memory, as would be the case if we had chosen a raw kernel page implementation. A new dummy BO is allocated per open file context, because even though the Vulkan spec mandates that writes into sparsely bound regions must be discarded, our implementation is still a workaround over the fact Mali CSF GPUs cannot support this behaviour on the hardware level, so writes still make it into the backing BO. If we had a global one, then it could be a venue for information leaks between file contexts, which should never happen in DRM. As a side note, care was put to adjust dummy BO offsets for sparse mappings so that all addresses in the new VA are mapped aligned against it. Signed-off-by: Adrián Larumbe Reviewed-by: Boris Brezillon Reviewed-by: Steven Price Link: https://patch.msgid.link/20260522185206.2798288-6-adrian.larumbe@collabora.com Signed-off-by: Steven Price --- drivers/gpu/drm/panthor/panthor_gem.c | 18 ++++ drivers/gpu/drm/panthor/panthor_gem.h | 2 + drivers/gpu/drm/panthor/panthor_mmu.c | 195 +++++++++++++++++++++++++++++----- include/uapi/drm/panthor_drm.h | 12 +++ 4 files changed, 201 insertions(+), 26 deletions(-) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c index a1e2eb1ca7bb..9855df738194 100644 --- a/drivers/gpu/drm/panthor/panthor_gem.c +++ b/drivers/gpu/drm/panthor/panthor_gem.c @@ -1347,6 +1347,24 @@ err_free_kbo: return ERR_PTR(ret); } +/** + * panthor_dummy_bo_create() - Create a Panthor BO meant to back sparse bindings. + * @ptdev: Device. + * + * Return: A valid pointer in case of success, an ERR_PTR() otherwise. + */ +struct panthor_gem_object * +panthor_dummy_bo_create(struct panthor_device *ptdev) +{ + /* Since even when the DRM device's mount point has enabled THP we have no guarantee + * that drm_gem_get_pages() will return a single 2MiB PMD, and also we cannot be sure + * that the 2MiB won't be reclaimed and re-allocated later on as 4KiB chunks, it doesn't + * make sense to pre-populate this object's page array, nor to fall back on a BO size + * of 4KiB. Sticking to a dummy object size of 2MiB lets us keep things simple for now. + */ + return panthor_gem_create(&ptdev->base, SZ_2M, DRM_PANTHOR_BO_NO_MMAP, NULL, 0); +} + static bool can_swap(void) { return get_nr_swap_pages() > 0; diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h index 56d63137b4eb..5ae37d0d3646 100644 --- a/drivers/gpu/drm/panthor/panthor_gem.h +++ b/drivers/gpu/drm/panthor/panthor_gem.h @@ -325,6 +325,8 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo); +struct panthor_gem_object *panthor_dummy_bo_create(struct panthor_device *ptdev); + #ifdef CONFIG_DEBUG_FS void panthor_gem_debugfs_init(struct drm_minor *minor); #endif diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c index f3cb94611e9c..31cc57029c12 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -116,6 +116,17 @@ struct panthor_mmu { struct panthor_vm_pool { /** @xa: Array used for VM handle tracking. */ struct xarray xa; + + /** + * @dummy: Dummy object used for sparse mappings + * + * Sparse bindings map virtual address ranges onto a dummy + * BO in a modulo fashion. Even though sparse writes are meant + * to be discarded and reads undefined, writes are still reflected + * in the dummy buffer. That means we must keep a dummy object per + * file context, to avoid data leaks between them. + */ + struct panthor_gem_object *dummy; }; /** @@ -395,6 +406,15 @@ struct panthor_vm { */ struct list_head lru_node; } reclaim; + + /** + * @dummy: Dummy object used for sparse mappings. + * + * VM's must keep a reference to the file context-wide dummy BO because + * they can outlive the file context, which includes the VM pool holding + * the original dummy BO reference. + */ + struct panthor_gem_object *dummy; }; /** @@ -1027,6 +1047,30 @@ panthor_vm_map_pages(struct panthor_vm *vm, u64 iova, int prot, return 0; } +static int +panthor_vm_map_sparse(struct panthor_vm *vm, u64 iova, int prot, + struct sg_table *sgt, u64 size) +{ + u64 mapped = 0; + int ret; + + while (mapped < size) { + u64 addr = iova + mapped; + u32 chunk_size = min(size - mapped, SZ_2M - (addr & (SZ_2M - 1))); + + ret = panthor_vm_map_pages(vm, addr, prot, sgt, + addr % SZ_2M, chunk_size); + if (ret) { + panthor_vm_unmap_pages(vm, iova, mapped); + return ret; + } + + mapped += chunk_size; + } + + return 0; +} + static int flags_to_prot(u32 flags) { int prot = 0; @@ -1269,6 +1313,7 @@ static int panthor_vm_op_ctx_prealloc_pts(struct panthor_vm_op_ctx *op_ctx) (DRM_PANTHOR_VM_BIND_OP_MAP_READONLY | \ DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | \ DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED | \ + DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE | \ DRM_PANTHOR_VM_BIND_OP_TYPE_MASK) static int panthor_vm_prepare_map_op_ctx(struct panthor_vm_op_ctx *op_ctx, @@ -1276,6 +1321,7 @@ static int panthor_vm_prepare_map_op_ctx(struct panthor_vm_op_ctx *op_ctx, struct panthor_gem_object *bo, const struct drm_panthor_vm_bind_op *op) { + bool is_sparse = op->flags & DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE; struct drm_gpuvm_bo *preallocated_vm_bo; struct sg_table *sgt = NULL; int ret; @@ -1287,8 +1333,21 @@ static int panthor_vm_prepare_map_op_ctx(struct panthor_vm_op_ctx *op_ctx, (op->flags & DRM_PANTHOR_VM_BIND_OP_TYPE_MASK) != DRM_PANTHOR_VM_BIND_OP_TYPE_MAP) return -EINVAL; - /* Make sure the VA and size are in-bounds. */ - if (op->size > bo->base.size || op->bo_offset > bo->base.size - op->size) + /* uAPI mandates sparsely bound regions must not be executable. */ + if (is_sparse && !(op->flags & DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC)) + return -EINVAL; + + /* For non-sparse, make sure the VA and size are in-bounds. + * For sparse, this is not applicable, because the dummy BO is + * repeatedly mapped over a potentially wider VA range. + */ + if (!is_sparse && (op->size > bo->base.size || op->bo_offset > bo->base.size - op->size)) + return -EINVAL; + + /* For sparse, we don't expect any user BO, the BO we get passed + * is the dummy BO attached to the VM pool. + */ + if (is_sparse && (op->bo_handle || op->bo_offset)) return -EINVAL; /* If the BO has an exclusive VM attached, it can't be mapped to other VMs. */ @@ -1437,7 +1496,9 @@ panthor_vm_get_bo_for_va(struct panthor_vm *vm, u64 va, u64 *bo_offset) if (vma && vma->base.gem.obj) { drm_gem_object_get(vma->base.gem.obj); bo = to_panthor_bo(vma->base.gem.obj); - *bo_offset = vma->base.gem.offset + (va - vma->base.va.addr); + *bo_offset = !(vma->flags & DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE) ? + vma->base.gem.offset + (va - vma->base.va.addr) : + va & (SZ_2M - 1); } mutex_unlock(&vm->op_lock); @@ -1542,6 +1603,9 @@ int panthor_vm_pool_create_vm(struct panthor_device *ptdev, if (IS_ERR(vm)) return PTR_ERR(vm); + drm_gem_object_get(&pool->dummy->base); + vm->dummy = pool->dummy; + ret = xa_alloc(&pool->xa, &id, vm, XA_LIMIT(1, PANTHOR_MAX_VMS_PER_FILE), GFP_KERNEL); @@ -1641,6 +1705,8 @@ void panthor_vm_pool_destroy(struct panthor_file *pfile) xa_for_each(&pfile->vms->xa, i, vm) panthor_vm_destroy(vm); + if (pfile->vms->dummy) + drm_gem_object_put(&pfile->vms->dummy->base); xa_destroy(&pfile->vms->xa); kfree(pfile->vms); } @@ -1653,12 +1719,28 @@ void panthor_vm_pool_destroy(struct panthor_file *pfile) */ int panthor_vm_pool_create(struct panthor_file *pfile) { + struct panthor_gem_object *dummy; + int ret; + pfile->vms = kzalloc_obj(*pfile->vms); if (!pfile->vms) return -ENOMEM; xa_init_flags(&pfile->vms->xa, XA_FLAGS_ALLOC1); + + dummy = panthor_dummy_bo_create(pfile->ptdev); + if (IS_ERR(dummy)) { + ret = PTR_ERR(dummy); + goto err_destroy_vm_pool; + } + + pfile->vms->dummy = dummy; + return 0; + +err_destroy_vm_pool: + panthor_vm_pool_destroy(pfile); + return ret; } /* dummy TLB ops, the real TLB flush happens in panthor_vm_flush_range() */ @@ -1995,6 +2077,9 @@ static void panthor_vm_free(struct drm_gpuvm *gpuvm) free_io_pgtable_ops(vm->pgtbl_ops); + if (vm->dummy) + drm_gem_object_put(&vm->dummy->base); + drm_mm_takedown(&vm->mm); kfree(vm); } @@ -2154,7 +2239,30 @@ static void panthor_vma_init(struct panthor_vma *vma, u32 flags) #define PANTHOR_VM_MAP_FLAGS \ (DRM_PANTHOR_VM_BIND_OP_MAP_READONLY | \ DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | \ - DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED) + DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED | \ + DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE) + +static void +panthor_fix_sparse_map_offset(struct drm_gpuva_op_map *op, u32 flags) +{ + if (op && (flags & DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE)) + op->gem.offset = op->va.addr & (SZ_2M - 1); +} + +static int +panthor_vm_exec_map_op(struct panthor_vm *vm, u32 flags, + const struct drm_gpuva_op_map *op) +{ + struct panthor_gem_object *bo = to_panthor_bo(op->gem.obj); + int prot = flags_to_prot(flags); + + if (flags & DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE) + return panthor_vm_map_sparse(vm, op->va.addr, prot, + bo->dmap.sgt, op->va.range); + + return panthor_vm_map_pages(vm, op->va.addr, prot, bo->dmap.sgt, + op->gem.offset, op->va.range); +} static int panthor_gpuva_sm_step_map(struct drm_gpuva_op *op, void *priv) { @@ -2167,10 +2275,9 @@ static int panthor_gpuva_sm_step_map(struct drm_gpuva_op *op, void *priv) return -EINVAL; panthor_vma_init(vma, op_ctx->flags & PANTHOR_VM_MAP_FLAGS); + panthor_fix_sparse_map_offset(&op->map, vma->flags); - ret = panthor_vm_map_pages(vm, op->map.va.addr, flags_to_prot(vma->flags), - op_ctx->map.bo->dmap.sgt, op->map.gem.offset, - op->map.va.range); + ret = panthor_vm_exec_map_op(vm, vma->flags, &op->map); if (ret) { panthor_vm_op_ctx_return_vma(op_ctx, vma); return ret; @@ -2202,6 +2309,8 @@ static void unmap_hugepage_align(const struct drm_gpuva_op_remap *op, u64 *unmap_start, u64 *unmap_range) { + struct panthor_vma *unmap_vma = container_of(op->unmap->va, struct panthor_vma, base); + bool is_sparse = unmap_vma->flags & DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE; u64 aligned_unmap_start, aligned_unmap_end, unmap_end; unmap_end = *unmap_start + *unmap_range; @@ -2209,11 +2318,15 @@ unmap_hugepage_align(const struct drm_gpuva_op_remap *op, aligned_unmap_end = ALIGN(unmap_end, SZ_2M); /* If we're dealing with a huge page, make sure the unmap region is - * aligned on the start of the page. + * aligned on the start of the page. If the unmapped VMA stands for + * a sparse mapping, always assume the backing storage is a THP, since + * the overhead of unmapping 2MiB worth of 4KiB pages and remapping + * some of them is offset by the logic of working out whether it's + * the opposite case right below. This also holds true for op->next. */ if (op->prev && aligned_unmap_start < *unmap_start && op->prev->va.addr <= aligned_unmap_start && - iova_mapped_as_huge_page(op->prev, *unmap_start)) { + (is_sparse || iova_mapped_as_huge_page(op->prev, *unmap_start))) { *unmap_range += *unmap_start - aligned_unmap_start; *unmap_start = aligned_unmap_start; } @@ -2223,7 +2336,7 @@ unmap_hugepage_align(const struct drm_gpuva_op_remap *op, */ if (op->next && aligned_unmap_end > unmap_end && op->next->va.addr + op->next->va.range >= aligned_unmap_end && - iova_mapped_as_huge_page(op->next, unmap_end - 1)) { + (is_sparse || iova_mapped_as_huge_page(op->next, unmap_end - 1))) { *unmap_range += aligned_unmap_end - unmap_end; } } @@ -2240,6 +2353,11 @@ static int panthor_gpuva_sm_step_remap(struct drm_gpuva_op *op, drm_gpuva_op_remap_to_unmap_range(&op->remap, &unmap_start, &unmap_range); + /* op->remap.prev's BO offset is always the same as the unmap va's, but + * that of op->remap.next must be adjusted so as to remain < SZ_2M + */ + panthor_fix_sparse_map_offset(op->remap.next, unmap_vma->flags); + /* * ARM IOMMU page table management code disallows partial unmaps of huge pages, * so when a partial unmap is requested, we must first unmap the entire huge @@ -2259,14 +2377,19 @@ static int panthor_gpuva_sm_step_remap(struct drm_gpuva_op *op, } if (op->remap.prev) { - struct panthor_gem_object *bo = to_panthor_bo(op->remap.prev->gem.obj); u64 offset = op->remap.prev->gem.offset + unmap_start - op->remap.prev->va.addr; u64 size = op->remap.prev->va.addr + op->remap.prev->va.range - unmap_start; - if (!unmap_vma->evicted) { - ret = panthor_vm_map_pages(vm, unmap_start, - flags_to_prot(unmap_vma->flags), - bo->dmap.sgt, offset, size); + if (!unmap_vma->evicted && size > 0) { + struct drm_gpuva_op_map map_op = { + .va.addr = unmap_start, + .va.range = size, + .gem.obj = op->remap.prev->gem.obj, + .gem.offset = offset, + }; + panthor_fix_sparse_map_offset(&map_op, unmap_vma->flags); + + ret = panthor_vm_exec_map_op(vm, unmap_vma->flags, &map_op); if (ret) return ret; } @@ -2277,14 +2400,19 @@ static int panthor_gpuva_sm_step_remap(struct drm_gpuva_op *op, } if (op->remap.next) { - struct panthor_gem_object *bo = to_panthor_bo(op->remap.next->gem.obj); u64 addr = op->remap.next->va.addr; u64 size = unmap_start + unmap_range - op->remap.next->va.addr; - if (!unmap_vma->evicted) { - ret = panthor_vm_map_pages(vm, addr, flags_to_prot(unmap_vma->flags), - bo->dmap.sgt, op->remap.next->gem.offset, - size); + if (!unmap_vma->evicted && size > 0) { + struct drm_gpuva_op_map map_op = { + .va.addr = addr, + .va.range = size, + .gem.obj = op->remap.next->gem.obj, + .gem.offset = op->remap.next->gem.offset, + }; + panthor_fix_sparse_map_offset(&map_op, unmap_vma->flags); + + ret = panthor_vm_exec_map_op(vm, unmap_vma->flags, &map_op); if (ret) return ret; } @@ -2481,11 +2609,17 @@ static int remap_evicted_vma(struct drm_gpuvm_bo *vm_bo, ret = panthor_vm_lock_region(vm, evicted_vma->base.va.addr, evicted_vma->base.va.range); if (!ret) { - ret = panthor_vm_map_pages(vm, evicted_vma->base.va.addr, - flags_to_prot(evicted_vma->flags), - bo->dmap.sgt, - evicted_vma->base.gem.offset, - evicted_vma->base.va.range); + struct drm_gpuva_op_map map_op = { + .va.addr = evicted_vma->base.va.addr, + .va.range = evicted_vma->base.va.range, + .gem.obj = &bo->base, + .gem.offset = evicted_vma->base.gem.offset, + }; + if (evicted_vma->flags & DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE) + drm_WARN_ON_ONCE(&vm->ptdev->base, map_op.gem.offset != + (map_op.va.addr & (SZ_2M - 1))); + + ret = panthor_vm_exec_map_op(vm, evicted_vma->flags, &map_op); if (!ret) evicted_vma->evicted = false; @@ -2849,7 +2983,13 @@ panthor_vm_bind_prepare_op_ctx(struct drm_file *file, switch (op->flags & DRM_PANTHOR_VM_BIND_OP_TYPE_MASK) { case DRM_PANTHOR_VM_BIND_OP_TYPE_MAP: - gem = drm_gem_object_lookup(file, op->bo_handle); + if (!(op->flags & DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE)) { + gem = drm_gem_object_lookup(file, op->bo_handle); + } else { + gem = &vm->dummy->base; + drm_gem_object_get(&vm->dummy->base); + } + ret = panthor_vm_prepare_map_op_ctx(op_ctx, vm, gem ? to_panthor_bo(gem) : NULL, op); @@ -3057,6 +3197,9 @@ int panthor_vm_map_bo_range(struct panthor_vm *vm, struct panthor_gem_object *bo struct panthor_vm_op_ctx op_ctx; int ret; + if (drm_WARN_ON(&vm->ptdev->base, flags & DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE)) + return -EINVAL; + ret = panthor_vm_prepare_map_op_ctx(&op_ctx, vm, bo, &op); if (ret) return ret; diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h index 14a93a4ef6ff..a2ff0f4ec691 100644 --- a/include/uapi/drm/panthor_drm.h +++ b/include/uapi/drm/panthor_drm.h @@ -614,6 +614,18 @@ enum drm_panthor_vm_bind_op_flags { */ DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED = 1 << 2, + /** + * @DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE: Sparsely map a virtual memory range + * + * Only valid with DRM_PANTHOR_VM_BIND_OP_TYPE_MAP. + * + * When this flag is set, the whole vm_bind range is mapped over a dummy object in a cyclic + * fashion, and all GPU reads from addresses in the range return undefined values. This flag + * being set means drm_panthor_vm_bind_op::bo_offset and drm_panthor_vm_bind_op::bo_handle + * must both be set to 0. DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC must also be set. + */ + DRM_PANTHOR_VM_BIND_OP_MAP_SPARSE = 1 << 3, + /** * @DRM_PANTHOR_VM_BIND_OP_TYPE_MASK: Mask used to determine the type of operation. */ -- cgit From 445075e199526096bc6f47dace4391efec88cf7e Mon Sep 17 00:00:00 2001 From: Yifan Zhang Date: Wed, 6 May 2026 21:45:05 +0800 Subject: drm/amdgpu: add ioctl to handle RAS poison error Add a new DRM_IOCTL_AMDGPU_PROC_OPTIONS ioctl with the AMDGPU_PROC_OPTIONS_OP_KFD_SIGBUS_DELAY option, allowing userspace (ROCr) to control per-process SIGBUS delivery. Userspace for this can be found at: https://github.com/ROCm/rocm-systems/pull/6190 Reviewed-by: Lijo Lazar Reviewed-by: Alex Deucher Signed-off-by: Yifan Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 6 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 27 ++++++++++++ drivers/gpu/drm/amd/amdkfd/kfd_events.c | 69 +++++++++++++++++++++++++++++- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 15 +++++++ drivers/gpu/drm/amd/amdkfd/kfd_process.c | 33 ++++++++++++++ include/uapi/drm/amdgpu_drm.h | 21 +++++++++ 8 files changed, 173 insertions(+), 1 deletion(-) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 7b09410d6d8f..5f775c6e9240 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1468,6 +1468,8 @@ int amdgpu_enable_vblank_kms(struct drm_crtc *crtc); void amdgpu_disable_vblank_kms(struct drm_crtc *crtc); int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); +int amdgpu_proc_options_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); /* * functions used by amdgpu_encoder.c diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index d403af5fb552..32132be6e683 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h @@ -210,6 +210,7 @@ int amdgpu_amdkfd_evict_userptr(struct mmu_interval_notifier *mni, int amdgpu_amdkfd_bo_validate_and_fence(struct amdgpu_bo *bo, uint32_t domain, struct dma_fence *fence); +int amdgpu_amdkfd_set_sigbus_delay(struct task_struct *task, u32 ms); #else static inline bool amdkfd_fence_check_mm(struct dma_fence *f, struct mm_struct *mm) @@ -241,6 +242,11 @@ int amdgpu_amdkfd_bo_validate_and_fence(struct amdgpu_bo *bo, { return 0; } +static inline +int amdgpu_amdkfd_set_sigbus_delay(struct task_struct *task, u32 ms) +{ + return -EOPNOTSUPP; +} #endif /* Shared API */ int amdgpu_amdkfd_alloc_kernel_mem(struct amdgpu_device *adev, size_t size, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index bf4260269681..503bb64c1e55 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -3076,6 +3076,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(AMDGPU_USERQ_SIGNAL, amdgpu_userq_signal_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_USERQ_WAIT, amdgpu_userq_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(AMDGPU_GEM_LIST_HANDLES, amdgpu_gem_list_handles_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_PROC_OPTIONS, amdgpu_proc_options_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), }; static const struct drm_driver amdgpu_kms_driver = { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 71272f40feef..72b6f55699a4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -1423,6 +1423,33 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return 0; } +/** + * amdgpu_proc_options_ioctl - set per-fd user options + * + * @dev: drm dev pointer + * @data: pointer to struct drm_amdgpu_proc_options + * @filp: drm file + * + * Sets options stored on the per-file amdgpu_fpriv. Currently the only + * supported option is %AMDGPU_PROC_OPTIONS_OP_KFD_SIGBUS_DELAY which + * controls how KFD delivers SIGBUS for poison/RAS events to the calling + * process (immediate, suppressed, or delayed by N milliseconds). + */ +int amdgpu_proc_options_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp) +{ + struct drm_amdgpu_proc_options *args = data; + + switch (args->op) { + case AMDGPU_PROC_OPTIONS_OP_KFD_SIGBUS_DELAY: + return amdgpu_amdkfd_set_sigbus_delay(current, + args->kfd_sigbus_delay.value); + default: + DRM_DEBUG_KMS("Invalid user option op %u\n", args->op); + return -EINVAL; + } +} + /** * amdgpu_driver_open_kms - drm callback for open * diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 81900b49d9d5..71e8f9a23215 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -29,10 +29,12 @@ #include #include #include +#include #include "kfd_priv.h" #include "kfd_events.h" #include "kfd_device_queue_manager.h" #include +#include /* * Wrapper around wait_queue_entry_t @@ -1338,6 +1340,71 @@ void kfd_signal_reset_event(struct kfd_node *dev) srcu_read_unlock(&kfd_processes_srcu, idx); } +/* + * Per-process opt-in for poison-consumption SIGBUS handling. + * + * Default: kernel sends SIGBUS to the process immediately when poison is + * consumed, in addition to delivering the KFD HW/MEMORY exception events. + * + * Userspace (ROCr) can opt-in per-process via the + * DRM_IOCTL_AMDGPU_PROC_OPTIONS / AMDGPU_PROC_OPTIONS_OP_KFD_SIGBUS_DELAY + * option. This lets the app's registered system-event callback handle the + * RAS error first, instead of being killed by SIGBUS. + * + * Encoded value (stored on the kfd_process): + * 0 - default: SIGBUS immediately (no opt-in) + * 0xFFFFFFFF - opt-in, never escalate to SIGBUS + * N (other) - opt-in, escalate to SIGBUS after N ms if app does not + * handle the error in time (safety timeout) + */ + +void kfd_signal_sigbus_delayed_fn(struct work_struct *work) +{ + struct kfd_process *p = container_of(to_delayed_work(work), + struct kfd_process, signal_work); + + if (p->lead_thread) + send_sig(SIGBUS, p->lead_thread, 0); + + kfd_unref_process(p); +} + +static void kfd_signal_sigbus_with_delay(struct kfd_node *dev, + struct kfd_process *p) +{ + u32 delay_ms = atomic_read(&p->kfd_sigbus_delay_ms); + + if (delay_ms == AMDGPU_PROC_OPTIONS_KFD_SIGBUS_DELAY_DISABLED) { + dev_info(dev->adev->dev, + "SIGBUS suppressed for process %s(pid:%d): app opted in to handle RAS error\n", + p->lead_thread->comm, p->lead_thread->pid); + return; + } + + if (delay_ms == 0) + goto send_now; + + /* + * Take an extra reference for the delayed worker. If the work is + * already pending (e.g. another device of this process consumed poison + * just before), drop the reference and skip rescheduling - the process + * only needs to be notified once. + */ + kref_get(&p->ref); + if (!schedule_delayed_work(&p->signal_work, msecs_to_jiffies(delay_ms))) { + kfd_unref_process(p); + return; + } + + dev_info(dev->adev->dev, + "Deferring SIGBUS to process %s(pid:%d) by %u ms (RAS error opt-in safety timeout)\n", + p->lead_thread->comm, p->lead_thread->pid, delay_ms); + return; + +send_now: + send_sig(SIGBUS, p->lead_thread, 0); +} + void kfd_signal_poison_consumed_event(struct kfd_node *dev, u32 pasid) { struct kfd_process *p = kfd_lookup_process_by_pasid(pasid, NULL); @@ -1392,7 +1459,7 @@ void kfd_signal_poison_consumed_event(struct kfd_node *dev, u32 pasid) rcu_read_unlock(); /* user application will handle SIGBUS signal */ - send_sig(SIGBUS, p->lead_thread, 0); + kfd_signal_sigbus_with_delay(dev, p); kfd_unref_process(p); } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index acd0e41e744c..591f41eadae2 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -957,6 +957,20 @@ struct kfd_process { size_t signal_event_count; bool signal_event_limit_reached; + /** + * @kfd_sigbus_delay_ms: Per-process KFD SIGBUS delivery option for + * poison/RAS events (set via DRM_IOCTL_AMDGPU_PROC_OPTIONS / + * AMDGPU_PROC_OPTIONS_OP_KFD_SIGBUS_DELAY). + * + * 0 - send SIGBUS immediately (default) + * 0xFFFFFFFF - suppress SIGBUS delivery + * other - delay SIGBUS delivery by this many milliseconds + */ + atomic_t kfd_sigbus_delay_ms; + + /* Delayed signal delivery to user */ + struct delayed_work signal_work; + /* Information used for memory eviction */ void *kgd_process_info; /* Eviction fence that is attached to all the BOs of this process. The @@ -1554,6 +1568,7 @@ void kfd_signal_vm_fault_event(struct kfd_process_device *pdd, void kfd_signal_reset_event(struct kfd_node *dev); void kfd_signal_poison_consumed_event(struct kfd_node *dev, u32 pasid); +void kfd_signal_sigbus_delayed_fn(struct work_struct *work); void kfd_signal_process_terminate_event(struct kfd_process *p); static inline void kfd_flush_tlb(struct kfd_process_device *pdd) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 368283d53077..9838954d77da 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -986,6 +986,33 @@ out: return process; } +/** + * amdgpu_amdkfd_set_sigbus_delay - Set per-process KFD SIGBUS delay + * @task: task in the target process + * @ms: encoded delay value (0 = immediate, 0xFFFFFFFF = suppress, + * otherwise delay in milliseconds) + * + * Stores the SIGBUS delivery option on the kfd_process associated with + * @task. If the calling process has not opened /dev/kfd yet (no + * kfd_process exists), this is a no-op - the option only applies to + * processes that actually use KFD. + */ +int amdgpu_amdkfd_set_sigbus_delay(struct task_struct *task, u32 ms) +{ + struct kfd_process *p; + + if (!task->mm) + return -EINVAL; + + p = kfd_lookup_process_by_mm(task->mm); + if (!p) + return 0; + + atomic_set(&p->kfd_sigbus_delay_ms, ms); + kfd_unref_process(p); + return 0; +} + static struct kfd_process *find_process_by_mm(const struct mm_struct *mm) { struct kfd_process *process; @@ -1322,6 +1349,11 @@ void kfd_process_notifier_release_internal(struct kfd_process *p) kfd_process_table_remove(p); cancel_delayed_work_sync(&p->eviction_work); cancel_delayed_work_sync(&p->restore_work); + /* + * If work pending, cancel it and drop the extra ref + */ + if (cancel_delayed_work_sync(&p->signal_work)) + kfd_unref_process(p); /* * Dequeue and destroy user queues, it is not safe for GPU to access @@ -1578,6 +1610,7 @@ struct kfd_process *create_process(const struct task_struct *thread, bool primar INIT_DELAYED_WORK(&process->eviction_work, evict_process_worker); INIT_DELAYED_WORK(&process->restore_work, restore_process_worker); + INIT_DELAYED_WORK(&process->signal_work, kfd_signal_sigbus_delayed_fn); process->last_restore_timestamp = get_jiffies_64(); err = kfd_event_init_process(process); if (err) diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 9f3090db2f16..b32c72a662b6 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -58,6 +58,7 @@ extern "C" { #define DRM_AMDGPU_USERQ_SIGNAL 0x17 #define DRM_AMDGPU_USERQ_WAIT 0x18 #define DRM_AMDGPU_GEM_LIST_HANDLES 0x19 +#define DRM_AMDGPU_PROC_OPTIONS 0x1A #define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create) #define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap) @@ -79,6 +80,7 @@ extern "C" { #define DRM_IOCTL_AMDGPU_USERQ_SIGNAL DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_USERQ_SIGNAL, struct drm_amdgpu_userq_signal) #define DRM_IOCTL_AMDGPU_USERQ_WAIT DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_USERQ_WAIT, struct drm_amdgpu_userq_wait) #define DRM_IOCTL_AMDGPU_GEM_LIST_HANDLES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_LIST_HANDLES, struct drm_amdgpu_gem_list_handles) +#define DRM_IOCTL_AMDGPU_PROC_OPTIONS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_PROC_OPTIONS, struct drm_amdgpu_proc_options) /** * DOC: memory domains @@ -1673,6 +1675,25 @@ struct drm_amdgpu_info_uq_metadata { #define AMDGPU_FAMILY_GC_11_5_4 154 /* GC 11.5.4 */ #define AMDGPU_FAMILY_GC_12_0_0 152 /* GC 12.0.0 */ +/* + * Definition of user options + * + * option: AMDGPU_PROC_OPTIONS_OP_KFD_SIGBUS_DELAY + * 0: Disable sigbus delay - SIGBUS will be raised immediately + * 0xFFFFFFFF: SIGBUS will not be raised + * other: Set the sigbus delay in milliseconds + */ +#define AMDGPU_PROC_OPTIONS_OP_KFD_SIGBUS_DELAY 0 + +#define AMDGPU_PROC_OPTIONS_KFD_SIGBUS_DELAY_DISABLED 0xFFFFFFFFu + +struct drm_amdgpu_proc_options { + __u32 op; + struct { + __u32 value; + } kfd_sigbus_delay; +}; + #if defined(__cplusplus) } #endif -- cgit From e239d3e3cbb7b27522727371fa66523fc769f454 Mon Sep 17 00:00:00 2001 From: Chenyu Chen Date: Tue, 26 May 2026 09:52:28 +0800 Subject: drm/edid: parse panel type from DisplayID 2.x Display Parameters Parse the Display Parameters Data Block (tag 0x21) defined in DisplayID v2.1a Section 4.2.6. Extract the Display Device Technology field from the color depth and device technology byte, which indicates whether the panel uses LCD or OLED technology. Add a panel_type field to struct drm_display_info and populate it during DisplayID iteration so downstream drivers can use it for panel-type-dependent behavior. Add DRM_MODE_PANEL_TYPE_LCD to the UAPI panel type property alongside the existing OLED value. Assisted-by: Copilot:Claude-Opus-4.6 Signed-off-by: Chenyu Chen Reviewed-by: Mario Limonciello (AMD) Signed-off-by: Alex Deucher --- drivers/gpu/drm/drm_connector.c | 3 ++- drivers/gpu/drm/drm_displayid_internal.h | 24 +++++++++++++++++ drivers/gpu/drm/drm_edid.c | 45 ++++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 6 +++++ include/uapi/drm/drm_mode.h | 1 + 5 files changed, 78 insertions(+), 1 deletion(-) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 3fa4d2082cd7..9d820a2a87ce 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1176,6 +1176,7 @@ static const struct drm_prop_enum_list drm_link_status_enum_list[] = { static const struct drm_prop_enum_list drm_panel_type_enum_list[] = { { DRM_MODE_PANEL_TYPE_UNKNOWN, "unknown" }, { DRM_MODE_PANEL_TYPE_OLED, "OLED" }, + { DRM_MODE_PANEL_TYPE_LCD, "LCD" }, }; /** @@ -1508,7 +1509,7 @@ EXPORT_SYMBOL(drm_hdmi_connector_get_output_format_name); * never read back the value of "DPMS" because it can be incorrect. * panel_type: * Immutable enum property to indicate the type of connected panel. - * Possible values are "unknown" (default) and "OLED". + * Possible values are "unknown" (default), "OLED", and "LCD". * PATH: * Connector path property to identify how this sink is physically * connected. Used by DP MST. This should be set by calling diff --git a/drivers/gpu/drm/drm_displayid_internal.h b/drivers/gpu/drm/drm_displayid_internal.h index 5b1b32f73516..6f431aafafcf 100644 --- a/drivers/gpu/drm/drm_displayid_internal.h +++ b/drivers/gpu/drm/drm_displayid_internal.h @@ -142,6 +142,30 @@ struct displayid_formula_timing_block { struct displayid_formula_timings_9 timings[]; } __packed; +#define DISPLAYID_DEVICE_TECH_UNSPECIFIED 0 +#define DISPLAYID_DEVICE_TECH_LCD 1 +#define DISPLAYID_DEVICE_TECH_OLED 2 + +#define DISPLAYID_DISPLAY_PARAMS_DEVICE_TECH GENMASK(6, 4) + +struct displayid_display_params_block { + struct displayid_block base; + __le16 horiz_image_size; + __le16 vert_image_size; + __le16 horiz_pixel_count; + __le16 vert_pixel_count; + u8 features; + u8 primary_color1[3]; + u8 primary_color2[3]; + u8 primary_color3[3]; + u8 white_point[3]; + __le16 max_luminance_full; + __le16 max_luminance_10; + __le16 min_luminance; + u8 color_depth_and_tech; /* [2:0] depth, [6:4] device tech, [7] theme */ + u8 gamma_eotf; +} __packed; + #define DISPLAYID_VESA_MSO_OVERLAP GENMASK(3, 0) #define DISPLAYID_VESA_MSO_MODE GENMASK(6, 5) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index aebbff8ac992..ae26618a9a57 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -6713,6 +6713,8 @@ static void drm_reset_display_info(struct drm_connector *connector) info->source_physical_address = CEC_PHYS_ADDR_INVALID; memset(&info->amd_vsdb, 0, sizeof(info->amd_vsdb)); + + info->panel_type = DRM_MODE_PANEL_TYPE_UNKNOWN; } static void drm_displayid_process_base_section_header(struct drm_connector *connector, @@ -6731,6 +6733,45 @@ static void drm_displayid_process_base_section_header(struct drm_connector *conn info->non_desktop = true; } +static void +drm_displayid_parse_display_params(struct drm_connector *connector, + const struct displayid_block *block) +{ + struct drm_display_info *info = &connector->display_info; + const struct displayid_display_params_block *params = + (const struct displayid_display_params_block *)block; + u8 tech; + + if (block->num_bytes < sizeof(*params) - sizeof(params->base)) { + drm_dbg_kms(connector->dev, + "[CONNECTOR:%d:%s] DisplayID Display Parameters block too short (%u < %zu)\n", + connector->base.id, connector->name, + block->num_bytes, + sizeof(*params) - sizeof(params->base)); + return; + } + + tech = FIELD_GET(DISPLAYID_DISPLAY_PARAMS_DEVICE_TECH, + params->color_depth_and_tech); + + drm_dbg_kms(connector->dev, + "[CONNECTOR:%d:%s] DisplayID Display Parameters: device technology %s\n", + connector->base.id, connector->name, + tech == DISPLAYID_DEVICE_TECH_LCD ? "LCD" : + tech == DISPLAYID_DEVICE_TECH_OLED ? "OLED" : "unspecified"); + + switch (tech) { + case DISPLAYID_DEVICE_TECH_LCD: + info->panel_type = DRM_MODE_PANEL_TYPE_LCD; + break; + case DISPLAYID_DEVICE_TECH_OLED: + info->panel_type = DRM_MODE_PANEL_TYPE_OLED; + break; + default: + break; + } +} + static void update_displayid_info(struct drm_connector *connector, const struct drm_edid *drm_edid) { @@ -6744,6 +6785,10 @@ static void update_displayid_info(struct drm_connector *connector, drm_displayid_process_base_section_header(connector, &iter); base_section_header_processed = true; } + + if (displayid_version(&iter) == DISPLAY_ID_STRUCTURE_VER_20 && + block->tag == DATA_BLOCK_2_DISPLAY_PARAMETERS) + drm_displayid_parse_display_params(connector, block); } displayid_iter_end(&iter); } diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 5ad62c207d00..cd06a3b914a0 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -921,6 +921,12 @@ struct drm_display_info { * @amd_vsdb: AMD-specific VSDB information. */ struct drm_amd_vsdb_info amd_vsdb; + + /** + * @panel_type: Panel type from DisplayID Display Parameters + * Data Block (tag 0x21). Uses DRM_MODE_PANEL_TYPE_* constants. + */ + u8 panel_type; }; int drm_display_info_set_bus_formats(struct drm_display_info *info, diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 381a3e857d4e..bd435effdcee 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -155,6 +155,7 @@ extern "C" { /* Panel type property */ #define DRM_MODE_PANEL_TYPE_UNKNOWN 0 #define DRM_MODE_PANEL_TYPE_OLED 1 +#define DRM_MODE_PANEL_TYPE_LCD 2 /* * DRM_MODE_ROTATE_ -- cgit From cdeb5e248de11537cf23cd5174f6c55bab2e850b Mon Sep 17 00:00:00 2001 From: Riana Tauro Date: Thu, 18 Jun 2026 11:36:35 +0530 Subject: drm/xe/uapi: Add additional error components to xe drm_ras Add additional Error components supported by XE drm_ras (Reliability, Availability and Serviceability). Reviewed-by: Aravind Iddamsetty Reviewed-by: Mallesh Koujalagi Acked-by: Rodrigo Vivi Link: https://patch.msgid.link/20260618060633.2790109-9-riana.tauro@intel.com Signed-off-by: Riana Tauro --- include/uapi/drm/xe_drm.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'include/uapi') diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 48e9f1fdb78d..50c80af4ad4e 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -2589,6 +2589,12 @@ enum drm_xe_ras_error_component { DRM_XE_RAS_ERR_COMP_CORE_COMPUTE = 1, /** @DRM_XE_RAS_ERR_COMP_SOC_INTERNAL: SoC Internal Error */ DRM_XE_RAS_ERR_COMP_SOC_INTERNAL, + /** @DRM_XE_RAS_ERR_COMP_DEVICE_MEMORY: Device Memory Error */ + DRM_XE_RAS_ERR_COMP_DEVICE_MEMORY, + /** @DRM_XE_RAS_ERR_COMP_PCIE: PCIe Subsystem Error */ + DRM_XE_RAS_ERR_COMP_PCIE, + /** @DRM_XE_RAS_ERR_COMP_FABRIC: Fabric Subsystem Error */ + DRM_XE_RAS_ERR_COMP_FABRIC, /** @DRM_XE_RAS_ERR_COMP_MAX: Max Error */ DRM_XE_RAS_ERR_COMP_MAX /* non-ABI */ }; @@ -2606,7 +2612,10 @@ enum drm_xe_ras_error_component { */ #define DRM_XE_RAS_ERROR_COMPONENT_NAMES { \ [DRM_XE_RAS_ERR_COMP_CORE_COMPUTE] = "core-compute", \ - [DRM_XE_RAS_ERR_COMP_SOC_INTERNAL] = "soc-internal" \ + [DRM_XE_RAS_ERR_COMP_SOC_INTERNAL] = "soc-internal", \ + [DRM_XE_RAS_ERR_COMP_DEVICE_MEMORY] = "device-memory", \ + [DRM_XE_RAS_ERR_COMP_PCIE] = "pcie", \ + [DRM_XE_RAS_ERR_COMP_FABRIC] = "fabric", \ } #if defined(__cplusplus) -- cgit From 1258f9c9ff1dba0d081e27a5f85597a916249988 Mon Sep 17 00:00:00 2001 From: Chenyu Chen Date: Tue, 26 May 2026 10:59:50 +0800 Subject: drm/edid: parse panel type from DisplayID 2.x Display Parameters Parse the Display Parameters Data Block (tag 0x21) defined in DisplayID v2.1a Section 4.2.6. Extract the Display Device Technology field from the color depth and device technology byte, which indicates whether the panel uses LCD or OLED technology. Add a panel_type field to struct drm_display_info and populate it during DisplayID iteration so downstream drivers can use it for panel-type-dependent behavior. Add DRM_MODE_PANEL_TYPE_LCD to the UAPI panel type property alongside the existing OLED value. Assisted-by: Copilot:Claude-Opus-4.6 Signed-off-by: Chenyu Chen Reviewed-by: Jani Nikula Reviewed-by: Mario Limonciello (AMD) Link: https://patch.msgid.link/20260526030254.1460480-3-chen-yu.chen@amd.com Signed-off-by: Mario Limonciello --- drivers/gpu/drm/drm_connector.c | 3 ++- drivers/gpu/drm/drm_displayid_internal.h | 24 +++++++++++++++++ drivers/gpu/drm/drm_edid.c | 45 ++++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 6 +++++ include/uapi/drm/drm_mode.h | 1 + 5 files changed, 78 insertions(+), 1 deletion(-) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index cbb067d02cb9..d194312cb6c5 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1189,6 +1189,7 @@ static const struct drm_prop_enum_list drm_link_status_enum_list[] = { static const struct drm_prop_enum_list drm_panel_type_enum_list[] = { { DRM_MODE_PANEL_TYPE_UNKNOWN, "unknown" }, { DRM_MODE_PANEL_TYPE_OLED, "OLED" }, + { DRM_MODE_PANEL_TYPE_LCD, "LCD" }, }; /** @@ -1533,7 +1534,7 @@ EXPORT_SYMBOL(drm_hdmi_connector_get_output_format_name); * never read back the value of "DPMS" because it can be incorrect. * panel_type: * Immutable enum property to indicate the type of connected panel. - * Possible values are "unknown" (default) and "OLED". + * Possible values are "unknown" (default), "OLED", and "LCD". * PATH: * Connector path property to identify how this sink is physically * connected. Used by DP MST. This should be set by calling diff --git a/drivers/gpu/drm/drm_displayid_internal.h b/drivers/gpu/drm/drm_displayid_internal.h index 5b1b32f73516..6f431aafafcf 100644 --- a/drivers/gpu/drm/drm_displayid_internal.h +++ b/drivers/gpu/drm/drm_displayid_internal.h @@ -142,6 +142,30 @@ struct displayid_formula_timing_block { struct displayid_formula_timings_9 timings[]; } __packed; +#define DISPLAYID_DEVICE_TECH_UNSPECIFIED 0 +#define DISPLAYID_DEVICE_TECH_LCD 1 +#define DISPLAYID_DEVICE_TECH_OLED 2 + +#define DISPLAYID_DISPLAY_PARAMS_DEVICE_TECH GENMASK(6, 4) + +struct displayid_display_params_block { + struct displayid_block base; + __le16 horiz_image_size; + __le16 vert_image_size; + __le16 horiz_pixel_count; + __le16 vert_pixel_count; + u8 features; + u8 primary_color1[3]; + u8 primary_color2[3]; + u8 primary_color3[3]; + u8 white_point[3]; + __le16 max_luminance_full; + __le16 max_luminance_10; + __le16 min_luminance; + u8 color_depth_and_tech; /* [2:0] depth, [6:4] device tech, [7] theme */ + u8 gamma_eotf; +} __packed; + #define DISPLAYID_VESA_MSO_OVERLAP GENMASK(3, 0) #define DISPLAYID_VESA_MSO_MODE GENMASK(6, 5) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index aebbff8ac992..ae26618a9a57 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -6713,6 +6713,8 @@ static void drm_reset_display_info(struct drm_connector *connector) info->source_physical_address = CEC_PHYS_ADDR_INVALID; memset(&info->amd_vsdb, 0, sizeof(info->amd_vsdb)); + + info->panel_type = DRM_MODE_PANEL_TYPE_UNKNOWN; } static void drm_displayid_process_base_section_header(struct drm_connector *connector, @@ -6731,6 +6733,45 @@ static void drm_displayid_process_base_section_header(struct drm_connector *conn info->non_desktop = true; } +static void +drm_displayid_parse_display_params(struct drm_connector *connector, + const struct displayid_block *block) +{ + struct drm_display_info *info = &connector->display_info; + const struct displayid_display_params_block *params = + (const struct displayid_display_params_block *)block; + u8 tech; + + if (block->num_bytes < sizeof(*params) - sizeof(params->base)) { + drm_dbg_kms(connector->dev, + "[CONNECTOR:%d:%s] DisplayID Display Parameters block too short (%u < %zu)\n", + connector->base.id, connector->name, + block->num_bytes, + sizeof(*params) - sizeof(params->base)); + return; + } + + tech = FIELD_GET(DISPLAYID_DISPLAY_PARAMS_DEVICE_TECH, + params->color_depth_and_tech); + + drm_dbg_kms(connector->dev, + "[CONNECTOR:%d:%s] DisplayID Display Parameters: device technology %s\n", + connector->base.id, connector->name, + tech == DISPLAYID_DEVICE_TECH_LCD ? "LCD" : + tech == DISPLAYID_DEVICE_TECH_OLED ? "OLED" : "unspecified"); + + switch (tech) { + case DISPLAYID_DEVICE_TECH_LCD: + info->panel_type = DRM_MODE_PANEL_TYPE_LCD; + break; + case DISPLAYID_DEVICE_TECH_OLED: + info->panel_type = DRM_MODE_PANEL_TYPE_OLED; + break; + default: + break; + } +} + static void update_displayid_info(struct drm_connector *connector, const struct drm_edid *drm_edid) { @@ -6744,6 +6785,10 @@ static void update_displayid_info(struct drm_connector *connector, drm_displayid_process_base_section_header(connector, &iter); base_section_header_processed = true; } + + if (displayid_version(&iter) == DISPLAY_ID_STRUCTURE_VER_20 && + block->tag == DATA_BLOCK_2_DISPLAY_PARAMETERS) + drm_displayid_parse_display_params(connector, block); } displayid_iter_end(&iter); } diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 4317166562cf..0cb72aa081d9 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -989,6 +989,12 @@ struct drm_display_info { * @amd_vsdb: AMD-specific VSDB information. */ struct drm_amd_vsdb_info amd_vsdb; + + /** + * @panel_type: Panel type from DisplayID Display Parameters + * Data Block (tag 0x21). Uses DRM_MODE_PANEL_TYPE_* constants. + */ + u8 panel_type; }; int drm_display_info_set_bus_formats(struct drm_display_info *info, diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 381a3e857d4e..bd435effdcee 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -155,6 +155,7 @@ extern "C" { /* Panel type property */ #define DRM_MODE_PANEL_TYPE_UNKNOWN 0 #define DRM_MODE_PANEL_TYPE_OLED 1 +#define DRM_MODE_PANEL_TYPE_LCD 2 /* * DRM_MODE_ROTATE_ -- cgit From 3a8bfa1f2af71ca21818253753fccc53337b7b9b Mon Sep 17 00:00:00 2001 From: Rafael Passos Date: Tue, 30 Jun 2026 22:20:58 -0300 Subject: drm/xe: Documentation: fix chars used for subsection Fixes "ERROR: A level 2 section cannot be used here". Equal signs are reserved for document titles. This file docs gets imported by driver-uapi.rst, and the page title is defined there. Signed-off-by: Rafael Passos Reviewed-by: Randy Dunlap Tested-by: Randy Dunlap Link: https://patch.msgid.link/20260701012141.167868-1-rafael@rcpassos.me Signed-off-by: Rodrigo Vivi [Rodrigo modified the subject while pushing it] --- include/uapi/drm/xe_drm.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/uapi') diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h index 50c80af4ad4e..509202a7b13e 100644 --- a/include/uapi/drm/xe_drm.h +++ b/include/uapi/drm/xe_drm.h @@ -2537,21 +2537,21 @@ struct drm_xe_exec_queue_set_property { * Refer to Documentation/netlink/specs/drm_ras.yaml for complete interface specification. * * Node Registration - * ================= + * ----------------- * * The driver registers DRM RAS nodes for each error severity level. * enum drm_xe_ras_error_severity defines the node-id, while DRM_XE_RAS_ERROR_SEVERITY_NAMES maps * node-id to node-name. * * Error Classification - * ==================== + * -------------------- * * Each node contains a list of error counters. Each error is identified by a error-id and * an error-name. enum drm_xe_ras_error_component defines the error-id, while * DRM_XE_RAS_ERROR_COMPONENT_NAMES maps error-id to error-name. * * User Interface - * ============== + * -------------- * * To retrieve error values of a error counter, userspace applications should * follow the below steps: -- cgit From 15dcf7609fc04b9b13faf921f40d98491404dbf0 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 25 Jul 2026 00:59:12 -0300 Subject: drm/nouveau: allow allocating NVDEC channels via abi16 Add NOUVEAU_FIFO_ENGINE_NVDEC to the abi16 uAPI and accept it in channel allocation, mapping it to the NVDEC engine runlist. Skip the Turing copy-engine workaround object for NVDEC channels: the copy engines are not part of the NVDEC runlist, so the workaround object cannot be instantiated on such channels (and is not needed there). This is required for NVK to implement Vulkan Video H.264 decode on top of the NVDEC engine: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31867 Reviewed-by: Daniel Almeida Signed-off-by: Dave Airlie Link: https://patch.msgid.link/20260725035912.1016464-1-daniel.almeida@collabora.com --- drivers/gpu/drm/nouveau/nouveau_abi16.c | 14 ++++++++++---- drivers/gpu/drm/nouveau/nouveau_drv.h | 4 +++- include/uapi/drm/nouveau_drm.h | 1 + 3 files changed, 14 insertions(+), 5 deletions(-) (limited to 'include/uapi') diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 291203121f0c..4542d5f4ded8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -408,6 +408,9 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) case NOUVEAU_FIFO_ENGINE_CE: engine = NV_DEVICE_HOST_RUNLIST_ENGINES_CE; break; + case NOUVEAU_FIFO_ENGINE_NVDEC: + engine = NV_DEVICE_HOST_RUNLIST_ENGINES_NVDEC; + break; default: return nouveau_abi16_put(abi16, -ENOSYS); } @@ -485,10 +488,13 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) goto done; break; case NV_DEVICE_INFO_V0_TURING: - ret = nvif_object_ctor(&chan->chan->user, "abi16CeWar", 0, TURING_DMA_COPY_A, - NULL, 0, &chan->ce); - if (ret) - goto done; + if (engine != NV_DEVICE_HOST_RUNLIST_ENGINES_NVDEC) { + ret = nvif_object_ctor(&chan->chan->user, "abi16CeWar", + 0, TURING_DMA_COPY_A, NULL, 0, + &chan->ce); + if (ret) + goto done; + } break; default: break; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 1c2523e2f92e..5fc75dc750ed 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -10,7 +10,7 @@ #define DRIVER_MAJOR 1 #define DRIVER_MINOR 4 -#define DRIVER_PATCHLEVEL 2 +#define DRIVER_PATCHLEVEL 3 /* * 1.1.1: @@ -39,6 +39,8 @@ * - add variable page sizes and compression for Turing+ * 1.4.2: * - tell userspace LPTE/SPTE races are fixed. + * 1.4.3: + * - VDEC contexts can be created. */ #include diff --git a/include/uapi/drm/nouveau_drm.h b/include/uapi/drm/nouveau_drm.h index 1fa82fa6af38..c4905b3e4e91 100644 --- a/include/uapi/drm/nouveau_drm.h +++ b/include/uapi/drm/nouveau_drm.h @@ -89,6 +89,7 @@ struct drm_nouveau_getparam { #define NOUVEAU_FIFO_ENGINE_PPP 0x04 #define NOUVEAU_FIFO_ENGINE_BSP 0x08 #define NOUVEAU_FIFO_ENGINE_CE 0x30 +#define NOUVEAU_FIFO_ENGINE_NVDEC 0x300 struct drm_nouveau_channel_alloc { __u32 fb_ctxdma_handle; -- cgit From 6a03efb8613a6ffc23da42af41b3e51e975ea406 Mon Sep 17 00:00:00 2001 From: Timur Kristóf Date: Wed, 22 Jul 2026 18:59:22 +0200 Subject: drm/fourcc: Add modifiers for AMD GFX6-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GFX6-8 are the oldest GPUs supported by the amdgpu kernel driver, and the last ones that didn't support DRM format modifiers until now. These are the Southern Islands, Sea Islands and Volcanic Islands families of GPUs. On GFX6-8, the GFX block can only use pre-determined tiling modes which are programmed by the kernel according to the tiling mode table. GFX6 uses the GB_TILE_MODE0...31 registers, and GFX7-8 also has GB_MACROTILE_MODE0...15 registers. DCC is also supported on GFX8, albeit not displayable. Note that the tiling table is uAPI and userspace relies on specific modes being present at specific indices. How the tiling works is primarily determined by the so-called array mode. Use the TILE field to specify the array mode. Pixel data is organized into micro tiles. Each micro tile may be 8x8 / 8x8x4 / 8x8x8 pixels, depending on the array mode. Add the MICROTILE field to specify microtile mode. Microtiles may be further organized into macro tiles, which have many configurable parameters. Macro tile mode selection depends on how many bits per pixel an image has. Add the PIPE_CONFIG, TILE_SPLIT, BANK_WIDTH, BANK_HEIGHT, MACRO_TILE_ASPECT, NUM_BANKS fields to specify parameters of macro tiled modes. Furthermore, tiling is also influenced by memory configuration. Old RFC patches received feedback concerning that, so I looked into it specifically: GB_ADDR_CONFIG.ROW_SIZE needs to be considered when calculating TILE_SPLIT, but does not need to be included in the modifiers, and also PIPE_INTERLEAVE matters, but it's hardcoded to the same value on all GFX6-8 GPUs and changing it would break userspace, so let's assume it isn't going to change. Therefore we don't need to include that in modifiers. Mesa also reads NUM_RANKS but actually doesn't use its value on GFX6-8. As a side note, tiling works similarly on GFX4-5 (that is Evergreen and Northern Islands). But that will need some additional PIPE_CONFIG enum values as well as some extra fields not relevant to GFX6-8. Initially, let's only expose the tiling modes that are most relevant to sharing buffers between different processes: Exposed array modes (TILE field): - 1D_TILED_THIN1: micro tiled only - 2D_TILED_THIN1: macro tiled Exposed micro tile modes (MICROTILE field): - DISPLAY: supported by DCE (the display engine) - THIN: more efficient but not displayable Exposed macro tile modes: All possible parameters (25088 permutations). More modes may be exposed in the future as needed. Technically, the amount of possible combinations of all possible tiling parameters is in the range of hundreds of thousands, but in practice, there are just a handful of possible modifiers for a surface. For example on GFX8, a surface would have these modifiers, from best to worst performance: - 2D_TILED_THIN1 + THIN + DCC + macrotile params [1] - 2D_TILED_THIN1 + THIN + macrotile params [1] - 2D_TILED_THIN1 + DISPLAY + macrotile params [1] - 1D_TILED_THIN1 + THIN - 1D_TILED_THIN1 + DISPLAY - LINEAR [1] The macro tiling parameters depend on how many bits per pixel of the specific surface has and how the chip is configured. There is only one set of valid macrotile params for a given surface. DCC is only supported by GFX8 and newer, and only with non-displayable macrotiling modes. When sharing buffers between different GFX6-8 GPUs, it is very unlikely that they support the exact same macrotiling configuration, so they will likely need to use micro tiled modes, which are still much better than using linear buffers. (Note that currently Mesa always uses LINEAR when copying between two GPUs.) Suggested-by: Bas Nieuwenhuizen Signed-off-by: Timur Kristóf Reviewed-by: Marek Olšák Reviewed-by: Daniel Stone Reviewed-by: Alex Deucher Acked-by: Christian König Signed-off-by: Alex Deucher --- include/uapi/drm/drm_fourcc.h | 209 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 191 insertions(+), 18 deletions(-) (limited to 'include/uapi') diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index 3a4d4dc635bf..a103fdc0b3a3 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -1646,36 +1646,69 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) * For multi-plane formats the above surfaces get merged into one plane for * each format plane, based on the required alignment only. * - * Bits Parameter Notes - * ----- ------------------------ --------------------------------------------- + * Bits Parameter Notes + * ------- ------------------------ --------------------------------------------- + * + * DRM format modifier fields on AMD GPUs: + * 7:0 TILE_VERSION Values are AMD_FMT_MOD_TILE_VER_* + * 12:8 TILE Values are AMD_FMT_MOD_TILE__* + * 13 DCC Delta Color Compression, supported on GFX8 and newer + * 55:14 (chip specific) See below for details, depends on GFX block version + * 63:56 Vendor Value is DRM_FORMAT_MOD_VENDOR_AMD + * + * Chip specific fields on Gfx9 and newer: + * 14 DCC_RETILE + * 15 DCC_PIPE_ALIGN + * 16 DCC_INDEPENDENT_64B + * 17 DCC_INDEPENDENT_128B + * 19:18 DCC_MAX_COMPRESSED_BLOCK Values are AMD_FMT_MOD_DCC_BLOCK_* + * 20 DCC_CONSTANT_ENCODE + * 23:21 PIPE_XOR_BITS Only for some chips + * 26:24 BANK_XOR_BITS Only for some chips + * 29:27 PACKERS Only for some chips + * 32:30 RB Only for some chips + * 35:33 PIPE Only for some chips + * 55:36 - Reserved for future use, must be zero + * + * Chip specific fields on Gfx6-8: + * 16:14 MICROTILE Micro tile format + * 21:17 PIPE_CONFIG Number of pipes and how pipes are interleaved + * 24:22 TILE_SPLIT Tile split size + * 26:25 BANK_WIDTH Number of tiles in the X direction in the same bank + * 28:27 BANK_HEIGHT Number of tiles in the Y direction in the same bank + * 30:29 MACRO_TILE_ASPECT Macro tile aspect ratio + * 32:31 NUM_BANKS Number of banks + * 55:33 - Reserved for future use, must be zero * - * 7:0 TILE_VERSION Values are AMD_FMT_MOD_TILE_VER_* - * 12:8 TILE Values are AMD_FMT_MOD_TILE__* - * 13 DCC - * 14 DCC_RETILE - * 15 DCC_PIPE_ALIGN - * 16 DCC_INDEPENDENT_64B - * 17 DCC_INDEPENDENT_128B - * 19:18 DCC_MAX_COMPRESSED_BLOCK Values are AMD_FMT_MOD_DCC_BLOCK_* - * 20 DCC_CONSTANT_ENCODE - * 23:21 PIPE_XOR_BITS Only for some chips - * 26:24 BANK_XOR_BITS Only for some chips - * 29:27 PACKERS Only for some chips - * 32:30 RB Only for some chips - * 35:33 PIPE Only for some chips - * 55:36 - Reserved for future use, must be zero */ #define AMD_FMT_MOD fourcc_mod_code(AMD, 0) #define IS_AMD_FMT_MOD(val) (((val) >> 56) == DRM_FORMAT_MOD_VENDOR_AMD) -/* Reserve 0 for GFX8 and older */ +#define AMD_FMT_MOD_TILE_VER_GFX6 0 #define AMD_FMT_MOD_TILE_VER_GFX9 1 #define AMD_FMT_MOD_TILE_VER_GFX10 2 #define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3 #define AMD_FMT_MOD_TILE_VER_GFX11 4 #define AMD_FMT_MOD_TILE_VER_GFX12 5 +/* + * Gfx6-8 tiling modes. + * A complete reference implementation is found in addrlib in the Mesa code base. + * + * - Microtiled modes (1D): + * Pixel data is organized into micro tiles of 8x8 pixels. + * + * - Macrotiled modes (2D): + * Micro tiles are further organized into macro tiles. + * These are optimized for even load distribution among memory channels. + * + * Note that only THIN1 modes are exposed here. + * THICK and XTHICK are for 3D images and not relevant to DRM format modifiers. + */ +#define AMD_FMT_MOD_TILE_GFX6_1D_TILED_THIN1 0x2 +#define AMD_FMT_MOD_TILE_GFX6_2D_TILED_THIN1 0x4 + /* * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical * version. @@ -1774,6 +1807,146 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) #define AMD_FMT_MOD_PIPE_SHIFT 33 #define AMD_FMT_MOD_PIPE_MASK 0x7 +/* + * MICRO_TILE_MODE, 3 bits. Determines the micro tile format. + * Only relevant to Gfx6-8. + * + * DISPLAY - Displayable tiling + * THIN - Non-displayable tiling, a.k.a thin micro tiling + * DEPTH, THICK - not exposed, not relevant to DRM format modifier use cases + * ROTATED - not exposed, not implemented in Linux or Mesa + */ +#define AMD_FMT_MOD_MICROTILE_SHIFT 14ULL +#define AMD_FMT_MOD_MICROTILE_MASK 0x7 + +#define AMD_FMT_MOD_MICROTILE_DISPLAY 0x0 +#define AMD_FMT_MOD_MICROTILE_THIN 0x1 + +/* + * PIPE_CONFIG, 5 bits. Number of pipes and how pipes are interleaved on the surface, + * which means the shader engine tile size and packer tile size. + * Typically matches the number of memory channels, or number of RBs. + * Only relevant to Gfx6-8 macro tiled modes. + * + * P_x_x + * where: + * - number of pipes + * x - shader engine tile size + * x - packer tile size + */ +#define AMD_FMT_MOD_PIPE_CONFIG_SHIFT 17ULL +#define AMD_FMT_MOD_PIPE_CONFIG_MASK 0x1f + +#define AMD_FMT_MOD_PIPE_CONFIG_P2 0x0 +#define AMD_FMT_MOD_PIPE_CONFIG_P4_8x16 0x4 +#define AMD_FMT_MOD_PIPE_CONFIG_P4_16x16 0x5 +#define AMD_FMT_MOD_PIPE_CONFIG_P4_16x32 0x6 +#define AMD_FMT_MOD_PIPE_CONFIG_P4_32x32 0x7 +#define AMD_FMT_MOD_PIPE_CONFIG_P8_16x16_8x16 0x8 +#define AMD_FMT_MOD_PIPE_CONFIG_P8_16x32_8x16 0x9 +#define AMD_FMT_MOD_PIPE_CONFIG_P8_32x32_8x16 0xa +#define AMD_FMT_MOD_PIPE_CONFIG_P8_16x32_16x16 0xb +#define AMD_FMT_MOD_PIPE_CONFIG_P8_32x32_16x16 0xc +#define AMD_FMT_MOD_PIPE_CONFIG_P8_32x32_16x32 0xd +#define AMD_FMT_MOD_PIPE_CONFIG_P8_32x64_32x32 0xe +#define AMD_FMT_MOD_PIPE_CONFIG_P16_32x32_8x16 0x10 +#define AMD_FMT_MOD_PIPE_CONFIG_P16_32x32_16x16 0x11 + +/* + * TILE_SPLIT, 3 bits. + * Only relevant to Gfx6-8 macro tiled modes. + * + * On GFX6 (or with depth tiling modes on GFX7 and newer), + * the GFX block uses the GB_TILE_MODE.TILE_SPLIT field directly. + * + * On GFX7 and newer with non-depth tiling modes, the GFX block uses a + * split factor which is stored in the GB_TILE_MODE.SAMPLE_SPLIT field. + * SAMPLE_SPLIT may be: 0 - 1 byte; 1 - 2 bytes; 2 - 4 bytes; 3 - 8 bytes. + * The actual tile size and tile split bytes are calculated as follows: + * + * bpp = ... <- bits per pixel in the current image + * thickness = ... <- depends on array mode; may be: 1, 4, 8 + * num_samples = ... <- number of samples in the current image + * tile_size_pixels = 8 * 8 + * tile_bytes_1x = thickness * tile_size_pixels * bpp / 8 + * sample_split_factor = 1 << SAMPLE_SPLIT + * tile_split_bytes = clamp(tile_bytes_1x * sample_split_factor, 256, dram_row_size_bytes) + * tile_bytes = clamp(tile_bytes_1x * num_samples, 64, tile_split_bytes) + * + * In both cases, the display block (DCE) has no SAMPLE_SPLIT + * and just needs the tile split bytes in the GRPH_CONTROL.GRPH_TILE_SPLIT field. + * To maximize compatibility between GFX6-7, we don't include the SAMPLE_SPLIT + * in the format modifiers. + * + * The actual tile split in bytes is: 64 << field value + * Possible values of this field: + * + * 0 - Tile split is 64 bytes + * 1 - Tile split is 128 bytes + * 2 - Tile split is 256 bytes + * 3 - Tile split is 512 bytes + * 4 - Tile split is 1 KiB + * 5 - Tile split is 2 KiB + * 6 - Tile split is 4 KiB + */ +#define AMD_FMT_MOD_TILE_SPLIT_SHIFT 22ULL +#define AMD_FMT_MOD_TILE_SPLIT_MASK 0x7 + +/* + * BANK_WIDTH, 2 bits. Number of tiles in the X direction in the same bank. + * Only relevant to Gfx6-8 macro tiled modes. + * The actual bank width is: 1 << field value + * Possible values: + * + * 0 - bank width is 1 + * 1 - bank width is 2 + * 2 - bank width is 4 + * 3 - bank width is 8 + */ +#define AMD_FMT_MOD_BANK_WIDTH_SHIFT 25ULL +#define AMD_FMT_MOD_BANK_WIDTH_MASK 0x3 + +/* + * BANK_HEIGHT, 2 bits. Number of tiles in the Y direction in the same bank. + * Only relevant to Gfx6-8 macro tiled modes. + * The actual bank height is: 1 << field value + * Possible values: + * + * 0 - bank height is 1 + * 1 - bank height is 2 + * 2 - bank height is 4 + * 3 - bank height is 8 + */ +#define AMD_FMT_MOD_BANK_HEIGHT_SHIFT 27ULL +#define AMD_FMT_MOD_BANK_HEIGHT_MASK 0x3 + +/* + * MACRO_TILE_ASPECT, 2 bits. Macro tile aspect ratio. + * Only relevant to Gfx6-8 macro tiled modes. + * Possible values: + * + * 0 - aspect ratio is 1:1 + * 1 - aspect ratio is 4:1 + * 2 - aspect ratio is 16:1 + * 3 - aspect ratio is 64:1 + */ +#define AMD_FMT_MOD_MACRO_TILE_ASPECT_SHIFT 29ULL +#define AMD_FMT_MOD_MACRO_TILE_ASPECT_MASK 0x3 + +/* + * NUM_BANKS, 2 bits. Number of banks. + * Only relevant to Gfx6-8 macro tiled modes. + * The actual number of banks is: 2 << field value + * Possible values: + * + * 0 - number of banks is 2 + * 1 - number of banks is 4 + * 2 - number of banks is 8 + * 3 - number of banks is 16 + */ +#define AMD_FMT_MOD_NUM_BANKS_SHIFT 31ULL +#define AMD_FMT_MOD_NUM_BANKS_MASK 0x3 + #define AMD_FMT_MOD_SET(field, value) \ ((__u64)(value) << AMD_FMT_MOD_##field##_SHIFT) #define AMD_FMT_MOD_GET(field, value) \ -- cgit From 5b1541c7b0dae224bec29c626ca31a0c31b57d6b Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 30 Jul 2026 12:47:47 -0700 Subject: drm/amdkfd: kfd_ioctl.h: fix most kernel-doc warnings Make corrections to kernel-doc comments: - use the struct keyword when describing structs - use the enum keyword when describing enums - insert colons (':') as needed in struct member descriptions - add missing short descriptions - convert some comments to kernel-doc format to prevent these warnings: Warning: include/uapi/linux/kfd_ioctl.h:708 cannot understand function prototype: 'struct kfd_ioctl_criu_args' Warning: include/uapi/linux/kfd_ioctl.h:771 cannot understand function prototype: 'enum kfd_ioctl_svm_op' Warning: include/uapi/linux/kfd_ioctl.h:805 cannot understand function prototype: 'enum kfd_ioctl_svm_attr_type' Warning: include/uapi/linux/kfd_ioctl.h:824 cannot understand function prototype: 'struct kfd_ioctl_svm_attribute' Warning: include/uapi/linux/kfd_ioctl.h:867 cannot understand function prototype: 'struct kfd_ioctl_svm_args' Warning: include/uapi/linux/kfd_ioctl.h:910 cannot understand function prototype: 'struct kfd_ioctl_set_xnack_mode_args' Warning: include/uapi/linux/kfd_ioctl.h:1075 cannot understand function prototype: 'struct kfd_ioctl_runtime_enable_args' Warning: include/uapi/linux/kfd_ioctl.h:1160 missing initial short description on line: * kfd_ioctl_dbg_trap_enable_args Warning: include/uapi/linux/kfd_ioctl.h:1182 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_enable_args' Warning: include/uapi/linux/kfd_ioctl.h:1190 missing initial short description on line: * kfd_ioctl_dbg_trap_send_runtime_event_args Warning: include/uapi/linux/kfd_ioctl.h:1208 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_send_runtime_event_args' Warning: include/uapi/linux/kfd_ioctl.h:1215 missing initial short description on line: * kfd_ioctl_dbg_trap_set_exceptions_enabled_args Warning: include/uapi/linux/kfd_ioctl.h:1225 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_set_exceptions_enabled_args' Warning: include/uapi/linux/kfd_ioctl.h:1230 missing initial short description on line: * kfd_ioctl_dbg_trap_set_wave_launch_override_args Warning: include/uapi/linux/kfd_ioctl.h:1252 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_set_wave_launch_override_args' Warning: include/uapi/linux/kfd_ioctl.h:1260 missing initial short description on line: * kfd_ioctl_dbg_trap_set_wave_launch_mode_args Warning: include/uapi/linux/kfd_ioctl.h:1270 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_set_wave_launch_mode_args' Warning: include/uapi/linux/kfd_ioctl.h:1276 missing initial short description on line: * kfd_ioctl_dbg_trap_suspend_queues_ags Warning: include/uapi/linux/kfd_ioctl.h:1305 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_suspend_queues_args' Warning: include/uapi/linux/kfd_ioctl.h:1313 missing initial short description on line: * kfd_ioctl_dbg_trap_resume_queues_args Warning: include/uapi/linux/kfd_ioctl.h:1330 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_resume_queues_args' Warning: include/uapi/linux/kfd_ioctl.h:1337 missing initial short description on line: * kfd_ioctl_dbg_trap_set_node_address_watch_args Warning: include/uapi/linux/kfd_ioctl.h:1354 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_set_node_address_watch_args' Warning: include/uapi/linux/kfd_ioctl.h:1363 missing initial short description on line: * kfd_ioctl_dbg_trap_clear_node_address_watch_args Warning: include/uapi/linux/kfd_ioctl.h:1376 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_clear_node_address_watch_args' Warning: include/uapi/linux/kfd_ioctl.h:1382 missing initial short description on line: * kfd_ioctl_dbg_trap_set_flags_args Warning: include/uapi/linux/kfd_ioctl.h:1393 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_set_flags_args' Warning: include/uapi/linux/kfd_ioctl.h:1399 missing initial short description on line: * kfd_ioctl_dbg_trap_query_debug_event_args Warning: include/uapi/linux/kfd_ioctl.h:1421 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_query_debug_event_args' Warning: include/uapi/linux/kfd_ioctl.h:1428 missing initial short description on line: * kfd_ioctl_dbg_trap_query_exception_info_args Warning: include/uapi/linux/kfd_ioctl.h:1448 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_query_exception_info_args' Warning: include/uapi/linux/kfd_ioctl.h:1457 missing initial short description on line: * kfd_ioctl_dbg_trap_get_queue_snapshot_args Warning: include/uapi/linux/kfd_ioctl.h:1485 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_queue_snapshot_args' Warning: include/uapi/linux/kfd_ioctl.h:1493 missing initial short description on line: * kfd_ioctl_dbg_trap_get_device_snapshot_args Warning: include/uapi/linux/kfd_ioctl.h:1521 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_device_snapshot_args' Warning: include/uapi/linux/kfd_ioctl.h:1529 missing initial short description on line: * kfd_ioctl_dbg_trap_args Warning: include/uapi/linux/kfd_ioctl.h:1539 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1569 This comment starts with '/**', but isn't a kernel-doc comment. * Enables/Disables GPU Specific profiler settings Warning: include/uapi/linux/kfd_ioctl.h:718 struct member 'num_bos' not described in 'kfd_ioctl_criu_args' Warning: include/uapi/linux/kfd_ioctl.h:718 struct member 'op' not described in 'kfd_ioctl_criu_args' Warning: include/uapi/linux/kfd_ioctl.h:874 struct member 'start_addr' not described in 'kfd_ioctl_svm_args' Warning: include/uapi/linux/kfd_ioctl.h:874 struct member 'size' not described in 'kfd_ioctl_svm_args' Warning: include/uapi/linux/kfd_ioctl.h:874 struct member 'op' not described in 'kfd_ioctl_svm_args' Warning: include/uapi/linux/kfd_ioctl.h:874 struct member 'nattr' not described in 'kfd_ioctl_svm_args' Warning: include/uapi/linux/kfd_ioctl.h:874 struct member 'attrs' not described in 'kfd_ioctl_svm_args' Warning: include/uapi/linux/kfd_ioctl.h:1079 struct member 'r_debug' not described in 'kfd_ioctl_runtime_enable_args' Warning: include/uapi/linux/kfd_ioctl.h:1079 struct member 'mode_mask' not described in 'kfd_ioctl_runtime_enable_args' Warning: include/uapi/linux/kfd_ioctl.h:1079 struct member 'capabilities_mask' not described in 'kfd_ioctl_runtime_enable_args' Warning: include/uapi/linux/kfd_ioctl.h:1254 struct member 'pad' not described in 'kfd_ioctl_dbg_trap_set_wave_launch_override_args' Warning: include/uapi/linux/kfd_ioctl.h:1267 cannot understand function prototype: 'struct kfd_ioctl_dbg_trap_set_wave_launch_mode_args' Warning: include/uapi/linux/kfd_ioctl.h:1308 expecting prototype for struct kfd_ioctl_dbg_trap_suspend_queues_ags. Prototype was for struct kfd_ioctl_dbg_trap_suspend_queues_args instead Warning: include/uapi/linux/kfd_ioctl.h:1332 struct member 'pad' not described in 'kfd_ioctl_dbg_trap_resume_queues_args' Warning: include/uapi/linux/kfd_ioctl.h:1488 expecting prototype for struct kfd_ioctl_dbg_trap_get_queue_snapshot_args. Prototype was for struct kfd_ioctl_dbg_trap_queue_snapshot_args instead Warning: include/uapi/linux/kfd_ioctl.h:1524 expecting prototype for struct kfd_ioctl_dbg_trap_get_device_snapshot_args. Prototype was for struct kfd_ioctl_dbg_trap_device_snapshot_args instead * This leaves the following struct members undescribed in kernel-doc comments: Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'enable' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'send_runtime_event' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'set_exceptions_enabled' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'launch_override' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'launch_mode' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'suspend_queues' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'resume_queues' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'set_node_address_watch' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'clear_node_address_watch' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'set_flags' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'query_debug_event' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'query_exception_info' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'queue_snapshot' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1555 struct member 'device_snapshot' not described in 'kfd_ioctl_dbg_trap_args' Warning: include/uapi/linux/kfd_ioctl.h:1571 struct member 'gpu_id' not described in 'kfd_ioctl_pmc_settings' Warning: include/uapi/linux/kfd_ioctl.h:1571 struct member 'lock' not described in 'kfd_ioctl_pmc_settings' Warning: include/uapi/linux/kfd_ioctl.h:1571 struct member 'perfcount_enable' not described in 'kfd_ioctl_pmc_settings' All amdgpu object files before/after compare equal after this change. Signed-off-by: Randy Dunlap Signed-off-by: Alex Deucher --- include/uapi/linux/kfd_ioctl.h | 180 ++++++++++++++++++++--------------------- 1 file changed, 89 insertions(+), 91 deletions(-) (limited to 'include/uapi') diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h index 9584b5aab727..749d196e2114 100644 --- a/include/uapi/linux/kfd_ioctl.h +++ b/include/uapi/linux/kfd_ioctl.h @@ -690,7 +690,7 @@ enum kfd_criu_op { }; /** - * kfd_ioctl_criu_args - Arguments perform CRIU operation + * struct kfd_ioctl_criu_args - Arguments perform CRIU operation * @devices: [in/out] User pointer to memory location for devices information. * This is an array of type kfd_criu_device_bucket. * @bos: [in/out] User pointer to memory location for BOs information @@ -698,11 +698,11 @@ enum kfd_criu_op { * @priv_data: [in/out] User pointer to memory location for private data * @priv_data_size: [in/out] Size of priv_data in bytes * @num_devices: [in/out] Number of GPUs used by process. Size of @devices array. - * @num_bos [in/out] Number of BOs used by process. Size of @bos array. + * @num_bos: [in/out] Number of BOs used by process. Size of @bos array. * @num_objects: [in/out] Number of objects used by process. Objects are opaque to * user application. * @pid: [in/out] PID of the process being checkpointed - * @op [in] Type of operation (kfd_criu_op) + * @op: [in] Type of operation (kfd_criu_op) * * Return: 0 on success, -errno on failure */ @@ -764,7 +764,7 @@ enum kfd_mmio_remap { #define KFD_IOCTL_SVM_FLAG_EXT_COHERENT 0x00000080 /** - * kfd_ioctl_svm_op - SVM ioctl operations + * enum kfd_ioctl_svm_op - SVM ioctl operations * * @KFD_IOCTL_SVM_OP_SET_ATTR: Modify one or more attributes * @KFD_IOCTL_SVM_OP_GET_ATTR: Query one or more attributes @@ -786,7 +786,7 @@ enum kfd_ioctl_svm_location { }; /** - * kfd_ioctl_svm_attr_type - SVM attribute types + * enum kfd_ioctl_svm_attr_type - SVM attribute types * * @KFD_IOCTL_SVM_ATTR_PREFERRED_LOC: gpuid of the preferred location, 0 for * system memory @@ -815,7 +815,7 @@ enum kfd_ioctl_svm_attr_type { }; /** - * kfd_ioctl_svm_attribute - Attributes as pairs of type and value + * struct kfd_ioctl_svm_attribute - Attributes as pairs of type and value * * The meaning of the @value depends on the attribute type. * @@ -828,7 +828,7 @@ struct kfd_ioctl_svm_attribute { }; /** - * kfd_ioctl_svm_args - Arguments for SVM ioctl + * struct kfd_ioctl_svm_args - Arguments for SVM ioctl * * @op specifies the operation to perform (see enum * @kfd_ioctl_svm_op). @start_addr and @size are common for all @@ -875,7 +875,7 @@ struct kfd_ioctl_svm_args { }; /** - * kfd_ioctl_set_xnack_mode_args - Arguments for set_xnack_mode + * struct kfd_ioctl_set_xnack_mode_args - Arguments for set_xnack_mode * * @xnack_enabled: [in/out] Whether to enable XNACK mode for this process * @@ -1055,15 +1055,15 @@ struct kfd_runtime_info { #define KFD_RUNTIME_ENABLE_MODE_TTMP_SAVE_MASK 2 /** - * kfd_ioctl_runtime_enable_args - Arguments for runtime enable + * struct kfd_ioctl_runtime_enable_args - Arguments for runtime enable * * Coordinates debug exception signalling and debug device enablement with runtime. * - * @r_debug - pointer to user struct for sharing information between ROCr and the debuggger - * @mode_mask - mask to set mode + * @r_debug: pointer to user struct for sharing information between ROCr and the debuggger + * @mode_mask: mask to set mode * KFD_RUNTIME_ENABLE_MODE_ENABLE_MASK - enable runtime for debugging, otherwise disable * KFD_RUNTIME_ENABLE_MODE_TTMP_SAVE_MASK - enable trap temporary setup (ignore on disable) - * @capabilities_mask - mask to notify runtime on what KFD supports + * @capabilities_mask: mask to notify runtime on what KFD supports * * Return - 0 on SUCCESS. * - EBUSY if runtime enable call already pending. @@ -1158,17 +1158,15 @@ enum kfd_dbg_trap_operations { }; /** - * kfd_ioctl_dbg_trap_enable_args - * - * Arguments for KFD_IOC_DBG_TRAP_ENABLE. + * struct kfd_ioctl_dbg_trap_enable_args - Arguments for KFD_IOC_DBG_TRAP_ENABLE. * * Enables debug session for target process. Call @op KFD_IOC_DBG_TRAP_DISABLE in * kfd_ioctl_dbg_trap_args to disable debug session. * - * @exception_mask (IN) - exceptions to raise to the debugger - * @rinfo_ptr (IN) - pointer to runtime info buffer (see kfd_runtime_info) - * @rinfo_size (IN/OUT) - size of runtime info buffer in bytes - * @dbg_fd (IN) - fd the KFD will nofify the debugger with of raised + * @exception_mask: (IN) - exceptions to raise to the debugger + * @rinfo_ptr: (IN) - pointer to runtime info buffer (see kfd_runtime_info) + * @rinfo_size: (IN/OUT) - size of runtime info buffer in bytes + * @dbg_fd: (IN) - fd the KFD will nofify the debugger with of raised * exceptions set in exception_mask. * * Generic errors apply (see kfd_dbg_trap_operations). @@ -1188,15 +1186,14 @@ struct kfd_ioctl_dbg_trap_enable_args { }; /** - * kfd_ioctl_dbg_trap_send_runtime_event_args - * + * struct kfd_ioctl_dbg_trap_send_runtime_event_args - Arguments for + * KFD_IOC_DBG_TRAP_SEND_RUNTIME_EVENT. * - * Arguments for KFD_IOC_DBG_TRAP_SEND_RUNTIME_EVENT. * Raises exceptions to runtime. * - * @exception_mask (IN) - exceptions to raise to runtime - * @gpu_id (IN) - target device id - * @queue_id (IN) - target queue id + * @exception_mask: (IN) - exceptions to raise to runtime + * @gpu_id: (IN) - target device id + * @queue_id: (IN) - target queue id * * Generic errors apply (see kfd_dbg_trap_operations). * Return - 0 on SUCCESS. @@ -1213,12 +1210,12 @@ struct kfd_ioctl_dbg_trap_send_runtime_event_args { }; /** - * kfd_ioctl_dbg_trap_set_exceptions_enabled_args + * struct kfd_ioctl_dbg_trap_set_exceptions_enabled_args - Arguments for + * KFD_IOC_SET_EXCEPTIONS_ENABLED * - * Arguments for KFD_IOC_SET_EXCEPTIONS_ENABLED * Set new exceptions to be raised to the debugger. * - * @exception_mask (IN) - new exceptions to raise the debugger + * @exception_mask: (IN) - new exceptions to raise the debugger * * Generic errors apply (see kfd_dbg_trap_operations). * Return - 0 on SUCCESS. @@ -1228,16 +1225,16 @@ struct kfd_ioctl_dbg_trap_set_exceptions_enabled_args { }; /** - * kfd_ioctl_dbg_trap_set_wave_launch_override_args + * struct kfd_ioctl_dbg_trap_set_wave_launch_override_args - Arguments for + * KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE * - * Arguments for KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_OVERRIDE * Enable HW exceptions to raise trap. * - * @override_mode (IN) - see kfd_dbg_trap_override_mode - * @enable_mask (IN/OUT) - reference kfd_dbg_trap_mask. + * @override_mode: (IN) - see kfd_dbg_trap_override_mode + * @enable_mask: (IN/OUT) - reference kfd_dbg_trap_mask. * IN is the override modes requested to be enabled. * OUT is referenced in Return below. - * @support_request_mask (IN/OUT) - reference kfd_dbg_trap_mask. + * @support_request_mask: (IN/OUT) - reference kfd_dbg_trap_mask. * IN is the override modes requested for support check. * OUT is referenced in Return below. * @@ -1254,36 +1251,38 @@ struct kfd_ioctl_dbg_trap_set_wave_launch_override_args { __u32 override_mode; __u32 enable_mask; __u32 support_request_mask; + /* private: */ __u32 pad; }; /** - * kfd_ioctl_dbg_trap_set_wave_launch_mode_args + * struct kfd_ioctl_dbg_trap_set_wave_launch_mode_args - Arguments for + * KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE * - * Arguments for KFD_IOC_DBG_TRAP_SET_WAVE_LAUNCH_MODE * Set wave launch mode. * - * @mode (IN) - see kfd_dbg_trap_wave_launch_mode + * @launch_mode: (IN) - see kfd_dbg_trap_wave_launch_mode * * Generic errors apply (see kfd_dbg_trap_operations). * Return - 0 on SUCCESS. */ struct kfd_ioctl_dbg_trap_set_wave_launch_mode_args { __u32 launch_mode; + /* private: */ __u32 pad; }; /** - * kfd_ioctl_dbg_trap_suspend_queues_ags + * struct kfd_ioctl_dbg_trap_suspend_queues_args - Arguments for + * KFD_IOC_DBG_TRAP_SUSPEND_QUEUES * - * Arguments for KFD_IOC_DBG_TRAP_SUSPEND_QUEUES * Suspend queues. * - * @exception_mask (IN) - raised exceptions to clear - * @queue_array_ptr (IN) - pointer to array of queue ids (u32 per queue id) + * @exception_mask: (IN) - raised exceptions to clear + * @queue_array_ptr: (IN) - pointer to array of queue ids (u32 per queue id) * to suspend - * @num_queues (IN) - number of queues to suspend in @queue_array_ptr - * @grace_period (IN) - wave time allowance before preemption + * @num_queues: (IN) - number of queues to suspend in @queue_array_ptr + * @grace_period: (IN) - wave time allowance before preemption * per 1K GPU clock cycle unit * * Generic errors apply (see kfd_dbg_trap_operations). @@ -1311,14 +1310,14 @@ struct kfd_ioctl_dbg_trap_suspend_queues_args { }; /** - * kfd_ioctl_dbg_trap_resume_queues_args + * struct kfd_ioctl_dbg_trap_resume_queues_args - Arguments for + * KFD_IOC_DBG_TRAP_RESUME_QUEUES * - * Arguments for KFD_IOC_DBG_TRAP_RESUME_QUEUES * Resume queues. * - * @queue_array_ptr (IN) - pointer to array of queue ids (u32 per queue id) + * @queue_array_ptr: (IN) - pointer to array of queue ids (u32 per queue id) * to resume - * @num_queues (IN) - number of queues to resume in @queue_array_ptr + * @num_queues: (IN) - number of queues to resume in @queue_array_ptr * * Generic errors apply (see kfd_dbg_trap_operations). * Return - Number of queues resumed on SUCCESS. @@ -1331,20 +1330,21 @@ struct kfd_ioctl_dbg_trap_suspend_queues_args { struct kfd_ioctl_dbg_trap_resume_queues_args { __u64 queue_array_ptr; __u32 num_queues; + /* private: */ __u32 pad; }; /** - * kfd_ioctl_dbg_trap_set_node_address_watch_args + * struct kfd_ioctl_dbg_trap_set_node_address_watch_args - Arguments for + * KFD_IOC_DBG_TRAP_SET_NODE_ADDRESS_WATCH * - * Arguments for KFD_IOC_DBG_TRAP_SET_NODE_ADDRESS_WATCH * Sets address watch for device. * - * @address (IN) - watch address to set - * @mode (IN) - see kfd_dbg_trap_address_watch_mode - * @mask (IN) - watch address mask - * @gpu_id (IN) - target gpu to set watch point - * @id (OUT) - watch id allocated + * @address: (IN) - watch address to set + * @mode: (IN) - see kfd_dbg_trap_address_watch_mode + * @mask: (IN) - watch address mask + * @gpu_id: (IN) - target gpu to set watch point + * @id: (OUT) - watch id allocated * * Generic errors apply (see kfd_dbg_trap_operations). * Return - 0 on SUCCESS. @@ -1361,13 +1361,13 @@ struct kfd_ioctl_dbg_trap_set_node_address_watch_args { }; /** - * kfd_ioctl_dbg_trap_clear_node_address_watch_args + * struct kfd_ioctl_dbg_trap_clear_node_address_watch_args - Arguments for + * KFD_IOC_DBG_TRAP_CLEAR_NODE_ADDRESS_WATCH * - * Arguments for KFD_IOC_DBG_TRAP_CLEAR_NODE_ADDRESS_WATCH * Clear address watch for device. * - * @gpu_id (IN) - target device to clear watch point - * @id (IN) - allocated watch id to clear + * @gpu_id: (IN) - target device to clear watch point + * @id: (IN) - allocated watch id to clear * * Generic errors apply (see kfd_dbg_trap_operations). * Return - 0 on SUCCESS. @@ -1380,12 +1380,12 @@ struct kfd_ioctl_dbg_trap_clear_node_address_watch_args { }; /** - * kfd_ioctl_dbg_trap_set_flags_args + * struct kfd_ioctl_dbg_trap_set_flags_args - Arguments for + * KFD_IOC_DBG_TRAP_SET_FLAGS * - * Arguments for KFD_IOC_DBG_TRAP_SET_FLAGS * Sets flags for wave behaviour. * - * @flags (IN/OUT) - IN = flags to enable, OUT = flags previously enabled + * @flags: (IN/OUT) - IN = flags to enable, OUT = flags previously enabled * * Generic errors apply (see kfd_dbg_trap_operations). * Return - 0 on SUCCESS. @@ -1393,13 +1393,13 @@ struct kfd_ioctl_dbg_trap_clear_node_address_watch_args { */ struct kfd_ioctl_dbg_trap_set_flags_args { __u32 flags; + /* private: */ __u32 pad; }; /** - * kfd_ioctl_dbg_trap_query_debug_event_args - * - * Arguments for KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT + * struct kfd_ioctl_dbg_trap_query_debug_event_args - Arguments for + * KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT * * Find one or more raised exceptions. This function can return multiple * exceptions from a single queue or a single device with one call. To find @@ -1409,9 +1409,9 @@ struct kfd_ioctl_dbg_trap_set_flags_args { * However, clearing an exception prevents retrieving further information * about it with KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO. * - * @exception_mask (IN/OUT) - exception to clear (IN) and raised (OUT) - * @gpu_id (OUT) - gpu id of exceptions raised - * @queue_id (OUT) - queue id of exceptions raised + * @exception_mask: (IN/OUT) - exception to clear (IN) and raised (OUT) + * @gpu_id: (OUT) - gpu id of exceptions raised + * @queue_id: (OUT) - queue id of exceptions raised * * Generic errors apply (see kfd_dbg_trap_operations). * Return - 0 on raised exception found @@ -1426,16 +1426,16 @@ struct kfd_ioctl_dbg_trap_query_debug_event_args { }; /** - * kfd_ioctl_dbg_trap_query_exception_info_args + * struct kfd_ioctl_dbg_trap_query_exception_info_args - Arguments for + * KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO * - * Arguments KFD_IOC_DBG_TRAP_QUERY_EXCEPTION_INFO * Get additional info on raised exception. * - * @info_ptr (IN) - pointer to exception info buffer to copy to - * @info_size (IN/OUT) - exception info buffer size (bytes) - * @source_id (IN) - target gpu or queue id - * @exception_code (IN) - target exception - * @clear_exception (IN) - clear raised @exception_code exception + * @info_ptr: (IN) - pointer to exception info buffer to copy to + * @info_size: (IN/OUT) - exception info buffer size (bytes) + * @source_id: (IN) - target gpu or queue id + * @exception_code: (IN) - target exception + * @clear_exception: (IN) - clear raised @exception_code exception * (0 = false, 1 = true) * * Generic errors apply (see kfd_dbg_trap_operations). @@ -1455,20 +1455,20 @@ struct kfd_ioctl_dbg_trap_query_exception_info_args { }; /** - * kfd_ioctl_dbg_trap_get_queue_snapshot_args + * struct kfd_ioctl_dbg_trap_queue_snapshot_args - Arguments for + * KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT * - * Arguments KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT * Get queue information. * - * @exception_mask (IN) - exceptions raised to clear - * @snapshot_buf_ptr (IN) - queue snapshot entry buffer (see kfd_queue_snapshot_entry) - * @num_queues (IN/OUT) - number of queue snapshot entries + * @exception_mask: (IN) - exceptions raised to clear + * @snapshot_buf_ptr: (IN) - queue snapshot entry buffer (see kfd_queue_snapshot_entry) + * @num_queues: (IN/OUT) - number of queue snapshot entries * The debugger specifies the size of the array allocated in @num_queues. * KFD returns the number of queues that actually existed. If this is * larger than the size specified by the debugger, KFD will not overflow * the array allocated by the debugger. * - * @entry_size (IN/OUT) - size per entry in bytes + * @entry_size: (IN/OUT) - size per entry in bytes * The debugger specifies sizeof(struct kfd_queue_snapshot_entry) in * @entry_size. KFD returns the number of bytes actually populated per * entry. The debugger should use the KFD_IOCTL_MINOR_VERSION to determine, @@ -1491,20 +1491,20 @@ struct kfd_ioctl_dbg_trap_queue_snapshot_args { }; /** - * kfd_ioctl_dbg_trap_get_device_snapshot_args + * struct kfd_ioctl_dbg_trap_device_snapshot_args - Arguments for + * KFD_IOC_DBG_TRAP_GET_DEVICE_SNAPSHOT * - * Arguments for KFD_IOC_DBG_TRAP_GET_DEVICE_SNAPSHOT * Get device information. * - * @exception_mask (IN) - exceptions raised to clear - * @snapshot_buf_ptr (IN) - pointer to snapshot buffer (see kfd_dbg_device_info_entry) - * @num_devices (IN/OUT) - number of debug devices to snapshot + * @exception_mask: (IN) - exceptions raised to clear + * @snapshot_buf_ptr: (IN) - pointer to snapshot buffer (see kfd_dbg_device_info_entry) + * @num_devices: (IN/OUT) - number of debug devices to snapshot * The debugger specifies the size of the array allocated in @num_devices. * KFD returns the number of devices that actually existed. If this is * larger than the size specified by the debugger, KFD will not overflow * the array allocated by the debugger. * - * @entry_size (IN/OUT) - size per entry in bytes + * @entry_size: (IN/OUT) - size per entry in bytes * The debugger specifies sizeof(struct kfd_dbg_device_info_entry) in * @entry_size. KFD returns the number of bytes actually populated. The * debugger should use KFD_IOCTL_MINOR_VERSION to determine, which fields @@ -1527,12 +1527,10 @@ struct kfd_ioctl_dbg_trap_device_snapshot_args { }; /** - * kfd_ioctl_dbg_trap_args - * - * Arguments to debug target process. + * struct kfd_ioctl_dbg_trap_args - Arguments to debug target process. * - * @pid - target process to debug - * @op - debug operation (see kfd_dbg_trap_operations) + * @pid: target process to debug + * @op: debug operation (see kfd_dbg_trap_operations) * * @op determines which union struct args to use. * Refer to kern docs for each kfd_ioctl_dbg_trap_*_args struct. @@ -1567,7 +1565,7 @@ enum kfd_profiler_ops { }; /** - * Enables/Disables GPU Specific profiler settings + * struct kfd_ioctl_pmc_settings - Enables/Disables GPU Specific profiler settings */ struct kfd_ioctl_pmc_settings { __u32 gpu_id; /* This is the user_gpu_id */ -- cgit