[PATCH v2 RESEND 2/5] drm: panthor: add devcoredump support

Adrian Larumbe adrian.larumbe at collabora.com
Thu Aug 22 12:27:31 UTC 2024


> On 21.08.2024 11:37, Daniel Almeida wrote:
> Dump the GPU state using devcoredump. This is useful for debugging
> purposes.
> 
> Signed-off-by: Daniel Almeida <daniel.almeida at collabora.com>

Reviewed-by: Adrian Larumbe <adrian.larumbe at collabora.com>

> ---
>  drivers/gpu/drm/panthor/Kconfig         |   1 +
>  drivers/gpu/drm/panthor/Makefile        |   1 +
>  drivers/gpu/drm/panthor/panthor_dump.c  | 376 ++++++++++++++++++++++++
>  drivers/gpu/drm/panthor/panthor_dump.h  |  21 ++
>  drivers/gpu/drm/panthor/panthor_mmu.c   |  22 ++
>  drivers/gpu/drm/panthor/panthor_mmu.h   |   6 +
>  drivers/gpu/drm/panthor/panthor_sched.c |  51 +++-
>  drivers/gpu/drm/panthor/panthor_sched.h |  10 +
>  include/uapi/drm/panthor_drm.h          | 124 ++++++++
>  9 files changed, 611 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/panthor/panthor_dump.c
>  create mode 100644 drivers/gpu/drm/panthor/panthor_dump.h
> 
> diff --git a/drivers/gpu/drm/panthor/Kconfig b/drivers/gpu/drm/panthor/Kconfig
> index 55b40ad07f3b..eeb80d8e8064 100644
> --- a/drivers/gpu/drm/panthor/Kconfig
> +++ b/drivers/gpu/drm/panthor/Kconfig
> @@ -14,6 +14,7 @@ config DRM_PANTHOR
>  	select IOMMU_IO_PGTABLE_LPAE
>  	select IOMMU_SUPPORT
>  	select PM_DEVFREQ
> +	select WANT_DEVCOREDUMP
>  	help
>  	  DRM driver for ARM Mali CSF-based GPUs.
>  
> diff --git a/drivers/gpu/drm/panthor/Makefile b/drivers/gpu/drm/panthor/Makefile
> index 15294719b09c..19be24ddf577 100644
> --- a/drivers/gpu/drm/panthor/Makefile
> +++ b/drivers/gpu/drm/panthor/Makefile
> @@ -4,6 +4,7 @@ panthor-y := \
>  	panthor_devfreq.o \
>  	panthor_device.o \
>  	panthor_drv.o \
> +	panthor_dump.o \
>  	panthor_fw.o \
>  	panthor_gem.o \
>  	panthor_gpu.o \
> diff --git a/drivers/gpu/drm/panthor/panthor_dump.c b/drivers/gpu/drm/panthor/panthor_dump.c
> new file mode 100644
> index 000000000000..7ec0e21dc7e9
> --- /dev/null
> +++ b/drivers/gpu/drm/panthor/panthor_dump.c
> @@ -0,0 +1,376 @@
> +// SPDX-License-Identifier: GPL-2.0 or MIT
> +/* SPDX-FileCopyrightText: Copyright Collabora 2024 */
> +
> +#include <drm/drm_gem.h>
> +#include <linux/iosys-map.h>
> +#include <linux/devcoredump.h>
> +#include <linux/err.h>
> +#include <linux/vmalloc.h>
> +#include <linux/types.h>
> +#include <uapi/drm/panthor_drm.h>
> +
> +#include "panthor_device.h"
> +#include "panthor_dump.h"
> +#include "panthor_mmu.h"
> +#include "panthor_sched.h"
> +
> +/* A magic value used when starting a new section in the dump */
> +#define PANT_DUMP_MAGIC 0x544e4150 /* PANT */
> +#define PANT_DUMP_MAJOR 1
> +#define PANT_DUMP_MINOR 0
> +
> +/* keep track of where we are in the underlying buffer */
> +struct dump_allocator {
> +	u8 *start;
> +	u8 *curr;
> +	size_t pos;
> +	size_t capacity;
> +};
> +
> +struct vm_dump_count {
> +	u64 size;
> +	u32 vas;
> +};
> +
> +struct queue_count {
> +	u32 queues;
> +};
> +
> +struct dump_group_args {
> +	struct panthor_device *ptdev;
> +	struct dump_allocator *alloc;
> +	struct panthor_group *group;
> +};
> +
> +struct dump_va_args {
> +	struct panthor_device *ptdev;
> +	struct dump_allocator *alloc;
> +};
> +
> +static void *alloc_bytes(struct dump_allocator *alloc, size_t size)
> +{
> +	void *ret;
> +
> +	if (alloc->pos + size > alloc->capacity)
> +		return ERR_PTR(-ENOMEM);
> +
> +	ret = alloc->curr;
> +	alloc->curr += size;
> +	alloc->pos += size;
> +	return ret;
> +}
> +
> +static struct drm_panthor_dump_header *
> +alloc_header(struct dump_allocator *alloc, u32 type, size_t size)
> +{
> +	struct drm_panthor_dump_header *hdr;
> +	int header_size = sizeof(*hdr);
> +
> +	hdr = alloc_bytes(alloc, header_size);
> +	if (IS_ERR(hdr))
> +		return hdr;
> +
> +	hdr->magic = PANT_DUMP_MAGIC;
> +	hdr->header_type = type;
> +	hdr->header_size = header_size;
> +	hdr->data_size = size;
> +	return hdr;
> +}
> +
> +static int dump_bo(struct panthor_device *ptdev, u8 *dst,
> +		   struct drm_gem_object *obj, int offset, int size)
> +{
> +	struct iosys_map map = {};
> +	int ret;
> +
> +	ret = drm_gem_vmap_unlocked(obj, &map);
> +	if (ret)
> +		return ret;
> +
> +	drm_dbg(&ptdev->base, "dumping bo %p, offset %d, size %d\n", obj,
> +		offset, size);
> +
> +	memcpy(dst, map.vaddr + offset, size);
> +	drm_gem_vunmap_unlocked(obj, &map);
> +	return ret;
> +}
> +
> +static int dump_va(struct dump_va_args *dump_va_args,
> +		   const struct drm_gpuva *va, int type)
> +{
> +	struct drm_gem_object *obj = va->gem.obj;
> +	const int hdr_size =
> +		sizeof(struct drm_panthor_dump_gpuva) + va->va.range;
> +	struct drm_panthor_dump_gpuva *dump_va;
> +	struct drm_panthor_dump_header *dump_hdr;
> +	u8 *bo_data;
> +
> +	dump_hdr = alloc_header(dump_va_args->alloc, type, hdr_size);
> +	if (IS_ERR(dump_hdr))
> +		return PTR_ERR(dump_hdr);
> +
> +	dump_va = alloc_bytes(dump_va_args->alloc, sizeof(*dump_va));
> +	if (IS_ERR(dump_va))
> +		return PTR_ERR(dump_va);
> +
> +	bo_data = alloc_bytes(dump_va_args->alloc, va->va.range);
> +	if (IS_ERR(bo_data))
> +		return PTR_ERR(bo_data);
> +
> +	dump_va->addr = va->va.addr;
> +	dump_va->range = va->va.range;
> +
> +	return dump_bo(dump_va_args->ptdev, bo_data, obj, va->gem.offset,
> +		       va->va.range);
> +}
> +
> +static int dump_va_cb(void *priv, const struct drm_gpuva *va)
> +{
> +	struct dump_va_args *dump_va_args = priv;
> +	int ret;
> +
> +	ret = dump_va(dump_va_args, va, DRM_PANTHOR_DUMP_HEADER_TYPE_VM);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int count_va_cb(void *priv, const struct drm_gpuva *va)
> +{
> +	struct vm_dump_count *count = priv;
> +
> +	count->vas++;
> +	count->size += va->va.range;
> +	return 0;
> +}
> +
> +static void count_queues(struct queue_count *count,
> +			 struct drm_panthor_dump_group_info *info)
> +{
> +	count->queues += info->queue_count;
> +}
> +
> +static int compute_dump_size(struct vm_dump_count *va_count,
> +			     struct queue_count *group_and_q_cnt)
> +{
> +	int size = 0;
> +	int i;
> +
> +	size += sizeof(struct drm_panthor_dump_header);
> +	size += sizeof(struct drm_panthor_dump_version);
> +
> +	size += sizeof(struct drm_panthor_dump_header);
> +	size += sizeof(struct drm_panthor_gpu_info);
> +
> +	size += sizeof(struct drm_panthor_dump_header);
> +	size += sizeof(struct drm_panthor_csif_info);
> +
> +	size += sizeof(struct drm_panthor_dump_header);
> +	size += sizeof(struct drm_panthor_fw_info);
> +
> +	for (i = 0; i < va_count->vas; i++) {
> +		size += sizeof(struct drm_panthor_dump_header);
> +		size += sizeof(struct drm_panthor_dump_gpuva);
> +	}
> +
> +	size += va_count->size;
> +
> +	size += sizeof(struct drm_panthor_dump_header);
> +	size += sizeof(struct drm_panthor_dump_group_info);
> +
> +	for (i = 0; i < group_and_q_cnt->queues; i++) {
> +		size += sizeof(struct drm_panthor_dump_header);
> +		size += sizeof(struct drm_panthor_dump_queue_info);
> +	}
> +
> +	return size;
> +}
> +
> +static int dump_queue_info(struct dump_group_args *dump_group_args,
> +			   struct drm_panthor_dump_queue_info *info)
> +{
> +	struct drm_panthor_dump_header *hdr;
> +	struct drm_panthor_dump_queue_info *queue_info;
> +
> +	drm_dbg(&dump_group_args->ptdev->base,
> +		"dumping queue info for cs_id %d, gpuva: %llx, insert: %llx, extract: %llx\n",
> +		info->cs_id, info->ringbuf_gpuva, info->ringbuf_insert,
> +		info->ringbuf_extract);
> +
> +	hdr = alloc_header(dump_group_args->alloc,
> +			   DRM_PANTHOR_DUMP_HEADER_TYPE_QUEUE_INFO,
> +			   sizeof(*info));
> +	if (IS_ERR(hdr))
> +		return PTR_ERR(hdr);
> +
> +	queue_info = alloc_bytes(dump_group_args->alloc, sizeof(*queue_info));
> +	if (IS_ERR(queue_info))
> +		return PTR_ERR(queue_info);
> +
> +	*queue_info = *info;
> +	return 0;
> +}
> +
> +static int dump_group_info(struct dump_group_args *dump_group_args,
> +			   struct drm_panthor_dump_group_info *info)
> +{
> +	struct drm_panthor_dump_header *hdr;
> +	struct drm_panthor_dump_group_info *group_info;
> +	int ret = 0;
> +
> +	drm_dbg(&dump_group_args->ptdev->base,
> +		"dumping group info for num_queues: %d, faulty bitmask: %d\n",
> +		info->queue_count, info->faulty_bitmask);
> +
> +	hdr = alloc_header(dump_group_args->alloc,
> +			   DRM_PANTHOR_DUMP_HEADER_TYPE_GROUP_INFO,
> +			   sizeof(*info));
> +	if (IS_ERR(hdr))
> +		return PTR_ERR(hdr);
> +
> +	group_info = alloc_bytes(dump_group_args->alloc, sizeof(*group_info));
> +	if (IS_ERR(group_info))
> +		return PTR_ERR(group_info);
> +
> +	*group_info = *info;
> +
> +	for (int i = 0; i < info->queue_count; i++) {
> +		struct drm_panthor_dump_queue_info qinfo;
> +
> +		ret = panthor_sched_get_queueinfo(dump_group_args->group, i,
> +						  &qinfo);
> +		if (ret)
> +			break;
> +		ret = dump_queue_info(dump_group_args, &qinfo);
> +		if (ret)
> +			break;
> +	}
> +
> +	return ret;
> +}
> +
> +int panthor_core_dump(struct panthor_core_dump_args *args)
> +{
> +	u8 *mem;
> +	int dump_size;
> +	int ret = 0;
> +	struct dump_allocator alloc = {};
> +	struct vm_dump_count va_count = {};
> +	struct drm_panthor_dump_header *hdr;
> +	struct drm_panthor_dump_version *version;
> +	struct drm_panthor_gpu_info *gpu_info;
> +	struct drm_panthor_csif_info *csif_info;
> +	struct drm_panthor_fw_info *fw_info;
> +	struct queue_count group_and_q_cnt = {};
> +	struct dump_va_args dump_va_args = {};
> +	struct drm_panthor_dump_group_info group_info;
> +	struct dump_group_args dump_group_args;
> +
> +	panthor_vm_foreach_va(args->group_vm, count_va_cb, &va_count);
> +
> +	panthor_sched_get_groupinfo(args->group, &group_info);
> +
> +	count_queues(&group_and_q_cnt, &group_info);
> +
> +	dump_size = compute_dump_size(&va_count, &group_and_q_cnt);
> +
> +	mem = vzalloc(dump_size);
> +	if (!mem)
> +		return ret;
> +
> +	alloc = (struct dump_allocator){
> +		.start = mem,
> +		.curr = mem,
> +		.pos = 0,
> +		.capacity = dump_size,
> +	};
> +
> +	hdr = alloc_header(&alloc, DRM_PANTHOR_DUMP_HEADER_TYPE_VERSION,
> +			   sizeof(struct drm_panthor_dump_version));
> +	if (IS_ERR(hdr)) {
> +		ret = PTR_ERR(hdr);
> +		goto free_valloc;
> +	}
> +
> +	version = alloc_bytes(&alloc, sizeof(*version));
> +	if (IS_ERR(version)) {
> +		ret = PTR_ERR(version);
> +		goto free_valloc;
> +	}
> +
> +	*version = (struct drm_panthor_dump_version){
> +		.major = PANT_DUMP_MAJOR,
> +		.minor = PANT_DUMP_MINOR,
> +	};
> +
> +	hdr = alloc_header(&alloc, DRM_PANTHOR_DUMP_HEADER_TYPE_GPU_INFO,
> +			   sizeof(args->ptdev->gpu_info));
> +	if (IS_ERR(hdr)) {
> +		ret = PTR_ERR(hdr);
> +		goto free_valloc;
> +	}
> +
> +	gpu_info = alloc_bytes(&alloc, sizeof(*gpu_info));
> +	if (IS_ERR(gpu_info)) {
> +		ret = PTR_ERR(gpu_info);
> +		goto free_valloc;
> +	}
> +
> +	*gpu_info = args->ptdev->gpu_info;
> +
> +	hdr = alloc_header(&alloc, DRM_PANTHOR_DUMP_HEADER_TYPE_CSIF_INFO,
> +			   sizeof(args->ptdev->csif_info));
> +	if (IS_ERR(hdr)) {
> +		ret = PTR_ERR(hdr);
> +		goto free_valloc;
> +	}
> +
> +	csif_info = alloc_bytes(&alloc, sizeof(*csif_info));
> +	if (IS_ERR(csif_info)) {
> +		ret = PTR_ERR(csif_info);
> +		goto free_valloc;
> +	}
> +
> +	*csif_info = args->ptdev->csif_info;
> +
> +	hdr = alloc_header(&alloc, DRM_PANTHOR_DUMP_HEADER_TYPE_FW_INFO,
> +			   sizeof(args->ptdev->fw_info));
> +	if (IS_ERR(hdr)) {
> +		ret = PTR_ERR(hdr);
> +		goto free_valloc;
> +	}
> +
> +	fw_info = alloc_bytes(&alloc, sizeof(*fw_info));
> +	if (IS_ERR(fw_info)) {
> +		ret = PTR_ERR(fw_info);
> +		goto free_valloc;
> +	}
> +
> +	*fw_info = args->ptdev->fw_info;
> +
> +	dump_va_args.ptdev = args->ptdev;
> +	dump_va_args.alloc = &alloc;
> +	ret = panthor_vm_foreach_va(args->group_vm, dump_va_cb, &dump_va_args);
> +	if (ret)
> +		goto free_valloc;
> +
> +	dump_group_args =
> +		(struct dump_group_args){ args->ptdev, &alloc, args->group };
> +	panthor_sched_get_groupinfo(args->group, &group_info);
> +	dump_group_info(&dump_group_args, &group_info);
> +
> +	if (alloc.pos < dump_size)
> +		drm_warn(&args->ptdev->base,
> +			 "dump size mismatch: expected %d, got %zu\n",
> +			 dump_size, alloc.pos);
> +
> +	dev_coredumpv(args->ptdev->base.dev, alloc.start, alloc.pos,
> +		      GFP_KERNEL);
> +
> +	return ret;
> +
> +free_valloc:
> +	vfree(mem);
> +	return ret;
> +}
> diff --git a/drivers/gpu/drm/panthor/panthor_dump.h b/drivers/gpu/drm/panthor/panthor_dump.h
> new file mode 100644
> index 000000000000..2a02943a2dbd
> --- /dev/null
> +++ b/drivers/gpu/drm/panthor/panthor_dump.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: GPL-2.0 or MIT */
> +/* SPDX-FileCopyrightText: Copyright Collabora 2024 */
> +
> +#ifndef __PANTHOR_DUMP_H__
> +#define __PANTHOR_DUMP_H__
> +
> +#include <drm/drm_gpuvm.h>
> +#include <drm/panthor_drm.h>
> +
> +#include "panthor_device.h"
> +#include "panthor_gem.h"
> +
> +struct panthor_core_dump_args {
> +	struct panthor_device *ptdev;
> +	struct panthor_vm *group_vm;
> +	struct panthor_group *group;
> +};
> +
> +int panthor_core_dump(struct panthor_core_dump_args *args);
> +
> +#endif /* __PANTHOR_DUMP_H__ */
> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
> index 412e95fcfb92..61d61157ace0 100644
> --- a/drivers/gpu/drm/panthor/panthor_mmu.c
> +++ b/drivers/gpu/drm/panthor/panthor_mmu.c
> @@ -2632,6 +2632,28 @@ int panthor_vm_prepare_mapped_bos_resvs(struct drm_exec *exec, struct panthor_vm
>  	return drm_gpuvm_prepare_objects(&vm->base, exec, slot_count);
>  }
>  
> +/**
> + * panthor_vm_foreachva() - Execute a callback for each VA in a VM
> + *
> + */
> +int panthor_vm_foreach_va(struct panthor_vm *vm,
> +			  int (*cb)(void *priv, const struct drm_gpuva *va),
> +			  void *priv)
> +{
> +	struct drm_gpuva *va;
> +	int ret = 0;
> +
> +	mutex_lock(&vm->op_lock);
> +	drm_gpuvm_for_each_va(va, &vm->base) {
> +		ret = cb(priv, va);
> +		if (ret)
> +			break;
> +	}
> +	mutex_unlock(&vm->op_lock);
> +
> +	return ret;
> +}
> +
>  /**
>   * panthor_mmu_unplug() - Unplug the MMU logic
>   * @ptdev: Device.
> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.h b/drivers/gpu/drm/panthor/panthor_mmu.h
> index 6788771071e3..05a5d68b23ae 100644
> --- a/drivers/gpu/drm/panthor/panthor_mmu.h
> +++ b/drivers/gpu/drm/panthor/panthor_mmu.h
> @@ -8,6 +8,7 @@
>  #include <linux/dma-resv.h>
>  
>  struct drm_exec;
> +struct drm_gpuva;
>  struct drm_sched_job;
>  struct panthor_gem_object;
>  struct panthor_heap_pool;
> @@ -52,6 +53,11 @@ void panthor_vm_add_job_fence_to_bos_resvs(struct panthor_vm *vm,
>  					   struct drm_sched_job *job);
>  
>  struct dma_resv *panthor_vm_resv(struct panthor_vm *vm);
> +
> +int panthor_vm_foreach_va(struct panthor_vm *vm,
> +			  int (*cb)(void *priv, const struct drm_gpuva *va),
> +			  void *priv);
> +
>  struct drm_gem_object *panthor_vm_root_gem(struct panthor_vm *vm);
>  
>  void panthor_vm_pool_destroy(struct panthor_file *pfile);
> diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c
> index e0ecc8bcfaae..59c30b311ee9 100644
> --- a/drivers/gpu/drm/panthor/panthor_sched.c
> +++ b/drivers/gpu/drm/panthor/panthor_sched.c
> @@ -24,6 +24,7 @@
>  
>  #include "panthor_devfreq.h"
>  #include "panthor_device.h"
> +#include "panthor_dump.h"
>  #include "panthor_fw.h"
>  #include "panthor_gem.h"
>  #include "panthor_gpu.h"
> @@ -2805,6 +2806,45 @@ static void group_sync_upd_work(struct work_struct *work)
>  	group_put(group);
>  }
>  
> +/**
> + * panthor_sched_get_groupinfo() - Build a group info structure for the group
> + *
> + * @group: the group to build a group info structure for
> + * @info: the group info structure to fill
> + */
> +void panthor_sched_get_groupinfo(struct panthor_group *group,
> +				 struct drm_panthor_dump_group_info *info)
> +{
> +	info->queue_count = group->queue_count;
> +	info->faulty_bitmask = group->fatal_queues;
> +}
> +
> +/** panthor_sched_get_queueinfo() - Build a queue info structure for a queue
> + * given its group and its cs_id
> + *
> + * @group: the group the queue belongs to
> + * @cs_id: the command stream ID of the queue
> + * @info: the queue info structure to fill
> + */
> +int panthor_sched_get_queueinfo(struct panthor_group *group, u32 cs_id,
> +				struct drm_panthor_dump_queue_info *info)
> +{
> +	struct panthor_queue *queue;
> +
> +	if (cs_id >= group->queue_count)
> +		return -EINVAL;
> +
> +	queue = group->queues[cs_id];
> +
> +	info->cs_id = cs_id;
> +	info->ringbuf_insert = queue->iface.input->insert;
> +	info->ringbuf_extract = queue->iface.output->extract;
> +	info->ringbuf_gpuva = panthor_kernel_bo_gpuva(queue->ringbuf);
> +	info->ringbuf_size = panthor_kernel_bo_size(queue->ringbuf);
> +
> +	return 0;
> +}
> +
>  static struct dma_fence *
>  queue_run_job(struct drm_sched_job *sched_job)
>  {
> @@ -2946,7 +2986,7 @@ queue_timedout_job(struct drm_sched_job *sched_job)
>  	struct panthor_device *ptdev = group->ptdev;
>  	struct panthor_scheduler *sched = ptdev->scheduler;
>  	struct panthor_queue *queue = group->queues[job->queue_idx];
> -
> +	struct panthor_core_dump_args core_dump_args;
>  	drm_warn(&ptdev->base, "job timeout\n");
>  
>  	drm_WARN_ON(&ptdev->base, atomic_read(&sched->reset.in_progress));
> @@ -2955,6 +2995,15 @@ queue_timedout_job(struct drm_sched_job *sched_job)
>  
>  	mutex_lock(&sched->lock);
>  	group->timedout = true;
> +
> +	core_dump_args = (struct panthor_core_dump_args) {
> +		.ptdev = ptdev,
> +		.group_vm = job->group->vm,
> +		.group = job->group,
> +	};
> +
> +	panthor_core_dump(&core_dump_args);
> +
>  	if (group->csg_id >= 0) {
>  		sched_queue_delayed_work(ptdev->scheduler, tick, 0);
>  	} else {
> diff --git a/drivers/gpu/drm/panthor/panthor_sched.h b/drivers/gpu/drm/panthor/panthor_sched.h
> index 3a30d2328b30..9a5b53498dcc 100644
> --- a/drivers/gpu/drm/panthor/panthor_sched.h
> +++ b/drivers/gpu/drm/panthor/panthor_sched.h
> @@ -17,6 +17,9 @@ struct panthor_device;
>  struct panthor_file;
>  struct panthor_group_pool;
>  struct panthor_job;
> +struct panthor_group;
> +struct drm_panthor_dump_group_info;
> +struct drm_panthor_dump_queue_info;
>  
>  int panthor_group_create(struct panthor_file *pfile,
>  			 const struct drm_panthor_group_create *group_args,
> @@ -41,6 +44,13 @@ int panthor_sched_init(struct panthor_device *ptdev);
>  void panthor_sched_unplug(struct panthor_device *ptdev);
>  void panthor_sched_pre_reset(struct panthor_device *ptdev);
>  void panthor_sched_post_reset(struct panthor_device *ptdev, bool reset_failed);
> +
> +void panthor_sched_get_groupinfo(struct panthor_group *group,
> +				 struct drm_panthor_dump_group_info *info);
> +
> +int panthor_sched_get_queueinfo(struct panthor_group *group, u32 cs_id,
> +				struct drm_panthor_dump_queue_info *info);
> +
>  void panthor_sched_suspend(struct panthor_device *ptdev);
>  void panthor_sched_resume(struct panthor_device *ptdev);
>  
> diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h
> index e235cf452460..82ec0f20c49e 100644
> --- a/include/uapi/drm/panthor_drm.h
> +++ b/include/uapi/drm/panthor_drm.h
> @@ -969,6 +969,130 @@ struct drm_panthor_tiler_heap_destroy {
>  	__u32 pad;
>  };
>  
> +/**
> + * enum drm_panthor_dump_header_type - Identifies the type of data that follows
> + * in a panthor core dump.
> + */
> +enum drm_panthor_dump_header_type {
> +	DRM_PANTHOR_DUMP_HEADER_TYPE_VERSION = 0,
> +	/**
> +	 * @DRM_PANTHOR_DUMP_HEADER_TYPE_GPU_INFO: Gpu information.
> +	 */
> +	DRM_PANTHOR_DUMP_HEADER_TYPE_GPU_INFO = 1,
> +	/**
> +	 * @DRM_PANTHOR_DUMP_HEADER_TYPE_CSIF_INFO: Command stream interface information.
> +	 */
> +	DRM_PANTHOR_DUMP_HEADER_TYPE_CSIF_INFO = 2,
> +	/**
> +	 * @DRM_PANTHOR_DUMP_HEADER_TYPE_FW_INFO: Information about the firmware.
> +	 */
> +	DRM_PANTHOR_DUMP_HEADER_TYPE_FW_INFO = 3,
> +	/**
> +	 * @DRM_PANTHOR_DUMP_HEADER_TYPE_VM: A dump of the VM for the context.
> +	 */
> +	DRM_PANTHOR_DUMP_HEADER_TYPE_VM = 4,
> +	/**
> +	 * @DRM_PANTHOR_DUMP_HEADER_TYPE_GROUP_INFO: Describes a group. A dump can
> +	 * contain either the faulty group, or all groups for the DRM FD.
> +	 */
> +	DRM_PANTHOR_DUMP_HEADER_TYPE_GROUP_INFO = 5,
> +	/**
> +	 * @DRM_PANTHOR_DUMP_HEADER_TYPE_QUEUE_INFO: Describes a faulty queue. This
> +	 * will immediately follow a group info.
> +	 */
> +	DRM_PANTHOR_DUMP_HEADER_TYPE_QUEUE_INFO = 6,
> +};
> +
> +/**
> + * struct drm_panthor_dump_header - A header that describes a section of a panthor core dump.
> + */
> +struct drm_panthor_dump_header {
> +	/** @magic: Always set to PANT (0x544e4150). */
> +	__u32 magic;
> +
> +	/** @header_type: Identifies the type of data in the following section of the
> +	 * core dump file
> +	 */
> +	enum drm_panthor_dump_header_type header_type;
> +
> +	/** @header_size: The size of the header.
> +	 *
> +	 * This is for backward-compatibility purposes in case this structure is
> +	 * augmented in the future. It allows userspace to skip over the header and
> +	 * access the actual data it describes.
> +	 */
> +	__u32 header_size;
> +
> +	/** @data_size: The size of the following section */
> +	__u32 data_size;
> +};
> +
> +/**
> + * struct drm_panthor_dump_version - Version information for a Panthor GPU dump.
> + *
> + * This structure is used to hold version information when performing a dump of
> + * the state of a Panthor GPU.
> + */
> +struct drm_panthor_dump_version {
> +	/** @major: Versioning information for backwards compatibility */
> +	__u32 major;
> +	/** @minor: Versioning information for backwards compatibility */
> +	__u32 minor;
> +};
> +
> +/**
> + * struct drm_panthor_dump_group_info - Group information for a Panthor GPU
> + * dump.
> + *
> + * This structure is used to hold information about a group when performing a
> + * dump of the state of a Panthor GPU.
> + */
> +struct drm_panthor_dump_group_info {
> +	/** @queue_count: The number of queues in the group. */
> +	__u32 queue_count;
> +	/** @faulty_queues: A bitmask denoting the faulty queues */
> +	__u32 faulty_bitmask;
> +};
> +
> +#define DRM_PANTHOR_DUMP_QUEUE_INFO_FLAGS_FAULTY	(1 << 0)
> +
> +/**
> + * struct drm_panthor_dump_queue_info - Queue information for a Panthor GPU
> + * dump.
> + *
> + * This structure is used to hold information about a queue when performing a
> + * dump of the state of a Panthor GPU.
> + */
> +struct drm_panthor_dump_queue_info {
> +	/** See DRM_PANTHOR_DUMP_QUEUE_INFO_FLAGS_XXX */
> +	u32 flags;
> +	/** @cs_id: The ID of the command stream. */
> +	__s32 cs_id;
> +	/** @faulty: Whether this queue has faulted */
> +	/** @ringbuf_gpuva: The GPU virtual address of the ring buffer. */
> +	__u64 ringbuf_gpuva;
> +	/** @ringbuf_insert: The insert point (i.e.: offset) in the ring buffer. This
> +	 * is where a instruction would be inserted next by the CPU.
> +	 */
> +	__u64 ringbuf_insert;
> +	/** @ringbuf_extract: The extract point (i.e.: offset) in the ring buffer.
> +	 * This is where the GPU would read the next instruction.
> +	 */
> +	__u64 ringbuf_extract;
> +	/** @ringbuf_size: The size of the ring buffer */
> +	__u64 ringbuf_size;
> +};
> +
> +/**
> + * struct drm_panthor_dump_gpuva - Describes a GPU VA range in the dump.
> + */
> +struct drm_panthor_dump_gpuva {
> +	/** @addr: The start address for the mapping */
> +	__u64 addr;
> +	/** @range: The range covered by the VA mapping */
> +	__u64 range;
> +};
> +
>  #if defined(__cplusplus)
>  }
>  #endif
> -- 
> 2.45.2


More information about the dri-devel mailing list