drm/prime: proper locking+refcounting for obj->dma_buf link
The export dma-buf cache is semantically similar to an flink name. So semantically it makes sense to treat it the same and remove the name (i.e. the dma_buf pointer) and its references when the last gem handle disappears. Again we need to be careful, but double so: Not just could someone race and export with a gem close ioctl (so we need to recheck obj->handle_count again when assigning the new name), but multiple exports can also race against each another. This is prevented by holding the dev->object_name_lock across the entire section which touches obj->dma_buf. With the new scheme we also need to reinstate the obj->dma_buf link at import time (in case the only reference userspace has held in-between was through the dma-buf fd and not through any native gem handle). For simplicity we don't check whether it's a native object but unconditionally set up that link - with the new scheme of removing the obj->dma_buf reference when the last handle disappears we can do that. To make it clear that this is not just for exported buffers anymore als rename it from export_dma_buf to dma_buf. To make sure that now one can race a fd_to_handle or handle_to_fd with gem_close we use the same tricks as in flink of extending the dev->object_name_locking critical section. With this change we finally have a guaranteed 1:1 relationship (at least for native objects) between gem objects and dma-bufs, even accounting for races (which can happen since the dma-buf itself holds a reference while in-flight). This prevent igt/prime_self_import/export-vs-gem_close-race from Oopsing the kernel. There is still a leak though since the per-file priv dma-buf/handle cache handling is racy. That will be fixed in a later patch. v2: Remove the bogus dma_buf_put from the export_and_register_object failure path if we've raced with the handle count dropping to 0. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:

committed by
Dave Airlie

parent
20228c4478
commit
319c933c71
@@ -667,8 +667,16 @@ struct drm_gem_object {
|
||||
|
||||
void *driver_private;
|
||||
|
||||
/* dma buf exported from this GEM object */
|
||||
struct dma_buf *export_dma_buf;
|
||||
/**
|
||||
* dma_buf - dma buf associated with this GEM object
|
||||
*
|
||||
* Pointer to the dma-buf associated with this gem object (either
|
||||
* through importing or exporting). We break the resulting reference
|
||||
* loop when the last gem handle for this object is released.
|
||||
*
|
||||
* Protected by obj->object_name_lock
|
||||
*/
|
||||
struct dma_buf *dma_buf;
|
||||
|
||||
/**
|
||||
* import_attach - dma buf attachment backing this object
|
||||
|
Reference in New Issue
Block a user