aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3406-drm-amdkfd-Add-debugfs-support-to-KFD.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3406-drm-amdkfd-Add-debugfs-support-to-KFD.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3406-drm-amdkfd-Add-debugfs-support-to-KFD.patch623
1 files changed, 623 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3406-drm-amdkfd-Add-debugfs-support-to-KFD.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3406-drm-amdkfd-Add-debugfs-support-to-KFD.patch
new file mode 100644
index 00000000..a4ec8e74
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3406-drm-amdkfd-Add-debugfs-support-to-KFD.patch
@@ -0,0 +1,623 @@
+From 789251c99cc601c2524e5dd9dd5ff8625560de06 Mon Sep 17 00:00:00 2001
+From: Felix Kuehling <Felix.Kuehling@amd.com>
+Date: Mon, 27 Nov 2017 18:29:49 -0500
+Subject: [PATCH 3406/4131] drm/amdkfd: Add debugfs support to KFD
+
+This commit adds several debugfs entries for kfd:
+
+kfd/hqds: dumps all HQDs on all GPUs for KFD-controlled compute and
+ SDMA RLC queues
+
+kfd/mqds: dumps all MQDs of all KFD processes on all GPUs
+
+kfd/rls: dumps HWS runlists on all GPUs
+
+Signed-off-by: Yong Zhao <yong.zhao@amd.com>
+Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com>
+Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com>
+Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
+---
+ drivers/gpu/drm/amd/amdkfd/Makefile | 2 +
+ drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c | 75 ++++++++++++++++++++++
+ .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 71 ++++++++++++++++++++
+ drivers/gpu/drm/amd/amdkfd/kfd_module.c | 3 +
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h | 4 ++
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c | 27 ++++++++
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c | 25 ++++++++
+ drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c | 24 +++++++
+ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 21 ++++++
+ drivers/gpu/drm/amd/amdkfd/kfd_process.c | 29 +++++++++
+ .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 63 ++++++++++++++++++
+ drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 55 ++++++++++++++++
+ 12 files changed, 399 insertions(+)
+ create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile
+index 342c2d9..67e2c42 100644
+--- a/drivers/gpu/drm/amd/amdkfd/Makefile
++++ b/drivers/gpu/drm/amd/amdkfd/Makefile
+@@ -37,4 +37,6 @@ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \
+ kfd_interrupt.o kfd_events.o cik_event_interrupt.o \
+ kfd_dbgdev.o kfd_dbgmgr.o
+
++amdkfd-$(CONFIG_DEBUG_FS) += kfd_debugfs.o
++
+ obj-$(CONFIG_HSA_AMD) += amdkfd.o
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
+new file mode 100644
+index 0000000..4bd6ebf
+--- /dev/null
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c
+@@ -0,0 +1,75 @@
++/*
++ * Copyright 2016-2017 Advanced Micro Devices, Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ * OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++#include <linux/debugfs.h>
++#include "kfd_priv.h"
++
++static struct dentry *debugfs_root;
++
++static int kfd_debugfs_open(struct inode *inode, struct file *file)
++{
++ int (*show)(struct seq_file *, void *) = inode->i_private;
++
++ return single_open(file, show, NULL);
++}
++
++static const struct file_operations kfd_debugfs_fops = {
++ .owner = THIS_MODULE,
++ .open = kfd_debugfs_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++void kfd_debugfs_init(void)
++{
++ struct dentry *ent;
++
++ debugfs_root = debugfs_create_dir("kfd", NULL);
++ if (!debugfs_root || debugfs_root == ERR_PTR(-ENODEV)) {
++ pr_warn("Failed to create kfd debugfs dir\n");
++ return;
++ }
++
++ ent = debugfs_create_file("mqds", S_IFREG | 0444, debugfs_root,
++ kfd_debugfs_mqds_by_process,
++ &kfd_debugfs_fops);
++ if (!ent)
++ pr_warn("Failed to create mqds in kfd debugfs\n");
++
++ ent = debugfs_create_file("hqds", S_IFREG | 0444, debugfs_root,
++ kfd_debugfs_hqds_by_device,
++ &kfd_debugfs_fops);
++ if (!ent)
++ pr_warn("Failed to create hqds in kfd debugfs\n");
++
++ ent = debugfs_create_file("rls", S_IFREG | 0444, debugfs_root,
++ kfd_debugfs_rls_by_device,
++ &kfd_debugfs_fops);
++ if (!ent)
++ pr_warn("Failed to create rls in kfd debugfs\n");
++}
++
++void kfd_debugfs_fini(void)
++{
++ debugfs_remove_recursive(debugfs_root);
++}
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+index 81ec7bb..d0693fd 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+@@ -1311,3 +1311,74 @@ void device_queue_manager_uninit(struct device_queue_manager *dqm)
+ dqm->ops.uninitialize(dqm);
+ kfree(dqm);
+ }
++
++#if defined(CONFIG_DEBUG_FS)
++
++static void seq_reg_dump(struct seq_file *m,
++ uint32_t (*dump)[2], uint32_t n_regs)
++{
++ uint32_t i, count;
++
++ for (i = 0, count = 0; i < n_regs; i++) {
++ if (count == 0 ||
++ dump[i-1][0] + sizeof(uint32_t) != dump[i][0]) {
++ seq_printf(m, "%s %08x: %08x",
++ i ? "\n" : "",
++ dump[i][0], dump[i][1]);
++ count = 7;
++ } else {
++ seq_printf(m, " %08x", dump[i][1]);
++ count--;
++ }
++ }
++
++ seq_puts(m, "\n");
++}
++
++int dqm_debugfs_hqds(struct seq_file *m, void *data)
++{
++ struct device_queue_manager *dqm = data;
++ uint32_t (*dump)[2], n_regs;
++ int pipe, queue;
++ int r = 0;
++
++ for (pipe = 0; pipe < get_pipes_per_mec(dqm); pipe++) {
++ int pipe_offset = pipe * get_queues_per_pipe(dqm);
++
++ for (queue = 0; queue < get_queues_per_pipe(dqm); queue++) {
++ if (!test_bit(pipe_offset + queue,
++ dqm->dev->shared_resources.queue_bitmap))
++ continue;
++
++ r = dqm->dev->kfd2kgd->hqd_dump(
++ dqm->dev->kgd, pipe, queue, &dump, &n_regs);
++ if (r)
++ break;
++
++ seq_printf(m, " CP Pipe %d, Queue %d\n",
++ pipe, queue);
++ seq_reg_dump(m, dump, n_regs);
++
++ kfree(dump);
++ }
++ }
++
++ for (pipe = 0; pipe < CIK_SDMA_ENGINE_NUM; pipe++) {
++ for (queue = 0; queue < CIK_SDMA_QUEUES_PER_ENGINE; queue++) {
++ r = dqm->dev->kfd2kgd->hqd_sdma_dump(
++ dqm->dev->kgd, pipe, queue, &dump, &n_regs);
++ if (r)
++ break;
++
++ seq_printf(m, " SDMA Engine %d, RLC %d\n",
++ pipe, queue);
++ seq_reg_dump(m, dump, n_regs);
++
++ kfree(dump);
++ }
++ }
++
++ return r;
++}
++
++#endif
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
+index 4e060c8..f50e494 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c
+@@ -123,6 +123,8 @@ static int __init kfd_module_init(void)
+
+ kfd_process_create_wq();
+
++ kfd_debugfs_init();
++
+ amdkfd_init_completed = 1;
+
+ dev_info(kfd_device, "Initialized module\n");
+@@ -139,6 +141,7 @@ static void __exit kfd_module_exit(void)
+ {
+ amdkfd_init_completed = 0;
+
++ kfd_debugfs_fini();
+ kfd_process_destroy_wq();
+ kfd_topology_shutdown();
+ kfd_chardev_exit();
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
+index 1f3a6ba..8972bcf 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h
+@@ -85,6 +85,10 @@ struct mqd_manager {
+ uint64_t queue_address, uint32_t pipe_id,
+ uint32_t queue_id);
+
++#if defined(CONFIG_DEBUG_FS)
++ int (*debugfs_show_mqd)(struct seq_file *m, void *data);
++#endif
++
+ struct mutex mqd_mutex;
+ struct kfd_dev *dev;
+ };
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
+index 7aa57ab..f8ef4a0 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
+@@ -365,6 +365,24 @@ static int update_mqd_hiq(struct mqd_manager *mm, void *mqd,
+ return 0;
+ }
+
++#if defined(CONFIG_DEBUG_FS)
++
++static int debugfs_show_mqd(struct seq_file *m, void *data)
++{
++ seq_hex_dump(m, " ", DUMP_PREFIX_OFFSET, 32, 4,
++ data, sizeof(struct cik_mqd), false);
++ return 0;
++}
++
++static int debugfs_show_mqd_sdma(struct seq_file *m, void *data)
++{
++ seq_hex_dump(m, " ", DUMP_PREFIX_OFFSET, 32, 4,
++ data, sizeof(struct cik_sdma_rlc_registers), false);
++ return 0;
++}
++
++#endif
++
+
+ struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
+ struct kfd_dev *dev)
+@@ -389,6 +407,9 @@ struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
+ mqd->update_mqd = update_mqd;
+ mqd->destroy_mqd = destroy_mqd;
+ mqd->is_occupied = is_occupied;
++#if defined(CONFIG_DEBUG_FS)
++ mqd->debugfs_show_mqd = debugfs_show_mqd;
++#endif
+ break;
+ case KFD_MQD_TYPE_HIQ:
+ mqd->init_mqd = init_mqd_hiq;
+@@ -397,6 +418,9 @@ struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
+ mqd->update_mqd = update_mqd_hiq;
+ mqd->destroy_mqd = destroy_mqd;
+ mqd->is_occupied = is_occupied;
++#if defined(CONFIG_DEBUG_FS)
++ mqd->debugfs_show_mqd = debugfs_show_mqd;
++#endif
+ break;
+ case KFD_MQD_TYPE_SDMA:
+ mqd->init_mqd = init_mqd_sdma;
+@@ -405,6 +429,9 @@ struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type,
+ mqd->update_mqd = update_mqd_sdma;
+ mqd->destroy_mqd = destroy_mqd_sdma;
+ mqd->is_occupied = is_occupied_sdma;
++#if defined(CONFIG_DEBUG_FS)
++ mqd->debugfs_show_mqd = debugfs_show_mqd_sdma;
++#endif
+ break;
+ default:
+ kfree(mqd);
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
+index 00e1f1a..971aec0 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c
+@@ -358,7 +358,23 @@ static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd,
+ return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd);
+ }
+
++#if defined(CONFIG_DEBUG_FS)
+
++static int debugfs_show_mqd(struct seq_file *m, void *data)
++{
++ seq_hex_dump(m, " ", DUMP_PREFIX_OFFSET, 32, 4,
++ data, sizeof(struct vi_mqd), false);
++ return 0;
++}
++
++static int debugfs_show_mqd_sdma(struct seq_file *m, void *data)
++{
++ seq_hex_dump(m, " ", DUMP_PREFIX_OFFSET, 32, 4,
++ data, sizeof(struct vi_sdma_mqd), false);
++ return 0;
++}
++
++#endif
+
+ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
+ struct kfd_dev *dev)
+@@ -383,6 +399,9 @@ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
+ mqd->update_mqd = update_mqd;
+ mqd->destroy_mqd = destroy_mqd;
+ mqd->is_occupied = is_occupied;
++#if defined(CONFIG_DEBUG_FS)
++ mqd->debugfs_show_mqd = debugfs_show_mqd;
++#endif
+ break;
+ case KFD_MQD_TYPE_HIQ:
+ mqd->init_mqd = init_mqd_hiq;
+@@ -391,6 +410,9 @@ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
+ mqd->update_mqd = update_mqd_hiq;
+ mqd->destroy_mqd = destroy_mqd;
+ mqd->is_occupied = is_occupied;
++#if defined(CONFIG_DEBUG_FS)
++ mqd->debugfs_show_mqd = debugfs_show_mqd;
++#endif
+ break;
+ case KFD_MQD_TYPE_SDMA:
+ mqd->init_mqd = init_mqd_sdma;
+@@ -399,6 +421,9 @@ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type,
+ mqd->update_mqd = update_mqd_sdma;
+ mqd->destroy_mqd = destroy_mqd_sdma;
+ mqd->is_occupied = is_occupied_sdma;
++#if defined(CONFIG_DEBUG_FS)
++ mqd->debugfs_show_mqd = debugfs_show_mqd_sdma;
++#endif
+ break;
+ default:
+ kfree(mqd);
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
+index c3230b9..0ecbd1f 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
+@@ -278,6 +278,7 @@ static int pm_create_runlist_ib(struct packet_manager *pm,
+ return retval;
+
+ *rl_size_bytes = alloc_size_bytes;
++ pm->ib_size_bytes = alloc_size_bytes;
+
+ pr_debug("Building runlist ib process count: %d queues count %d\n",
+ pm->dqm->processes_count, pm->dqm->queue_count);
+@@ -591,3 +592,26 @@ void pm_release_ib(struct packet_manager *pm)
+ }
+ mutex_unlock(&pm->lock);
+ }
++
++#if defined(CONFIG_DEBUG_FS)
++
++int pm_debugfs_runlist(struct seq_file *m, void *data)
++{
++ struct packet_manager *pm = data;
++
++ mutex_lock(&pm->lock);
++
++ if (!pm->allocated) {
++ seq_puts(m, " No active runlist\n");
++ goto out;
++ }
++
++ seq_hex_dump(m, " ", DUMP_PREFIX_OFFSET, 32, 4,
++ pm->ib_buffer_obj->cpu_ptr, pm->ib_size_bytes, false);
++
++out:
++ mutex_unlock(&pm->lock);
++ return 0;
++}
++
++#endif
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+index 1edab21..dca493b 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+@@ -33,6 +33,7 @@
+ #include <linux/kfd_ioctl.h>
+ #include <linux/idr.h>
+ #include <linux/kfifo.h>
++#include <linux/seq_file.h>
+ #include <kgd_kfd_interface.h>
+
+ #include "amd_shared.h"
+@@ -735,6 +736,7 @@ struct packet_manager {
+ struct mutex lock;
+ bool allocated;
+ struct kfd_mem_obj *ib_buffer_obj;
++ unsigned int ib_size_bytes;
+ };
+
+ int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm);
+@@ -781,4 +783,23 @@ int kfd_event_destroy(struct kfd_process *p, uint32_t event_id);
+
+ int dbgdev_wave_reset_wavefronts(struct kfd_dev *dev, struct kfd_process *p);
+
++/* Debugfs */
++#if defined(CONFIG_DEBUG_FS)
++
++void kfd_debugfs_init(void);
++void kfd_debugfs_fini(void);
++int kfd_debugfs_mqds_by_process(struct seq_file *m, void *data);
++int pqm_debugfs_mqds(struct seq_file *m, void *data);
++int kfd_debugfs_hqds_by_device(struct seq_file *m, void *data);
++int dqm_debugfs_hqds(struct seq_file *m, void *data);
++int kfd_debugfs_rls_by_device(struct seq_file *m, void *data);
++int pm_debugfs_runlist(struct seq_file *m, void *data);
++
++#else
++
++static inline void kfd_debugfs_init(void) {}
++static inline void kfd_debugfs_fini(void) {}
++
++#endif
++
+ #endif
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+index 39f4c19..99c18ee 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+@@ -620,3 +620,32 @@ int kfd_reserved_mem_mmap(struct kfd_process *process,
+ PFN_DOWN(__pa(qpd->cwsr_kaddr)),
+ KFD_CWSR_TBA_TMA_SIZE, vma->vm_page_prot);
+ }
++
++#if defined(CONFIG_DEBUG_FS)
++
++int kfd_debugfs_mqds_by_process(struct seq_file *m, void *data)
++{
++ struct kfd_process *p;
++ unsigned int temp;
++ int r = 0;
++
++ int idx = srcu_read_lock(&kfd_processes_srcu);
++
++ hash_for_each_rcu(kfd_processes_table, temp, p, kfd_processes) {
++ seq_printf(m, "Process %d PASID %d:\n",
++ p->lead_thread->tgid, p->pasid);
++
++ mutex_lock(&p->mutex);
++ r = pqm_debugfs_mqds(m, &p->pqm);
++ mutex_unlock(&p->mutex);
++
++ if (r)
++ break;
++ }
++
++ srcu_read_unlock(&kfd_processes_srcu, idx);
++
++ return r;
++}
++
++#endif
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+index 10f9a87..33cf119 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+@@ -369,4 +369,67 @@ struct kernel_queue *pqm_get_kernel_queue(
+ return NULL;
+ }
+
++#if defined(CONFIG_DEBUG_FS)
+
++int pqm_debugfs_mqds(struct seq_file *m, void *data)
++{
++ struct process_queue_manager *pqm = data;
++ struct process_queue_node *pqn;
++ struct queue *q;
++ enum KFD_MQD_TYPE mqd_type;
++ struct mqd_manager *mqd_manager;
++ int r = 0;
++
++ list_for_each_entry(pqn, &pqm->queues, process_queue_list) {
++ if (pqn->q) {
++ q = pqn->q;
++ switch (q->properties.type) {
++ case KFD_QUEUE_TYPE_SDMA:
++ seq_printf(m, " SDMA queue on device %x\n",
++ q->device->id);
++ mqd_type = KFD_MQD_TYPE_SDMA;
++ break;
++ case KFD_QUEUE_TYPE_COMPUTE:
++ seq_printf(m, " Compute queue on device %x\n",
++ q->device->id);
++ mqd_type = KFD_MQD_TYPE_CP;
++ break;
++ default:
++ seq_printf(m,
++ " Bad user queue type %d on device %x\n",
++ q->properties.type, q->device->id);
++ continue;
++ }
++ mqd_manager = q->device->dqm->ops.get_mqd_manager(
++ q->device->dqm, mqd_type);
++ } else if (pqn->kq) {
++ q = pqn->kq->queue;
++ mqd_manager = pqn->kq->mqd;
++ switch (q->properties.type) {
++ case KFD_QUEUE_TYPE_DIQ:
++ seq_printf(m, " DIQ on device %x\n",
++ pqn->kq->dev->id);
++ mqd_type = KFD_MQD_TYPE_HIQ;
++ break;
++ default:
++ seq_printf(m,
++ " Bad kernel queue type %d on device %x\n",
++ q->properties.type,
++ pqn->kq->dev->id);
++ continue;
++ }
++ } else {
++ seq_printf(m,
++ " Weird: Queue node with neither kernel nor user queue\n");
++ continue;
++ }
++
++ r = mqd_manager->debugfs_show_mqd(m, q->mqd);
++ if (r != 0)
++ break;
++ }
++
++ return r;
++}
++
++#endif
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+index 19ce590..9d03a56 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+@@ -32,6 +32,7 @@
+ #include "kfd_priv.h"
+ #include "kfd_crat.h"
+ #include "kfd_topology.h"
++#include "kfd_device_queue_manager.h"
+
+ static struct list_head topology_device_list;
+ static int topology_crat_parsed;
+@@ -1233,3 +1234,57 @@ struct kfd_dev *kfd_topology_enum_kfd_devices(uint8_t idx)
+ return device;
+
+ }
++
++#if defined(CONFIG_DEBUG_FS)
++
++int kfd_debugfs_hqds_by_device(struct seq_file *m, void *data)
++{
++ struct kfd_topology_device *dev;
++ unsigned int i = 0;
++ int r = 0;
++
++ down_read(&topology_lock);
++
++ list_for_each_entry(dev, &topology_device_list, list) {
++ if (!dev->gpu) {
++ i++;
++ continue;
++ }
++
++ seq_printf(m, "Node %u, gpu_id %x:\n", i++, dev->gpu->id);
++ r = dqm_debugfs_hqds(m, dev->gpu->dqm);
++ if (r)
++ break;
++ }
++
++ up_read(&topology_lock);
++
++ return r;
++}
++
++int kfd_debugfs_rls_by_device(struct seq_file *m, void *data)
++{
++ struct kfd_topology_device *dev;
++ unsigned int i = 0;
++ int r = 0;
++
++ down_read(&topology_lock);
++
++ list_for_each_entry(dev, &topology_device_list, list) {
++ if (!dev->gpu) {
++ i++;
++ continue;
++ }
++
++ seq_printf(m, "Node %u, gpu_id %x:\n", i++, dev->gpu->id);
++ r = pm_debugfs_runlist(m, &dev->gpu->dqm->packets);
++ if (r)
++ break;
++ }
++
++ up_read(&topology_lock);
++
++ return r;
++}
++
++#endif
+--
+2.7.4
+