diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-08-15 00:02:46 +0200 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-11-21 19:12:24 +0900 |
commit | 7f663e197afad44296b98c1e69c2ab28721ebe0b (patch) | |
tree | 148ad8668f7505216e94868846f4cb818805c87a /include | |
parent | e091ad0f24a0146820ab758a17f5915fec0ea747 (diff) | |
download | linux-3.10-7f663e197afad44296b98c1e69c2ab28721ebe0b.tar.gz linux-3.10-7f663e197afad44296b98c1e69c2ab28721ebe0b.tar.bz2 linux-3.10-7f663e197afad44296b98c1e69c2ab28721ebe0b.zip |
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>
Signed-off-by: Chanho Park <chanho61.park@samsung.com>
Conflicts:
drivers/gpu/drm/drm_gem.c
Change-Id: I915b0e73cedffa0ba358cf00510e19dccfcb4703
Diffstat (limited to 'include')
-rw-r--r-- | include/drm/drmP.h | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c3f97ada401..c124c9071f5 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -681,8 +681,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; /* dma buf attachment backing this object */ struct dma_buf_attachment *import_attach; |