Relax the spinlock used for looking up the handle in the XArray and acquiring a reference to it to an RCU protected critical section. This incurs the requirement that we protect the syncobj struct itself using RCU, which we achieve by simply calling kfree_rcu() and being more careful in acquiring our reference. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Daniel Vetter <daniel.vetter@xxxxxxxx> --- drivers/gpu/drm/drm_syncobj.c | 12 +++++------- include/drm/drm_syncobj.h | 2 ++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 4fc71dc9fc43..aafc03986a48 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -86,13 +86,11 @@ struct drm_syncobj *drm_syncobj_find(struct drm_file *file_private, { struct drm_syncobj *syncobj; - xa_lock(&file_private->syncobjs); - + rcu_read_lock(); syncobj = xa_load(&file_private->syncobjs, handle); - if (syncobj) - drm_syncobj_get(syncobj); - - xa_unlock(&file_private->syncobjs); + if (syncobj && !kref_get_unless_zero(&syncobj->refcount)) + syncobj = NULL; + rcu_read_unlock(); return syncobj; } @@ -309,7 +307,7 @@ void drm_syncobj_free(struct kref *kref) struct drm_syncobj, refcount); drm_syncobj_replace_fence(syncobj, NULL); - kfree(syncobj); + kfree_rcu(syncobj, rcu); } EXPORT_SYMBOL(drm_syncobj_free); diff --git a/include/drm/drm_syncobj.h b/include/drm/drm_syncobj.h index 6cf7243a1dc5..7c1503d47abf 100644 --- a/include/drm/drm_syncobj.h +++ b/include/drm/drm_syncobj.h @@ -61,6 +61,8 @@ struct drm_syncobj { * @file: A file backing for this syncobj. */ struct file *file; + + struct rcu_head rcu; }; void drm_syncobj_free(struct kref *kref); -- 2.23.0.rc0 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel