diff options
author | Philip Yang <Philip.Yang@amd.com> | 2022-04-08 10:25:11 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2022-06-30 15:31:30 -0400 |
commit | 414e9f520e897818302a6b1729aa2dad8cc928ca (patch) | |
tree | 561dd9e0628342e32206655964bfdfa6e6fffed0 | |
parent | 46ae2af9a8aa168cbad69f21bb1426771339ac9a (diff) | |
download | lwn-414e9f520e897818302a6b1729aa2dad8cc928ca.tar.gz lwn-414e9f520e897818302a6b1729aa2dad8cc928ca.zip |
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>
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c | 14 |
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; } |