summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdkfd
diff options
context:
space:
mode:
authorPhilip Yang <Philip.Yang@amd.com>2022-04-08 10:25:11 -0400
committerAlex Deucher <alexander.deucher@amd.com>2022-06-30 15:31:30 -0400
commit414e9f520e897818302a6b1729aa2dad8cc928ca (patch)
tree561dd9e0628342e32206655964bfdfa6e6fffed0 /drivers/gpu/drm/amd/amdkfd
parent46ae2af9a8aa168cbad69f21bb1426771339ac9a (diff)
downloadlinux-414e9f520e897818302a6b1729aa2dad8cc928ca.tar.bz2
drm/amdkfd: Asynchronously free smi_client
The synchronize_rcu may take several ms, which noticeably slows down applications close SMI event handle. Use call_rcu to free client->fifo and client asynchronously and eliminate the synchronize_rcu call in the user thread. 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>
Diffstat (limited to 'drivers/gpu/drm/amd/amdkfd')
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
index e5896b7a16dd..0472b56de245 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c
@@ -38,6 +38,7 @@ struct kfd_smi_client {
uint64_t events;
struct kfd_dev *dev;
spinlock_t lock;
+ struct rcu_head rcu;
pid_t pid;
bool suser;
};
@@ -137,6 +138,14 @@ static ssize_t kfd_smi_ev_write(struct file *filep, const char __user *user,
return sizeof(events);
}
+static void kfd_smi_ev_client_free(struct rcu_head *p)
+{
+ struct kfd_smi_client *ev = container_of(p, struct kfd_smi_client, rcu);
+
+ kfifo_free(&ev->fifo);
+ kfree(ev);
+}
+
static int kfd_smi_ev_release(struct inode *inode, struct file *filep)
{
struct kfd_smi_client *client = filep->private_data;
@@ -146,10 +155,7 @@ static int kfd_smi_ev_release(struct inode *inode, struct file *filep)
list_del_rcu(&client->list);
spin_unlock(&dev->smi_lock);
- synchronize_rcu();
- kfifo_free(&client->fifo);
- kfree(client);
-
+ call_rcu(&client->rcu, kfd_smi_ev_client_free);
return 0;
}