From 2edeed47d5e38a3f54e5040812196bef4aca4be5 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Thu, 2 May 2019 16:38:31 -0400 Subject: [PATCH 2770/2940] drm/amdkfd: Temporary hack to enable notification to debugger Send SIGUSR2 to the debugger when events signal in the debugged process. This change will be reverted once the real debugger notification mechanism is implemented. Change-Id: If5b55ec1fd3b5e46b189de831b3ab6bbf4a7fe3e Signed-off-by: Felix Kuehling --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 40 ++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index b5a7b6bb4a60..ab76749bf44e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -32,6 +32,7 @@ #include "kfd_events.h" #include "kfd_iommu.h" #include +#include /* * Wrapper around wait_queue_entry_t @@ -452,6 +453,36 @@ static void acknowledge_signal(struct kfd_process *p, struct kfd_event *ev) page_slots(p->signal_page)[ev->event_id] = UNSIGNALED_EVENT_SLOT; } +/* HACK: Temporary hack to enable signaling to debuggers running in a + * separate process. Remove this when the real signaling mechanism is + * implemented. + */ +static void signal_event_to_debugger(struct kfd_process *p) +{ + struct kfd_process_device *pdd; + struct task_struct *tracer; + + /* Check that a debugger is attached to the process */ + rcu_read_lock(); + tracer = ptrace_parent(p->lead_thread); + if (tracer) + get_task_struct(tracer); + rcu_read_unlock(); + if (!tracer) + return; + + /* Check that GPU debugging is enabled for at least one device + * for this process + */ + list_for_each_entry(pdd, &p->per_device_data, per_device_list) + if (pdd->is_debugging_enabled) { + send_sig(SIGUSR2, tracer, 0); + break; + } + + put_task_struct(tracer); +} + static void set_event_from_interrupt(struct kfd_process *p, struct kfd_event *ev) { @@ -464,6 +495,7 @@ static void set_event_from_interrupt(struct kfd_process *p, void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id, uint32_t valid_id_bits) { + bool events_signaled = false; struct kfd_event *ev = NULL; /* @@ -483,6 +515,7 @@ void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id, valid_id_bits); if (ev) { set_event_from_interrupt(p, ev); + events_signaled = true; } else if (p->signal_page) { /* * Partial ID lookup failed. Assume that the event ID @@ -504,8 +537,10 @@ void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id, if (id >= KFD_SIGNAL_EVENT_LIMIT) break; - if (slots[id] != UNSIGNALED_EVENT_SLOT) + if (slots[id] != UNSIGNALED_EVENT_SLOT) { set_event_from_interrupt(p, ev); + events_signaled = true; + } } } else { /* With relatively many events, it's faster to @@ -516,9 +551,12 @@ void kfd_signal_event_interrupt(unsigned int pasid, uint32_t partial_id, if (slots[id] != UNSIGNALED_EVENT_SLOT) { ev = lookup_event_by_id(p, id); set_event_from_interrupt(p, ev); + events_signaled = true; } } } + if (events_signaled) + signal_event_to_debugger(p); mutex_unlock(&p->event_mutex); kfd_unref_process(p); -- 2.17.1