]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amdkfd: Improve signal event slow path
authorPhilip Yang <Philip.Yang@amd.com>
Wed, 4 Dec 2024 22:49:08 +0000 (17:49 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 18 Dec 2024 17:39:07 +0000 (12:39 -0500)
If event slot is not signaled, kfd_signal_event_interrupt goes to slow
path to scan all event slots to find the signaled event, this is needed
for old ASICs that don't have the event ID or the event IDs are
incorrect in the IH payload.

There is case that GPU signal the same event twice, then driver process
the first event interrupt, set_event and event slot is auto-reset, then
for the second event interrupt, KFD goes to slow path as event is not
signaled, just drop the second event interrupt because the application
only need wakeup once.

Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdkfd/kfd_events.c

index ea37922492093534d4018be7f6c28fe48b50d10b..d075f24e5f9f39aff4d3d82d351e4d5fc4377e86 100644 (file)
@@ -748,6 +748,16 @@ void kfd_signal_event_interrupt(u32 pasid, uint32_t partial_id,
                uint64_t *slots = page_slots(p->signal_page);
                uint32_t id;
 
+               /*
+                * If id is valid but slot is not signaled, GPU may signal the same event twice
+                * before driver have chance to process the first interrupt, then signal slot is
+                * auto-reset after set_event wakeup the user space, just drop the second event as
+                * the application only need wakeup once.
+                */
+               if ((valid_id_bits > 31 || (1U << valid_id_bits) >= KFD_SIGNAL_EVENT_LIMIT) &&
+                   partial_id < KFD_SIGNAL_EVENT_LIMIT && slots[partial_id] == UNSIGNALED_EVENT_SLOT)
+                       goto out_unlock;
+
                if (valid_id_bits)
                        pr_debug_ratelimited("Partial ID invalid: %u (%u valid bits)\n",
                                             partial_id, valid_id_bits);
@@ -776,6 +786,7 @@ void kfd_signal_event_interrupt(u32 pasid, uint32_t partial_id,
                }
        }
 
+out_unlock:
        rcu_read_unlock();
        kfd_unref_process(p);
 }