[PATCH] drm/amdkfd: fix race condition in kfd_wait_on_events

Felix Kuehling Felix.Kuehling at amd.com
Tue Apr 12 21:58:53 UTC 2022


Add the waiters to the wait queue during initialization, while holding the
event spinlock. Otherwise the waiter will not get activated if the event
signals before being added to the wait queue.

Signed-off-by: Felix Kuehling <Felix.Kuehling at amd.com>
---
 drivers/gpu/drm/amd/amdkfd/kfd_events.c | 26 +++++--------------------
 1 file changed, 5 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index e43bb14adfca..ca562b9a8abe 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -784,7 +784,7 @@ static struct kfd_event_waiter *alloc_event_waiters(uint32_t num_events)
 	return event_waiters;
 }
 
-static int init_event_waiter_get_status(struct kfd_process *p,
+static int init_event_waiter(struct kfd_process *p,
 		struct kfd_event_waiter *waiter,
 		uint32_t event_id)
 {
@@ -797,25 +797,13 @@ static int init_event_waiter_get_status(struct kfd_process *p,
 	waiter->event = ev;
 	waiter->activated = ev->signaled;
 	ev->signaled = ev->signaled && !ev->auto_reset;
+	if (!waiter->activated)
+		add_wait_queue(&ev->wq, &waiter->wait);
 	spin_unlock(&ev->lock);
 
 	return 0;
 }
 
-static void init_event_waiter_add_to_waitlist(struct kfd_event_waiter *waiter)
-{
-	struct kfd_event *ev = waiter->event;
-
-	/* Only add to the wait list if we actually need to
-	 * wait on this event.
-	 */
-	if (!waiter->activated) {
-		spin_lock(&ev->lock);
-		add_wait_queue(&ev->wq, &waiter->wait);
-		spin_unlock(&ev->lock);
-	}
-}
-
 /* test_event_condition - Test condition of events being waited for
  * @all:           Return completion only if all events have signaled
  * @num_events:    Number of events to wait for
@@ -945,8 +933,8 @@ int kfd_wait_on_events(struct kfd_process *p,
 			goto out_unlock;
 		}
 
-		ret = init_event_waiter_get_status(p, &event_waiters[i],
-				event_data.event_id);
+		ret = init_event_waiter(p, &event_waiters[i],
+					event_data.event_id);
 		if (ret)
 			goto out_unlock;
 	}
@@ -964,10 +952,6 @@ int kfd_wait_on_events(struct kfd_process *p,
 		goto out_unlock;
 	}
 
-	/* Add to wait lists if we need to wait. */
-	for (i = 0; i < num_events; i++)
-		init_event_waiter_add_to_waitlist(&event_waiters[i]);
-
 	mutex_unlock(&p->event_mutex);
 
 	while (true) {
-- 
2.32.0



More information about the amd-gfx mailing list