aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/2770-drm-amdkfd-Temporary-hack-to-enable-notification-to-.patch
blob: f8dcc07c436ac1e158f3c41382916485616aea89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
From 2edeed47d5e38a3f54e5040812196bef4aca4be5 Mon Sep 17 00:00:00 2001
From: Felix Kuehling <Felix.Kuehling@amd.com>
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 <Felix.Kuehling@amd.com>
---
 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 <linux/device.h>
+#include <linux/ptrace.h>
 
 /*
  * 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