diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3780-drm-amdkfd-add-queue-snapshot.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3780-drm-amdkfd-add-queue-snapshot.patch | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3780-drm-amdkfd-add-queue-snapshot.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3780-drm-amdkfd-add-queue-snapshot.patch new file mode 100644 index 00000000..e0e75e7d --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3780-drm-amdkfd-add-queue-snapshot.patch @@ -0,0 +1,311 @@ +From ffcec3477d42f38d9f4b1ed0da69bf9880931070 Mon Sep 17 00:00:00 2001 +From: Jonathan Kim <jonathan.kim@amd.com> +Date: Tue, 27 Aug 2019 15:14:51 -0400 +Subject: [PATCH 3780/4256] drm/amdkfd: add queue snapshot + +update ioctl call to get queue snapshot per process + +Change-Id: I827e8dd4e570e31e01c775b24949b0d2aeb6d9b4 +Signed-off-by: Jonathan Kim <jonathan.kim@amd.com> +Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> +--- + drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 12 ++++- + drivers/gpu/drm/amd/amdkfd/kfd_debug_events.c | 45 ++++++++++--------- + drivers/gpu/drm/amd/amdkfd/kfd_debug_events.h | 2 + + .../drm/amd/amdkfd/kfd_device_queue_manager.c | 38 ++++++++++++++++ + .../drm/amd/amdkfd/kfd_device_queue_manager.h | 5 +++ + drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 5 +++ + .../amd/amdkfd/kfd_process_queue_manager.c | 36 +++++++++++++++ + include/uapi/linux/kfd_ioctl.h | 21 +++++++++ + 8 files changed, 142 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +index 44a9803f26f3..547e7f511775 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +@@ -2628,7 +2628,6 @@ static int kfd_ioctl_dbg_set_debug_trap(struct file *filep, + debug_trap_action == KFD_IOC_DBG_TRAP_NODE_SUSPEND || + debug_trap_action == KFD_IOC_DBG_TRAP_NODE_RESUME; + +- + pid = find_get_pid(args->pid); + if (!pid) { + pr_err("Cannot find pid info for %i\n", +@@ -2801,6 +2800,17 @@ static int kfd_ioctl_dbg_set_debug_trap(struct file *filep, + args->data2, + &args->data3); + break; ++ case KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT: ++ r = pqm_get_queue_snapshot(&p->pqm, args->data1, ++ (void __user *)args->ptr, ++ args->data2); ++ ++ if (r > 0) { ++ args->data2 = r; ++ r = 0; ++ } ++ ++ 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 +index 1681107a2aa6..5433b6527bae 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug_events.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug_events.c +@@ -101,6 +101,25 @@ static int kfd_dbg_ev_release(struct inode *inode, struct file *filep) + ((x) = (n) ? (x) | KFD_DBG_EV_STATUS_NEW_QUEUE : \ + (x) & ~KFD_DBG_EV_STATUS_NEW_QUEUE) + ++uint32_t kfd_dbg_get_queue_status_word(struct queue *q, int flags) ++{ ++ uint32_t queue_status_word = 0; ++ ++ KFD_DBG_EV_SET_EVENT_TYPE(queue_status_word, ++ q->properties.debug_event_type); ++ KFD_DBG_EV_SET_SUSPEND_STATE(queue_status_word, ++ q->properties.is_suspended); ++ KFD_DBG_EV_SET_NEW_QUEUE_STATE(queue_status_word, ++ q->properties.is_new); ++ ++ if (flags & KFD_DBG_EV_FLAG_CLEAR_STATUS) { ++ q->properties.is_new = false; ++ q->properties.debug_event_type = 0; ++ } ++ ++ return queue_status_word; ++} ++ + int kfd_dbg_ev_query_debug_event(struct kfd_process_device *pdd, + unsigned int *queue_id, + unsigned int flags, +@@ -126,16 +145,8 @@ int kfd_dbg_ev_query_debug_event(struct kfd_process_device *pdd, + 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); +- KFD_DBG_EV_SET_NEW_QUEUE_STATE(*event_status, +- q->properties.is_new); +- if (flags & KFD_DBG_EV_FLAG_CLEAR_STATUS) { +- q->properties.is_new = false; +- q->properties.debug_event_type = 0; +- } ++ *event_status = kfd_dbg_get_queue_status_word(q, flags); ++ + goto out; + + } else { +@@ -146,17 +157,9 @@ int kfd_dbg_ev_query_debug_event(struct kfd_process_device *pdd, + || 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); +- KFD_DBG_EV_SET_NEW_QUEUE_STATE(*event_status, +- pqn->q->properties.is_new); +- if (flags & KFD_DBG_EV_FLAG_CLEAR_STATUS) { +- pqn->q->properties.is_new = false; +- pqn->q->properties.debug_event_type +- = 0; +- } ++ *event_status = ++ kfd_dbg_get_queue_status_word(pqn->q, ++ flags); + goto out; + } + } +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug_events.h b/drivers/gpu/drm/amd/amdkfd/kfd_debug_events.h +index 5b035a4321c6..49ccf8b2b66c 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_debug_events.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug_events.h +@@ -25,6 +25,8 @@ + + #include "kfd_priv.h" + ++uint32_t kfd_dbg_get_queue_status_word(struct queue *q, int flags); ++ + int kfd_dbg_ev_query_debug_event(struct kfd_process_device *pdd, + unsigned int *queue_id, + unsigned int flags, +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 83cddab4d482..dbcbacb5abd4 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +@@ -35,6 +35,7 @@ + #include "cik_regs.h" + #include "kfd_kernel_queue.h" + #include "amdgpu_amdkfd.h" ++#include "kfd_debug_events.h" + + /* Size of the per-pipe EOP queue */ + #define CIK_HPD_EOP_BYTES_LOG2 11 +@@ -2234,6 +2235,43 @@ int resume_queues(struct kfd_process *p, + return r; + } + ++static uint32_t set_queue_type_for_user(struct queue_properties *q_props) ++{ ++ switch (q_props->type) { ++ case KFD_QUEUE_TYPE_COMPUTE: ++ return q_props->format == KFD_QUEUE_FORMAT_PM4 ++ ? KFD_IOC_QUEUE_TYPE_COMPUTE ++ : KFD_IOC_QUEUE_TYPE_COMPUTE_AQL; ++ case KFD_QUEUE_TYPE_SDMA: ++ return KFD_IOC_QUEUE_TYPE_SDMA; ++ case KFD_QUEUE_TYPE_SDMA_XGMI: ++ return KFD_IOC_QUEUE_TYPE_SDMA_XGMI; ++ default: ++ WARN_ONCE(true, "queue type not recognized!"); ++ return 0xffffffff; ++ }; ++} ++ ++void set_queue_snapshot_entry(struct device_queue_manager *dqm, ++ struct queue *q, ++ int flags, ++ struct kfd_queue_snapshot_entry *qss_entry) ++{ ++ dqm_lock(dqm); ++ ++ qss_entry->ring_base_address = q->properties.queue_address, ++ qss_entry->write_pointer_address = (uint64_t)q->properties.write_ptr; ++ qss_entry->read_pointer_address = (uint64_t)q->properties.read_ptr, ++ qss_entry->ctx_save_restore_address = ++ q->properties.ctx_save_restore_area_address; ++ qss_entry->queue_id = q->properties.queue_id; ++ qss_entry->gpu_id = q->device->id; ++ qss_entry->ring_size = (uint32_t)q->properties.queue_size; ++ qss_entry->queue_type = set_queue_type_for_user(&q->properties); ++ qss_entry->queue_status = kfd_dbg_get_queue_status_word(q, flags); ++ ++ dqm_unlock(dqm); ++} + + #if defined(CONFIG_DEBUG_FS) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +index fcab7ad80512..54f4fad61359 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +@@ -237,6 +237,11 @@ int resume_queues(struct kfd_process *p, + uint32_t flags, + uint32_t *queue_ids); + ++void set_queue_snapshot_entry(struct device_queue_manager *dqm, ++ struct queue *q, ++ int flags, ++ struct kfd_queue_snapshot_entry *qss_entry); ++ + static inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd) + { + return (pdd->lds_base >> 16) & 0xFF; +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +index 5d3cffc9d0ec..b0965eaa327e 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +@@ -1055,6 +1055,11 @@ int pqm_get_wave_state(struct process_queue_manager *pqm, + u32 *ctl_stack_used_size, + u32 *save_area_used_size); + ++int pqm_get_queue_snapshot(struct process_queue_manager *pqm, ++ int flags, ++ struct kfd_queue_snapshot_entry __user *buf, ++ int num_qss_entries); ++ + int amdkfd_fence_wait_timeout(unsigned int *fence_addr, + unsigned int fence_value, + unsigned int timeout_ms); +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 d47ab53d613b..a594945097a3 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +@@ -505,6 +505,42 @@ int pqm_get_wave_state(struct process_queue_manager *pqm, + save_area_used_size); + } + ++int pqm_get_queue_snapshot(struct process_queue_manager *pqm, ++ int flags, ++ struct kfd_queue_snapshot_entry __user *buf, ++ int num_qss_entries) ++{ ++ struct process_queue_node *pqn; ++ int r, qss_entry_count = 0; ++ ++ mutex_lock(&pqm->process->event_mutex); ++ ++ list_for_each_entry(pqn, &pqm->queues, process_queue_list) { ++ if (!pqn->q) ++ continue; ++ ++ if (qss_entry_count < num_qss_entries) { ++ ++ struct kfd_queue_snapshot_entry src = {0}; ++ ++ set_queue_snapshot_entry(pqn->q->device->dqm, ++ pqn->q, flags, &src); ++ ++ r = copy_to_user(buf++, &src, sizeof(src)); ++ ++ if (r) { ++ qss_entry_count = -EFAULT; ++ goto unlock; ++ } ++ } ++ ++ qss_entry_count++; ++ } ++unlock: ++ mutex_unlock(&pqm->process->event_mutex); ++ return qss_entry_count; ++} ++ + #if defined(CONFIG_DEBUG_FS) + + int pqm_debugfs_mqds(struct seq_file *m, void *data) +diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h +index 86805463e1d3..be91603f2c0f 100644 +--- a/include/uapi/linux/kfd_ioctl.h ++++ b/include/uapi/linux/kfd_ioctl.h +@@ -91,6 +91,19 @@ struct kfd_ioctl_get_queue_wave_state_args { + __u32 pad; + }; + ++struct kfd_queue_snapshot_entry { ++ __u64 ring_base_address; ++ __u64 write_pointer_address; ++ __u64 read_pointer_address; ++ __u64 ctx_save_restore_address; ++ __u32 queue_id; ++ __u32 gpu_id; ++ __u32 ring_size; ++ __u32 queue_type; ++ __u32 queue_status; ++ __u32 reserved[19]; ++}; ++ + /* For kfd_ioctl_set_memory_policy_args.default_policy and alternate_policy */ + #define KFD_IOC_CACHE_POLICY_COHERENT 0 + #define KFD_IOC_CACHE_POLICY_NONCOHERENT 1 +@@ -252,6 +265,14 @@ struct kfd_ioctl_dbg_wave_control_args { + */ + #define KFD_IOC_DBG_TRAP_QUERY_DEBUG_EVENT 6 + ++/* KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT: ++ * ptr: user buffer (IN) ++ * data1: flags (IN) ++ * data2: number of queue snapshots (IN/OUT) - 0 for IN ignores buffer writes ++ * data3: unused ++ */ ++#define KFD_IOC_DBG_TRAP_GET_QUEUE_SNAPSHOT 7 ++ + struct kfd_ioctl_dbg_trap_args { + __u64 ptr; /* to KFD -- used for pointer arguments: queue arrays */ + __u32 pid; /* to KFD */ +-- +2.17.1 + |