diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3444-drm-amdkfd-add-debug-notification.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3444-drm-amdkfd-add-debug-notification.patch | 577 |
1 files changed, 577 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3444-drm-amdkfd-add-debug-notification.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3444-drm-amdkfd-add-debug-notification.patch new file mode 100644 index 00000000..69b42ac6 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3444-drm-amdkfd-add-debug-notification.patch @@ -0,0 +1,577 @@ +From 149171bf2e15568cb3d7169d6e4c6dbd5fbaa8cb Mon Sep 17 00:00:00 2001 +From: Jonathan Kim <jonathan.kim@amd.com> +Date: Thu, 9 May 2019 20:49:29 -0400 +Subject: [PATCH 3444/4256] drm/amdkfd: add debug notification + +User space adds trace to process. Ring buffer entry is flagged by IH and +process info is sent to debug event handler by kernel. Kernel updates queue +debug event status as pending event by doorbell id and updates fifo data +accessible by user space after kernel sends wake signal on polling fd. Fifo +data records debug event history as fifo string where 't' is trap and 'v' +is vm fault. + +User space can query pending events by target queue id or find the first +queue with a pending event. User space also has option of clearing pending +event status on target (or first found) queue. Kernel will report queried +pending event type (trap or vm fault) and suspend status of queue. + +Change-Id: Ied5b7c21306638c8cfdaac8d8b9bae342b235b47 +Signed-off-by: Jonathan Kim <jonathan.kim@amd.com> +--- + drivers/gpu/drm/amd/amdkfd/Makefile | 3 +- + drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 18 ++ + drivers/gpu/drm/amd/amdkfd/kfd_debug_events.c | 285 ++++++++++++++++++ + drivers/gpu/drm/amd/amdkfd/kfd_debug_events.h | 40 +++ + .../gpu/drm/amd/amdkfd/kfd_int_process_v9.c | 27 +- + drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 11 + + include/uapi/linux/kfd_ioctl.h | 21 +- + 7 files changed, 396 insertions(+), 9 deletions(-) + create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_debug_events.c + create mode 100644 drivers/gpu/drm/amd/amdkfd/kfd_debug_events.h + +diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile +index dad236a68a25..aa951107a895 100644 +--- a/drivers/gpu/drm/amd/amdkfd/Makefile ++++ b/drivers/gpu/drm/amd/amdkfd/Makefile +@@ -59,7 +59,8 @@ AMDKFD_FILES := $(AMDKFD_PATH)/kfd_module.o \ + $(AMDKFD_PATH)/kfd_rdma.o \ + $(AMDKFD_PATH)/kfd_peerdirect.o \ + $(AMDKFD_PATH)/kfd_ipc.o \ +- $(AMDKFD_PATH)/kfd_trace.o ++ $(AMDKFD_PATH)/kfd_trace.o \ ++ $(AMDKFD_PATH)/kfd_debug_events.o + + ifneq ($(CONFIG_AMD_IOMMU_V2),) + AMDKFD_FILES += $(AMDKFD_PATH)/kfd_iommu.o +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +index e96aa4eaaa66..44a9803f26f3 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +@@ -42,6 +42,7 @@ + #include "kfd_priv.h" + #include "kfd_device_queue_manager.h" + #include "kfd_dbgmgr.h" ++#include "kfd_debug_events.h" + #include "kfd_ipc.h" + #include "kfd_trace.h" + +@@ -2736,6 +2737,18 @@ static int kfd_ioctl_dbg_set_debug_trap(struct file *filep, + r = dev->kfd2kgd->enable_debug_trap(dev->kgd, + pdd->trap_debug_wave_launch_mode, + dev->vm_info.last_vmid_kfd); ++ if (r) ++ break; ++ ++ r = kfd_dbg_ev_enable(pdd); ++ if (r >= 0) { ++ args->data3 = r; ++ r = 0; ++ } else { ++ pdd->debug_trap_enabled = false; ++ dev->kfd2kgd->disable_debug_trap(dev->kgd); ++ } ++ + break; + default: + pr_err("Invalid trap enable option: %i\n", +@@ -2783,6 +2796,11 @@ static int kfd_ioctl_dbg_set_debug_trap(struct file *filep, + if (r) + goto unlock_out; + break; ++ case KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT: ++ r = kfd_dbg_ev_query_debug_event(pdd, &args->data1, ++ args->data2, ++ &args->data3); ++ break; + default: + pr_err("Invalid option: %i\n", debug_trap_action); + r = -EINVAL; +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug_events.c +new file mode 100644 +index 000000000000..210cccdeed81 +--- /dev/null ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug_events.c +@@ -0,0 +1,285 @@ ++/* ++ * Copyright 2019 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/kfifo.h> ++#include <linux/poll.h> ++#include <linux/wait.h> ++#include <linux/anon_inodes.h> ++#include <uapi/linux/kfd_ioctl.h> ++#include "kfd_debug_events.h" ++#include "kfd_priv.h" ++#include "kfd_topology.h" ++ ++/* poll and read functions */ ++static __poll_t kfd_dbg_ev_poll(struct file *, struct poll_table_struct *); ++static ssize_t kfd_dbg_ev_read(struct file *, char __user *, size_t, loff_t *); ++static int kfd_dbg_ev_release(struct inode *, struct file *); ++ ++/* fd name */ ++static const char kfd_dbg_name[] = "kfd_debug"; ++ ++/* fops for polling, read and ioctl */ ++static const struct file_operations kfd_dbg_ev_fops = { ++ .owner = THIS_MODULE, ++ .poll = kfd_dbg_ev_poll, ++ .read = kfd_dbg_ev_read, ++ .release = kfd_dbg_ev_release ++}; ++ ++/* poll on wait queue of file */ ++static __poll_t kfd_dbg_ev_poll(struct file *filep, ++ struct poll_table_struct *wait) ++{ ++ ++ struct kfd_debug_process_device *dpd = filep->private_data; ++ ++ __poll_t mask = 0; ++ ++ /* pending event have been queue'd via interrupt */ ++ poll_wait(filep, &dpd->wait_queue, wait); ++ mask |= !kfifo_is_empty(&dpd->fifo) ? POLLIN | POLLRDNORM : mask; ++ ++ return mask; ++} ++ ++/* read based on wait entries and return types found */ ++static ssize_t kfd_dbg_ev_read(struct file *filep, char __user *user, ++ size_t size, loff_t *offset) ++{ ++ int ret, copied; ++ struct kfd_debug_process_device *dpd = filep->private_data; ++ ++ ret = kfifo_to_user(&dpd->fifo, user, size, &copied); ++ ++ if (ret) { ++ pr_debug("KFD DEBUG EVENT: Failed to read poll fd (%i)\n", ret); ++ return ret; ++ } ++ ++ return copied; ++} ++ ++static int kfd_dbg_ev_release(struct inode *inode, struct file *filep) ++{ ++ struct kfd_debug_process_device *dpd = filep->private_data; ++ ++ kfifo_free(&dpd->fifo); ++ ++ return 0; ++} ++ ++/* query pending events and return queue_id, event_type and is_suspended */ ++#define KFD_DBG_EV_SET_SUSPEND_STATE(x, s) \ ++ ((x) = (s) ? (x) | KFD_DBG_EV_STATUS_SUSPENDED : \ ++ (x) & ~KFD_DBG_EV_STATUS_SUSPENDED) ++ ++#define KFD_DBG_EV_SET_EVENT_TYPE(x, e) \ ++ ((x) = ((x) & ~(KFD_DBG_EV_STATUS_TRAP \ ++ | KFD_DBG_EV_STATUS_VMFAULT)) | (e)) ++ ++int kfd_dbg_ev_query_debug_event(struct kfd_process_device *pdd, ++ unsigned int *queue_id, ++ unsigned int flags, ++ uint32_t *event_status) ++{ ++ struct process_queue_manager *pqm; ++ struct process_queue_node *pqn; ++ struct queue *q; ++ int ret = 0; ++ ++ if (!pdd || !pdd->process) ++ return -ENODATA; ++ ++ /* lock process events to update event queues */ ++ mutex_lock(&pdd->process->event_mutex); ++ pqm = &pdd->process->pqm; ++ ++ if (*queue_id != KFD_INVALID_QUEUEID) { ++ q = pqm_get_user_queue(pqm, *queue_id); ++ ++ if (!q) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ KFD_DBG_EV_SET_EVENT_TYPE(*event_status, ++ q->properties.debug_event_type); ++ KFD_DBG_EV_SET_SUSPEND_STATE(*event_status, ++ q->properties.is_suspended); ++ if (flags & KFD_DBG_EV_FLAG_CLEAR_STATUS) ++ q->properties.debug_event_type = 0; ++ goto out; ++ ++ } else { ++ list_for_each_entry(pqn, &pqm->queues, process_queue_list) { ++ if (pqn->q && ++ (pqn->q->properties.debug_event_type ++ == KFD_DBG_EV_STATUS_TRAP ++ || pqn->q->properties.debug_event_type ++ == KFD_DBG_EV_STATUS_VMFAULT)) { ++ *queue_id = pqn->q->properties.queue_id; ++ KFD_DBG_EV_SET_EVENT_TYPE(*event_status, ++ pqn->q->properties.debug_event_type); ++ KFD_DBG_EV_SET_SUSPEND_STATE(*event_status, ++ pqn->q->properties.is_suspended); ++ if (flags & KFD_DBG_EV_FLAG_CLEAR_STATUS) ++ pqn->q->properties.debug_event_type ++ = 0; ++ goto out; ++ } ++ } ++ ret = -EAGAIN; ++ } ++ ++out: ++ mutex_unlock(&pdd->process->event_mutex); ++ return ret; ++} ++ ++/* create event queue struct associated with process per device */ ++static int kfd_create_event_queue(struct kfd_process_device *pdd) ++{ ++ struct process_queue_manager *pqm; ++ struct process_queue_node *pqn; ++ struct kfd_topology_device *tdev; ++ int ret; ++ ++ if (!pdd || !pdd->process) ++ return -ESRCH; ++ ++ tdev = kfd_topology_device_by_id(pdd->dev->id); ++ ++ pdd->dpd.max_debug_events = tdev->node_props.simd_count ++ * tdev->node_props.max_waves_per_simd; ++ ++ ret = kfifo_alloc(&pdd->dpd.fifo, pdd->dpd.max_debug_events, ++ GFP_KERNEL); ++ ++ if (ret) ++ return ret; ++ ++ init_waitqueue_head(&pdd->dpd.wait_queue); ++ ++ pqm = &pdd->process->pqm; ++ ++ /* to reset queue pending status - TBD need init in queue creation */ ++ list_for_each_entry(pqn, &pqm->queues, process_queue_list) { ++ if (pqn->q->device == pdd->dev) ++ pqn->q->properties.debug_event_type = 0; ++ } ++ ++ return ret; ++} ++ ++/* update process device, write to kfifo and wake up wait queue */ ++static void kfd_dbg_ev_update_event_queue(struct kfd_process_device *pdd, ++ unsigned int doorbell_id, ++ bool is_vmfault) ++{ ++ struct process_queue_manager *pqm; ++ struct process_queue_node *pqn; ++ char fifo_output; ++ ++ if (!pdd->debug_trap_enabled) ++ return; ++ ++ pqm = &pdd->process->pqm; ++ ++ /* iterate through each queue */ ++ list_for_each_entry(pqn, &pqm->queues, ++ process_queue_list) { ++ ++ if (!pqn->q) ++ continue; ++ ++ if (pqn->q->device != pdd->dev) ++ continue; ++ ++ if (pqn->q->doorbell_id != doorbell_id && !is_vmfault) ++ continue; ++ ++ pqn->q->properties.debug_event_type |= ++ is_vmfault ? KFD_DBG_EV_STATUS_VMFAULT : ++ KFD_DBG_EV_STATUS_TRAP; ++ ++ fifo_output = is_vmfault ? 'v' : 't'; ++ ++ kfifo_in(&pdd->dpd.fifo, &fifo_output, 1); ++ ++ wake_up_all(&pdd->dpd.wait_queue); ++ ++ if (!is_vmfault) ++ break; ++ } ++} ++ ++/* set pending event queue entry from ring entry */ ++void kfd_set_dbg_ev_from_interrupt(struct kfd_dev *dev, ++ unsigned int pasid, ++ uint32_t doorbell_id, ++ bool is_vmfault) ++{ ++ struct kfd_process *p; ++ struct kfd_process_device *pdd; ++ ++ p = kfd_lookup_process_by_pasid(pasid); ++ ++ if (!p) ++ return; ++ ++ pdd = kfd_get_process_device_data(dev, p); ++ ++ if (!pdd) { ++ kfd_unref_process(p); ++ return; ++ } ++ ++ mutex_lock(&p->event_mutex); ++ ++ kfd_dbg_ev_update_event_queue(pdd, doorbell_id, is_vmfault); ++ ++ mutex_unlock(&p->event_mutex); ++ ++ kfd_unref_process(p); ++} ++ ++/* enable debug and return file pointer struct */ ++int kfd_dbg_ev_enable(struct kfd_process_device *pdd) ++{ ++ int ret; ++ ++ if (!pdd || !pdd->process) ++ return -ESRCH; ++ ++ mutex_lock(&pdd->process->event_mutex); ++ ++ ret = kfd_create_event_queue(pdd); ++ ++ mutex_unlock(&pdd->process->event_mutex); ++ ++ if (ret) ++ return ret; ++ ++ return anon_inode_getfd(kfd_dbg_name, &kfd_dbg_ev_fops, ++ (void *)&pdd->dpd, 0); ++} ++ +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug_events.h b/drivers/gpu/drm/amd/amdkfd/kfd_debug_events.h +new file mode 100644 +index 000000000000..5b035a4321c6 +--- /dev/null ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug_events.h +@@ -0,0 +1,40 @@ ++/* ++ * Copyright 2019 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. ++ */ ++ ++#ifndef KFD_DEBUG_EVENTS_H_INCLUDED ++#define KFD_DEBUG_EVENTS_H_INCLUDED ++ ++#include "kfd_priv.h" ++ ++int kfd_dbg_ev_query_debug_event(struct kfd_process_device *pdd, ++ unsigned int *queue_id, ++ unsigned int flags, ++ uint32_t *event_status); ++ ++void kfd_set_dbg_ev_from_interrupt(struct kfd_dev *dev, ++ unsigned int pasid, ++ uint32_t doorbell_id, ++ bool is_vmfault); ++ ++int kfd_dbg_ev_enable(struct kfd_process_device *pdd); ++ ++#endif +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c +index 3ef67d2e0d9f..ab8a695c4a3c 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c +@@ -22,9 +22,13 @@ + + #include "kfd_priv.h" + #include "kfd_events.h" ++#include "kfd_debug_events.h" + #include "soc15_int.h" + #include "kfd_device_queue_manager.h" + ++#define KFD_CONTEXT_ID_DEBUG_TRAP_MASK 0x000080 ++#define KFD_CONTEXT_ID_DEBUG_DOORBELL_MASK 0x0003ff ++ + static bool event_interrupt_isr_v9(struct kfd_dev *dev, + const uint32_t *ih_ring_entry, + uint32_t *patched_ihre, +@@ -88,21 +92,29 @@ static void event_interrupt_wq_v9(struct kfd_dev *dev, + const uint32_t *ih_ring_entry) + { + uint16_t source_id, client_id, pasid, vmid; +- uint32_t context_id; ++ uint32_t context_id0, context_id1; + + source_id = SOC15_SOURCE_ID_FROM_IH_ENTRY(ih_ring_entry); + client_id = SOC15_CLIENT_ID_FROM_IH_ENTRY(ih_ring_entry); + pasid = SOC15_PASID_FROM_IH_ENTRY(ih_ring_entry); + vmid = SOC15_VMID_FROM_IH_ENTRY(ih_ring_entry); +- context_id = SOC15_CONTEXT_ID0_FROM_IH_ENTRY(ih_ring_entry); ++ context_id0 = SOC15_CONTEXT_ID0_FROM_IH_ENTRY(ih_ring_entry); ++ context_id1 = SOC15_CONTEXT_ID1_FROM_IH_ENTRY(ih_ring_entry); + + if (source_id == SOC15_INTSRC_CP_END_OF_PIPE) +- kfd_signal_event_interrupt(pasid, context_id, 32); ++ kfd_signal_event_interrupt(pasid, context_id0, 32); + else if (source_id == SOC15_INTSRC_SDMA_TRAP) +- kfd_signal_event_interrupt(pasid, context_id & 0xfffffff, 28); +- else if (source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG) +- kfd_signal_event_interrupt(pasid, context_id & 0xffffff, 24); +- else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE) ++ kfd_signal_event_interrupt(pasid, context_id0 & 0xfffffff, 28); ++ else if (source_id == SOC15_INTSRC_SQ_INTERRUPT_MSG) { ++ if (context_id1 & KFD_CONTEXT_ID_DEBUG_TRAP_MASK) { ++ kfd_set_dbg_ev_from_interrupt(dev, pasid, ++ context_id0 & ++ KFD_CONTEXT_ID_DEBUG_DOORBELL_MASK, ++ false); ++ } else ++ kfd_signal_event_interrupt(pasid, ++ context_id0 & 0xffffff, 24); ++ } else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE) + kfd_signal_hw_exception_event(pasid); + else if (client_id == SOC15_IH_CLIENTID_VMC || + client_id == SOC15_IH_CLIENTID_VMC1 || +@@ -118,6 +130,7 @@ static void event_interrupt_wq_v9(struct kfd_dev *dev, + info.prot_read = ring_id & 0x10; + info.prot_write = ring_id & 0x20; + ++ kfd_set_dbg_ev_from_interrupt(dev, pasid, -1, true); + kfd_process_vm_fault(dev->dqm, pasid); + kfd_signal_vm_fault_event(dev, pasid, &info); + } +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +index 40c2b0d5a954..73aa6a3330eb 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +@@ -510,6 +510,7 @@ struct queue_properties { + /* Relevant for CU */ + uint32_t cu_mask_count; /* Must be a multiple of 32 */ + uint32_t *cu_mask; ++ unsigned int debug_event_type; + }; + + #define QUEUE_IS_ACTIVE(q) ((q).queue_size > 0 && \ +@@ -696,6 +697,13 @@ enum kfd_pdd_bound { + PDD_BOUND_SUSPENDED, + }; + ++struct kfd_debug_process_device { ++ struct kfifo fifo; ++ wait_queue_head_t wait_queue; ++ int max_debug_events; ++}; ++ ++ + /* Data that is per-process-per device. */ + struct kfd_process_device { + /* +@@ -710,6 +718,9 @@ struct kfd_process_device { + /* The process that owns this kfd_process_device. */ + struct kfd_process *process; + ++ /* per-process-per device debug event info */ ++ struct kfd_debug_process_device dpd; ++ + /* per-process-per device QCM data structure */ + struct qcm_process_device qpd; + +diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h +index 8c2862565444..617c07047d55 100644 +--- a/include/uapi/linux/kfd_ioctl.h ++++ b/include/uapi/linux/kfd_ioctl.h +@@ -187,11 +187,19 @@ struct kfd_ioctl_dbg_wave_control_args { + __u32 buf_size_in_bytes; /*including gpu_id and buf_size */ + }; + ++/* mapping event types to API spec */ ++#define KFD_DBG_EV_STATUS_TRAP 1 ++#define KFD_DBG_EV_STATUS_VMFAULT 2 ++#define KFD_DBG_EV_STATUS_SUSPENDED 4 ++#define KFD_DBG_EV_FLAG_CLEAR_STATUS 1 ++ ++#define KFD_INVALID_QUEUEID 0xffffffff ++ + /* KFD_IOC_DBG_TRAP_ENABLE: + * ptr: unused + * data1: 0=disable, 1=enable + * data2: queue ID (for future use) +- * data3: unused ++ * data3: return value for fd + */ + #define KFD_IOC_DBG_TRAP_ENABLE 0 + +@@ -235,6 +243,14 @@ struct kfd_ioctl_dbg_wave_control_args { + */ + #define KFD_IOC_DBG_TRAP_NODE_RESUME 5 + ++/* KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT: ++ * ptr: unused ++ * data1: queue id (IN/OUT) ++ * data2: flags (IN) ++ * data3: suspend[2:2], event type [1:0] (OUT) ++ */ ++#define KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT 6 ++ + struct kfd_ioctl_dbg_trap_args { + __u64 ptr; /* to KFD -- used for pointer arguments: queue arrays */ + __u32 pid; /* to KFD */ +@@ -657,6 +673,9 @@ struct kfd_ioctl_cross_memory_copy_args { + #define AMDKFD_IOC_IPC_EXPORT_HANDLE \ + AMDKFD_IOWR(0x20, struct kfd_ioctl_ipc_export_handle_args) + ++#define AMDKFD_IOC_DBG_TRAP \ ++ AMDKFD_IOWR(0x21, struct kfd_ioctl_dbg_trap_args) ++ + #define AMDKFD_IOC_CROSS_MEMORY_COPY \ + AMDKFD_IOWR(0x22, struct kfd_ioctl_cross_memory_copy_args) + +-- +2.17.1 + |