2011-11-25 19:21:02 +04:00
/*
* Copyright © 2012 Red Hat
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice ( including the next
* paragraph ) shall be included in all copies or substantial portions of the
* Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING
* FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE .
*
* Authors :
* Dave Airlie < airlied @ redhat . com >
* Rob Clark < rob . clark @ linaro . org >
*
*/
# include <linux/export.h>
# include <linux/dma-buf.h>
2016-09-26 23:44:14 +03:00
# include <linux/rbtree.h>
2017-03-08 17:12:35 +03:00
# include <drm/drm_prime.h>
2014-09-23 17:46:53 +04:00
# include <drm/drm_gem.h>
2017-03-08 17:12:35 +03:00
# include <drm/drmP.h>
2014-09-23 17:46:53 +04:00
2014-09-10 14:43:53 +04:00
# include "drm_internal.h"
2011-11-25 19:21:02 +04:00
/*
* DMA - BUF / GEM Object references and lifetime overview :
*
* On the export the dma_buf holds a reference to the exporting GEM
* object . It takes this reference in handle_to_fd_ioctl , when it
* first calls . prime_export and stores the exporting GEM object in
2017-01-27 10:04:25 +03:00
* the dma_buf priv . This reference needs to be released when the
* final reference to the & dma_buf itself is dropped and its
* & dma_buf_ops . release function is called . For GEM - based drivers ,
* the dma_buf should be exported using drm_gem_dmabuf_export ( ) and
* then released by drm_gem_dmabuf_release ( ) .
2011-11-25 19:21:02 +04:00
*
* On the import the importing GEM object holds a reference to the
* dma_buf ( which in turn holds a ref to the exporting GEM object ) .
* It takes that reference in the fd_to_handle ioctl .
* It calls dma_buf_get , creates an attachment to it and stores the
* attachment in the GEM object . When this attachment is destroyed
* when the imported object is destroyed , we remove the attachment
* and drop the reference to the dma_buf .
*
2017-01-27 10:04:25 +03:00
* When all the references to the & dma_buf are dropped , i . e . when
* userspace has closed both handles to the imported GEM object ( through the
* FD_TO_HANDLE IOCTL ) and closed the file descriptor of the exported
* ( through the HANDLE_TO_FD IOCTL ) dma_buf , and all kernel - internal references
* are also gone , then the dma_buf gets destroyed . This can also happen as a
* part of the clean up procedure in the drm_release ( ) function if userspace
* fails to properly clean up . Note that both the kernel and userspace ( by
* keeeping the PRIME file descriptors open ) can hold references onto a
* & dma_buf .
*
2011-11-25 19:21:02 +04:00
* Thus the chain of references always flows in one direction
* ( avoiding loops ) : importing_gem - > dmabuf - > exporting_gem
*
* Self - importing : if userspace is using PRIME as a replacement for flink
* then it will get a fd - > handle request for a GEM object that it created .
* Drivers should detect this situation and return back the gem object
2013-01-16 00:47:42 +04:00
* from the dma - buf private . Prime will do this automatically for drivers that
* use the drm_gem_prime_ { import , export } helpers .
2018-01-19 00:44:20 +03:00
*
* GEM struct & dma_buf_ops symbols are now exported . They can be resued by
* drivers which implement GEM interface .
2011-11-25 19:21:02 +04:00
*/
struct drm_prime_member {
struct dma_buf * dma_buf ;
uint32_t handle ;
2016-09-26 23:44:14 +03:00
struct rb_node dmabuf_rb ;
struct rb_node handle_rb ;
2011-11-25 19:21:02 +04:00
} ;
2013-06-19 10:03:05 +04:00
struct drm_prime_attachment {
struct sg_table * sgt ;
enum dma_data_direction dir ;
} ;
2014-01-22 22:16:30 +04:00
static int drm_prime_add_buf_handle ( struct drm_prime_file_private * prime_fpriv ,
struct dma_buf * dma_buf , uint32_t handle )
2013-06-26 05:21:41 +04:00
{
struct drm_prime_member * member ;
2016-09-26 23:44:14 +03:00
struct rb_node * * p , * rb ;
2013-06-26 05:21:41 +04:00
member = kmalloc ( sizeof ( * member ) , GFP_KERNEL ) ;
if ( ! member )
return - ENOMEM ;
get_dma_buf ( dma_buf ) ;
member - > dma_buf = dma_buf ;
member - > handle = handle ;
2016-09-26 23:44:14 +03:00
rb = NULL ;
p = & prime_fpriv - > dmabufs . rb_node ;
while ( * p ) {
struct drm_prime_member * pos ;
rb = * p ;
pos = rb_entry ( rb , struct drm_prime_member , dmabuf_rb ) ;
if ( dma_buf > pos - > dma_buf )
p = & rb - > rb_right ;
else
p = & rb - > rb_left ;
}
rb_link_node ( & member - > dmabuf_rb , rb , p ) ;
rb_insert_color ( & member - > dmabuf_rb , & prime_fpriv - > dmabufs ) ;
rb = NULL ;
p = & prime_fpriv - > handles . rb_node ;
while ( * p ) {
struct drm_prime_member * pos ;
rb = * p ;
pos = rb_entry ( rb , struct drm_prime_member , handle_rb ) ;
if ( handle > pos - > handle )
p = & rb - > rb_right ;
else
p = & rb - > rb_left ;
}
rb_link_node ( & member - > handle_rb , rb , p ) ;
rb_insert_color ( & member - > handle_rb , & prime_fpriv - > handles ) ;
2013-06-26 05:21:41 +04:00
return 0 ;
}
2011-11-25 19:21:02 +04:00
2013-08-15 02:02:49 +04:00
static struct dma_buf * drm_prime_lookup_buf_by_handle ( struct drm_prime_file_private * prime_fpriv ,
uint32_t handle )
{
2016-09-26 23:44:14 +03:00
struct rb_node * rb ;
rb = prime_fpriv - > handles . rb_node ;
while ( rb ) {
struct drm_prime_member * member ;
2013-08-15 02:02:49 +04:00
2016-09-26 23:44:14 +03:00
member = rb_entry ( rb , struct drm_prime_member , handle_rb ) ;
2013-08-15 02:02:49 +04:00
if ( member - > handle = = handle )
return member - > dma_buf ;
2016-09-26 23:44:14 +03:00
else if ( member - > handle < handle )
rb = rb - > rb_right ;
else
rb = rb - > rb_left ;
2013-08-15 02:02:49 +04:00
}
return NULL ;
}
2013-08-15 02:02:48 +04:00
static int drm_prime_lookup_buf_handle ( struct drm_prime_file_private * prime_fpriv ,
struct dma_buf * dma_buf ,
uint32_t * handle )
{
2016-09-26 23:44:14 +03:00
struct rb_node * rb ;
rb = prime_fpriv - > dmabufs . rb_node ;
while ( rb ) {
struct drm_prime_member * member ;
2013-08-15 02:02:48 +04:00
2016-09-26 23:44:14 +03:00
member = rb_entry ( rb , struct drm_prime_member , dmabuf_rb ) ;
2013-08-15 02:02:48 +04:00
if ( member - > dma_buf = = dma_buf ) {
* handle = member - > handle ;
return 0 ;
2016-09-26 23:44:14 +03:00
} else if ( member - > dma_buf < dma_buf ) {
rb = rb - > rb_right ;
} else {
rb = rb - > rb_left ;
2013-08-15 02:02:48 +04:00
}
}
2016-09-26 23:44:14 +03:00
2013-08-15 02:02:48 +04:00
return - ENOENT ;
}
2018-01-19 00:44:20 +03:00
/**
* drm_gem_map_attach - dma_buf attach implementation for GEM
* @ dma_buf : buffer to attach device to
* @ attach : buffer attachment data
*
* Allocates & drm_prime_attachment and calls & drm_driver . gem_prime_pin for
* device specific attachment . This can be used as the & dma_buf_ops . attach
* callback .
*
* Returns 0 on success , negative error code on failure .
*/
2018-05-28 12:47:52 +03:00
int drm_gem_map_attach ( struct dma_buf * dma_buf ,
2018-01-05 00:12:14 +03:00
struct dma_buf_attachment * attach )
2013-04-09 11:52:54 +04:00
{
2013-06-19 10:03:05 +04:00
struct drm_prime_attachment * prime_attach ;
2013-04-09 11:52:54 +04:00
struct drm_gem_object * obj = dma_buf - > priv ;
struct drm_device * dev = obj - > dev ;
2013-06-19 10:03:05 +04:00
prime_attach = kzalloc ( sizeof ( * prime_attach ) , GFP_KERNEL ) ;
if ( ! prime_attach )
return - ENOMEM ;
prime_attach - > dir = DMA_NONE ;
attach - > priv = prime_attach ;
2013-04-09 11:52:54 +04:00
if ( ! dev - > driver - > gem_prime_pin )
return 0 ;
return dev - > driver - > gem_prime_pin ( obj ) ;
}
2018-01-05 00:12:14 +03:00
EXPORT_SYMBOL ( drm_gem_map_attach ) ;
2013-04-09 11:52:54 +04:00
2018-01-19 00:44:20 +03:00
/**
* drm_gem_map_detach - dma_buf detach implementation for GEM
* @ dma_buf : buffer to detach from
* @ attach : attachment to be detached
*
* Cleans up & dma_buf_attachment . This can be used as the & dma_buf_ops . detach
* callback .
*/
2018-01-05 00:12:14 +03:00
void drm_gem_map_detach ( struct dma_buf * dma_buf ,
struct dma_buf_attachment * attach )
2013-04-09 11:52:54 +04:00
{
2013-06-19 10:03:05 +04:00
struct drm_prime_attachment * prime_attach = attach - > priv ;
2013-04-09 11:52:54 +04:00
struct drm_gem_object * obj = dma_buf - > priv ;
struct drm_device * dev = obj - > dev ;
2018-02-27 14:49:56 +03:00
if ( prime_attach ) {
struct sg_table * sgt = prime_attach - > sgt ;
2013-06-19 10:03:05 +04:00
2018-02-27 14:49:56 +03:00
if ( sgt ) {
if ( prime_attach - > dir ! = DMA_NONE )
dma_unmap_sg_attrs ( attach - > dev , sgt - > sgl ,
sgt - > nents ,
prime_attach - > dir ,
DMA_ATTR_SKIP_CPU_SYNC ) ;
sg_free_table ( sgt ) ;
}
kfree ( sgt ) ;
kfree ( prime_attach ) ;
attach - > priv = NULL ;
2013-07-04 11:19:12 +04:00
}
2013-06-19 10:03:05 +04:00
2018-02-27 14:49:56 +03:00
if ( dev - > driver - > gem_prime_unpin )
dev - > driver - > gem_prime_unpin ( obj ) ;
2013-04-09 11:52:54 +04:00
}
2018-01-05 00:12:14 +03:00
EXPORT_SYMBOL ( drm_gem_map_detach ) ;
2013-04-09 11:52:54 +04:00
2013-08-15 02:02:49 +04:00
void drm_prime_remove_buf_handle_locked ( struct drm_prime_file_private * prime_fpriv ,
struct dma_buf * dma_buf )
2013-06-26 05:21:42 +04:00
{
2016-09-26 23:44:14 +03:00
struct rb_node * rb ;
2013-06-26 05:21:42 +04:00
2016-09-26 23:44:14 +03:00
rb = prime_fpriv - > dmabufs . rb_node ;
while ( rb ) {
struct drm_prime_member * member ;
member = rb_entry ( rb , struct drm_prime_member , dmabuf_rb ) ;
2013-06-26 05:21:42 +04:00
if ( member - > dma_buf = = dma_buf ) {
2016-09-26 23:44:14 +03:00
rb_erase ( & member - > handle_rb , & prime_fpriv - > handles ) ;
rb_erase ( & member - > dmabuf_rb , & prime_fpriv - > dmabufs ) ;
2013-06-26 05:21:42 +04:00
dma_buf_put ( dma_buf ) ;
kfree ( member ) ;
2016-09-26 23:44:14 +03:00
return ;
} else if ( member - > dma_buf < dma_buf ) {
rb = rb - > rb_right ;
} else {
rb = rb - > rb_left ;
2013-06-26 05:21:42 +04:00
}
}
}
2018-01-19 00:44:20 +03:00
/**
* drm_gem_map_dma_buf - map_dma_buf implementation for GEM
* @ attach : attachment whose scatterlist is to be returned
* @ dir : direction of DMA transfer
*
* Calls & drm_driver . gem_prime_get_sg_table and then maps the scatterlist . This
* can be used as the & dma_buf_ops . map_dma_buf callback .
*
* Returns sg_table containing the scatterlist to be returned ; returns ERR_PTR
* on error . May return - EINTR if it is interrupted by a signal .
*/
2018-01-05 00:12:14 +03:00
struct sg_table * drm_gem_map_dma_buf ( struct dma_buf_attachment * attach ,
enum dma_data_direction dir )
2013-01-16 00:47:42 +04:00
{
2013-06-19 10:03:05 +04:00
struct drm_prime_attachment * prime_attach = attach - > priv ;
2013-01-16 00:47:42 +04:00
struct drm_gem_object * obj = attach - > dmabuf - > priv ;
struct sg_table * sgt ;
2013-06-19 10:03:05 +04:00
if ( WARN_ON ( dir = = DMA_NONE | | ! prime_attach ) )
return ERR_PTR ( - EINVAL ) ;
/* return the cached mapping when possible */
if ( prime_attach - > dir = = dir )
return prime_attach - > sgt ;
/*
* two mappings with different directions for the same attachment are
* not allowed
*/
if ( WARN_ON ( prime_attach - > dir ! = DMA_NONE ) )
return ERR_PTR ( - EBUSY ) ;
2013-01-16 00:47:42 +04:00
sgt = obj - > dev - > driver - > gem_prime_get_sg_table ( obj ) ;
2013-06-24 11:40:53 +04:00
if ( ! IS_ERR ( sgt ) ) {
2017-11-30 20:34:28 +03:00
if ( ! dma_map_sg_attrs ( attach - > dev , sgt - > sgl , sgt - > nents , dir ,
DMA_ATTR_SKIP_CPU_SYNC ) ) {
2013-06-24 10:34:21 +04:00
sg_free_table ( sgt ) ;
kfree ( sgt ) ;
sgt = ERR_PTR ( - ENOMEM ) ;
2013-06-19 10:03:05 +04:00
} else {
prime_attach - > sgt = sgt ;
prime_attach - > dir = dir ;
2013-06-24 10:34:21 +04:00
}
}
2013-01-16 00:47:42 +04:00
return sgt ;
}
2018-01-05 00:12:14 +03:00
EXPORT_SYMBOL ( drm_gem_map_dma_buf ) ;
2013-01-16 00:47:42 +04:00
2018-01-19 00:44:20 +03:00
/**
* drm_gem_unmap_dma_buf - unmap_dma_buf implementation for GEM
2018-03-26 22:22:25 +03:00
* @ attach : attachment to unmap buffer from
* @ sgt : scatterlist info of the buffer to unmap
* @ dir : direction of DMA transfer
2018-01-19 00:44:20 +03:00
*
* Not implemented . The unmap is done at drm_gem_map_detach ( ) . This can be
* used as the & dma_buf_ops . unmap_dma_buf callback .
*/
2018-01-05 00:12:14 +03:00
void drm_gem_unmap_dma_buf ( struct dma_buf_attachment * attach ,
struct sg_table * sgt ,
enum dma_data_direction dir )
2013-01-16 00:47:42 +04:00
{
2013-06-19 10:03:05 +04:00
/* nothing to be done here */
2013-01-16 00:47:42 +04:00
}
2018-01-05 00:12:14 +03:00
EXPORT_SYMBOL ( drm_gem_unmap_dma_buf ) ;
2013-01-16 00:47:42 +04:00
2016-10-05 15:21:44 +03:00
/**
* drm_gem_dmabuf_export - dma_buf export implementation for GEM
2016-10-05 20:40:56 +03:00
* @ dev : parent device for the exported dmabuf
* @ exp_info : the export information used by dma_buf_export ( )
2016-10-05 15:21:44 +03:00
*
* This wraps dma_buf_export ( ) for use by generic GEM drivers that are using
* drm_gem_dmabuf_release ( ) . In addition to calling dma_buf_export ( ) , we take
2016-12-08 00:45:27 +03:00
* a reference to the & drm_device and the exported & drm_gem_object ( stored in
2017-01-25 09:26:46 +03:00
* & dma_buf_export_info . priv ) which is released by drm_gem_dmabuf_release ( ) .
2016-10-05 15:21:44 +03:00
*
* Returns the new dmabuf .
*/
struct dma_buf * drm_gem_dmabuf_export ( struct drm_device * dev ,
struct dma_buf_export_info * exp_info )
{
struct dma_buf * dma_buf ;
dma_buf = dma_buf_export ( exp_info ) ;
2016-12-08 00:45:27 +03:00
if ( IS_ERR ( dma_buf ) )
return dma_buf ;
2017-09-26 11:28:49 +03:00
drm_dev_get ( dev ) ;
2017-02-28 17:46:41 +03:00
drm_gem_object_get ( exp_info - > priv ) ;
2016-10-05 15:21:44 +03:00
return dma_buf ;
}
EXPORT_SYMBOL ( drm_gem_dmabuf_export ) ;
2014-01-22 22:16:30 +04:00
/**
* drm_gem_dmabuf_release - dma_buf release implementation for GEM
* @ dma_buf : buffer to be released
*
* Generic release function for dma_bufs exported as PRIME buffers . GEM drivers
* must use this in their dma_buf ops structure as the release callback .
2016-10-05 15:21:44 +03:00
* drm_gem_dmabuf_release ( ) should be used in conjunction with
* drm_gem_dmabuf_export ( ) .
2014-01-22 22:16:30 +04:00
*/
2013-08-15 02:02:30 +04:00
void drm_gem_dmabuf_release ( struct dma_buf * dma_buf )
2013-01-16 00:47:42 +04:00
{
struct drm_gem_object * obj = dma_buf - > priv ;
2016-10-05 15:21:44 +03:00
struct drm_device * dev = obj - > dev ;
2013-01-16 00:47:42 +04:00
2013-08-15 02:02:46 +04:00
/* drop the reference on the export fd holds */
2017-02-28 17:46:41 +03:00
drm_gem_object_put_unlocked ( obj ) ;
2016-10-05 15:21:44 +03:00
2017-09-26 20:04:00 +03:00
drm_dev_put ( dev ) ;
2013-01-16 00:47:42 +04:00
}
2013-08-15 02:02:30 +04:00
EXPORT_SYMBOL ( drm_gem_dmabuf_release ) ;
2013-01-16 00:47:42 +04:00
2018-01-19 00:44:20 +03:00
/**
* drm_gem_dmabuf_vmap - dma_buf vmap implementation for GEM
* @ dma_buf : buffer to be mapped
*
* Sets up a kernel virtual mapping . This can be used as the & dma_buf_ops . vmap
* callback .
*
* Returns the kernel virtual address .
*/
2018-01-05 00:12:14 +03:00
void * drm_gem_dmabuf_vmap ( struct dma_buf * dma_buf )
2013-01-16 00:47:42 +04:00
{
struct drm_gem_object * obj = dma_buf - > priv ;
struct drm_device * dev = obj - > dev ;
2018-04-24 03:46:08 +03:00
if ( dev - > driver - > gem_prime_vmap )
return dev - > driver - > gem_prime_vmap ( obj ) ;
else
return NULL ;
2013-01-16 00:47:42 +04:00
}
2018-01-05 00:12:14 +03:00
EXPORT_SYMBOL ( drm_gem_dmabuf_vmap ) ;
2013-01-16 00:47:42 +04:00
2018-01-19 00:44:20 +03:00
/**
* drm_gem_dmabuf_vunmap - dma_buf vunmap implementation for GEM
* @ dma_buf : buffer to be unmapped
* @ vaddr : the virtual address of the buffer
*
* Releases a kernel virtual mapping . This can be used as the
* & dma_buf_ops . vunmap callback .
*/
2018-01-05 00:12:14 +03:00
void drm_gem_dmabuf_vunmap ( struct dma_buf * dma_buf , void * vaddr )
2013-01-16 00:47:42 +04:00
{
struct drm_gem_object * obj = dma_buf - > priv ;
struct drm_device * dev = obj - > dev ;
2018-04-24 03:46:08 +03:00
if ( dev - > driver - > gem_prime_vunmap )
dev - > driver - > gem_prime_vunmap ( obj , vaddr ) ;
2013-01-16 00:47:42 +04:00
}
2018-01-05 00:12:14 +03:00
EXPORT_SYMBOL ( drm_gem_dmabuf_vunmap ) ;
2013-01-16 00:47:42 +04:00
2018-01-19 00:44:20 +03:00
/**
* drm_gem_dmabuf_mmap - dma_buf mmap implementation for GEM
* @ dma_buf : buffer to be mapped
* @ vma : virtual address range
*
* Provides memory mapping for the buffer . This can be used as the
* & dma_buf_ops . mmap callback .
*
* Returns 0 on success or a negative error code on failure .
*/
2018-01-05 00:12:14 +03:00
int drm_gem_dmabuf_mmap ( struct dma_buf * dma_buf , struct vm_area_struct * vma )
2013-01-16 00:47:42 +04:00
{
2013-06-28 09:24:53 +04:00
struct drm_gem_object * obj = dma_buf - > priv ;
struct drm_device * dev = obj - > dev ;
if ( ! dev - > driver - > gem_prime_mmap )
return - ENOSYS ;
return dev - > driver - > gem_prime_mmap ( obj , vma ) ;
2013-01-16 00:47:42 +04:00
}
2018-01-05 00:12:14 +03:00
EXPORT_SYMBOL ( drm_gem_dmabuf_mmap ) ;
2013-01-16 00:47:42 +04:00
static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
2013-04-09 11:52:54 +04:00
. attach = drm_gem_map_attach ,
. detach = drm_gem_map_detach ,
2013-01-16 00:47:42 +04:00
. map_dma_buf = drm_gem_map_dma_buf ,
. unmap_dma_buf = drm_gem_unmap_dma_buf ,
. release = drm_gem_dmabuf_release ,
. mmap = drm_gem_dmabuf_mmap ,
. vmap = drm_gem_dmabuf_vmap ,
. vunmap = drm_gem_dmabuf_vunmap ,
} ;
/**
* DOC : PRIME Helpers
*
* Drivers can implement @ gem_prime_export and @ gem_prime_import in terms of
* simpler APIs by using the helper functions @ drm_gem_prime_export and
* @ drm_gem_prime_import . These functions implement dma - buf support in terms of
2015-06-19 16:52:29 +03:00
* six lower - level driver callbacks :
2013-01-16 00:47:42 +04:00
*
* Export callbacks :
*
2015-11-25 20:07:55 +03:00
* * @ gem_prime_pin ( optional ) : prepare a GEM object for exporting
* * @ gem_prime_get_sg_table : provide a scatter / gather table of pinned pages
* * @ gem_prime_vmap : vmap a buffer exported by your driver
* * @ gem_prime_vunmap : vunmap a buffer exported by your driver
* * @ gem_prime_mmap ( optional ) : mmap a buffer exported by your driver
2015-06-19 16:52:29 +03:00
*
2013-01-16 00:47:42 +04:00
* Import callback :
*
2015-11-25 20:07:55 +03:00
* * @ gem_prime_import_sg_table ( import ) : produce a GEM object from another
2013-01-16 00:47:42 +04:00
* driver ' s scatter / gather table
*/
2014-01-22 22:16:30 +04:00
/**
2014-10-20 18:53:13 +04:00
* drm_gem_prime_export - helper library implementation of the export callback
2014-01-22 22:16:30 +04:00
* @ dev : drm_device to export from
* @ obj : GEM object to export
2015-12-23 00:36:44 +03:00
* @ flags : flags like DRM_CLOEXEC and DRM_RDWR
2014-01-22 22:16:30 +04:00
*
* This is the implementation of the gem_prime_export functions for GEM drivers
* using the PRIME helpers .
*/
2013-01-16 00:47:42 +04:00
struct dma_buf * drm_gem_prime_export ( struct drm_device * dev ,
2016-10-05 15:21:43 +03:00
struct drm_gem_object * obj ,
int flags )
2013-01-16 00:47:42 +04:00
{
2016-10-05 15:21:43 +03:00
struct dma_buf_export_info exp_info = {
. exp_name = KBUILD_MODNAME , /* white lie for debug */
. owner = dev - > driver - > fops - > owner ,
. ops = & drm_gem_prime_dmabuf_ops ,
. size = obj - > size ,
. flags = flags ,
. priv = obj ,
} ;
2014-07-01 14:57:26 +04:00
if ( dev - > driver - > gem_prime_res_obj )
2015-01-23 10:23:43 +03:00
exp_info . resv = dev - > driver - > gem_prime_res_obj ( obj ) ;
2014-07-01 14:57:26 +04:00
2016-10-05 15:21:44 +03:00
return drm_gem_dmabuf_export ( dev , & exp_info ) ;
2013-01-16 00:47:42 +04:00
}
EXPORT_SYMBOL ( drm_gem_prime_export ) ;
2013-08-15 02:02:46 +04:00
static struct dma_buf * export_and_register_object ( struct drm_device * dev ,
struct drm_gem_object * obj ,
uint32_t flags )
{
struct dma_buf * dmabuf ;
/* prevent races with concurrent gem_close. */
if ( obj - > handle_count = = 0 ) {
dmabuf = ERR_PTR ( - ENOENT ) ;
return dmabuf ;
}
2018-11-10 17:56:43 +03:00
if ( dev - > driver - > gem_prime_export )
dmabuf = dev - > driver - > gem_prime_export ( dev , obj , flags ) ;
else
dmabuf = drm_gem_prime_export ( dev , obj , flags ) ;
2013-08-15 02:02:46 +04:00
if ( IS_ERR ( dmabuf ) ) {
/* normally the created dma-buf takes ownership of the ref,
* but if that fails then drop the ref
*/
return dmabuf ;
}
/*
* Note that callers do not need to clean up the export cache
* since the check for obj - > handle_count guarantees that someone
* will clean it up .
*/
obj - > dma_buf = dmabuf ;
get_dma_buf ( obj - > dma_buf ) ;
return dmabuf ;
}
2014-01-22 22:16:30 +04:00
/**
* drm_gem_prime_handle_to_fd - PRIME export function for GEM drivers
* @ dev : dev to export the buffer from
* @ file_priv : drm file - private structure
* @ handle : buffer handle to export
* @ flags : flags like DRM_CLOEXEC
* @ prime_fd : pointer to storage for the fd id of the create dma - buf
*
* This is the PRIME export function which must be used mandatorily by GEM
* drivers to ensure correct lifetime management of the underlying GEM object .
* The actual exporting from GEM object to a dma - buf is done through the
* gem_prime_export driver callback .
*/
2011-11-25 19:21:02 +04:00
int drm_gem_prime_handle_to_fd ( struct drm_device * dev ,
2014-01-22 22:16:30 +04:00
struct drm_file * file_priv , uint32_t handle ,
uint32_t flags ,
int * prime_fd )
2011-11-25 19:21:02 +04:00
{
struct drm_gem_object * obj ;
drm/prime: keep a reference from the handle to exported dma-buf (v6)
Currently we have a problem with this:
1. i915: create gem object
2. i915: export gem object to prime
3. radeon: import gem object
4. close prime fd
5. radeon: unref object
6. i915: unref object
i915 has an imported object reference in its file priv, that isn't
cleaned up properly until fd close. The reference gets added at step 2,
but at step 6 we don't have enough info to clean it up.
The solution is to take a reference on the dma-buf when we export it,
and drop the reference when the gem handle goes away.
So when we export a dma_buf from a gem object, we keep track of it
with the handle, we take a reference to the dma_buf. When we close
the handle (i.e. userspace is finished with the buffer), we drop
the reference to the dma_buf, and it gets collected.
This patch isn't meant to fix any other problem or bikesheds, and it doesn't
fix any races with other scenarios.
v1.1: move export symbol line back up.
v2: okay I had to do a bit more, as the first patch showed a leak
on one of my tests, that I found using the dma-buf debugfs support,
the problem case is exporting a buffer twice with the same handle,
we'd add another export handle for it unnecessarily, however
we now fail if we try to export the same object with a different gem handle,
however I'm not sure if that is a case I want to support, and I've
gotten the code to WARN_ON if we hit something like that.
v2.1: rebase this patch, write better commit msg.
v3: cleanup error handling, track import vs export in linked list,
these two patches were separate previously, but seem to work better
like this.
v4: danvet is correct, this code is no longer useful, since the buffer
better exist, so remove it.
v5: always take a reference to the dma buf object, import or export.
(Imre Deak contributed this originally)
v6: square the circle, remove import vs export tracking now
that there is no difference
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-04-22 03:54:36 +04:00
int ret = 0 ;
struct dma_buf * dmabuf ;
2011-11-25 19:21:02 +04:00
2013-08-15 02:02:49 +04:00
mutex_lock ( & file_priv - > prime . lock ) ;
2016-05-09 13:04:54 +03:00
obj = drm_gem_object_lookup ( file_priv , handle ) ;
2013-08-15 02:02:49 +04:00
if ( ! obj ) {
ret = - ENOENT ;
goto out_unlock ;
}
dmabuf = drm_prime_lookup_buf_by_handle ( & file_priv - > prime , handle ) ;
if ( dmabuf ) {
get_dma_buf ( dmabuf ) ;
goto out_have_handle ;
}
2011-11-25 19:21:02 +04:00
2013-08-15 02:02:49 +04:00
mutex_lock ( & dev - > object_name_lock ) ;
2011-11-25 19:21:02 +04:00
/* re-export the original imported object */
if ( obj - > import_attach ) {
drm/prime: keep a reference from the handle to exported dma-buf (v6)
Currently we have a problem with this:
1. i915: create gem object
2. i915: export gem object to prime
3. radeon: import gem object
4. close prime fd
5. radeon: unref object
6. i915: unref object
i915 has an imported object reference in its file priv, that isn't
cleaned up properly until fd close. The reference gets added at step 2,
but at step 6 we don't have enough info to clean it up.
The solution is to take a reference on the dma-buf when we export it,
and drop the reference when the gem handle goes away.
So when we export a dma_buf from a gem object, we keep track of it
with the handle, we take a reference to the dma_buf. When we close
the handle (i.e. userspace is finished with the buffer), we drop
the reference to the dma_buf, and it gets collected.
This patch isn't meant to fix any other problem or bikesheds, and it doesn't
fix any races with other scenarios.
v1.1: move export symbol line back up.
v2: okay I had to do a bit more, as the first patch showed a leak
on one of my tests, that I found using the dma-buf debugfs support,
the problem case is exporting a buffer twice with the same handle,
we'd add another export handle for it unnecessarily, however
we now fail if we try to export the same object with a different gem handle,
however I'm not sure if that is a case I want to support, and I've
gotten the code to WARN_ON if we hit something like that.
v2.1: rebase this patch, write better commit msg.
v3: cleanup error handling, track import vs export in linked list,
these two patches were separate previously, but seem to work better
like this.
v4: danvet is correct, this code is no longer useful, since the buffer
better exist, so remove it.
v5: always take a reference to the dma buf object, import or export.
(Imre Deak contributed this originally)
v6: square the circle, remove import vs export tracking now
that there is no difference
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-04-22 03:54:36 +04:00
dmabuf = obj - > import_attach - > dmabuf ;
2013-08-15 02:02:46 +04:00
get_dma_buf ( dmabuf ) ;
drm/prime: keep a reference from the handle to exported dma-buf (v6)
Currently we have a problem with this:
1. i915: create gem object
2. i915: export gem object to prime
3. radeon: import gem object
4. close prime fd
5. radeon: unref object
6. i915: unref object
i915 has an imported object reference in its file priv, that isn't
cleaned up properly until fd close. The reference gets added at step 2,
but at step 6 we don't have enough info to clean it up.
The solution is to take a reference on the dma-buf when we export it,
and drop the reference when the gem handle goes away.
So when we export a dma_buf from a gem object, we keep track of it
with the handle, we take a reference to the dma_buf. When we close
the handle (i.e. userspace is finished with the buffer), we drop
the reference to the dma_buf, and it gets collected.
This patch isn't meant to fix any other problem or bikesheds, and it doesn't
fix any races with other scenarios.
v1.1: move export symbol line back up.
v2: okay I had to do a bit more, as the first patch showed a leak
on one of my tests, that I found using the dma-buf debugfs support,
the problem case is exporting a buffer twice with the same handle,
we'd add another export handle for it unnecessarily, however
we now fail if we try to export the same object with a different gem handle,
however I'm not sure if that is a case I want to support, and I've
gotten the code to WARN_ON if we hit something like that.
v2.1: rebase this patch, write better commit msg.
v3: cleanup error handling, track import vs export in linked list,
these two patches were separate previously, but seem to work better
like this.
v4: danvet is correct, this code is no longer useful, since the buffer
better exist, so remove it.
v5: always take a reference to the dma buf object, import or export.
(Imre Deak contributed this originally)
v6: square the circle, remove import vs export tracking now
that there is no difference
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-04-22 03:54:36 +04:00
goto out_have_obj ;
2011-11-25 19:21:02 +04:00
}
2013-08-15 02:02:46 +04:00
if ( obj - > dma_buf ) {
get_dma_buf ( obj - > dma_buf ) ;
dmabuf = obj - > dma_buf ;
drm/prime: keep a reference from the handle to exported dma-buf (v6)
Currently we have a problem with this:
1. i915: create gem object
2. i915: export gem object to prime
3. radeon: import gem object
4. close prime fd
5. radeon: unref object
6. i915: unref object
i915 has an imported object reference in its file priv, that isn't
cleaned up properly until fd close. The reference gets added at step 2,
but at step 6 we don't have enough info to clean it up.
The solution is to take a reference on the dma-buf when we export it,
and drop the reference when the gem handle goes away.
So when we export a dma_buf from a gem object, we keep track of it
with the handle, we take a reference to the dma_buf. When we close
the handle (i.e. userspace is finished with the buffer), we drop
the reference to the dma_buf, and it gets collected.
This patch isn't meant to fix any other problem or bikesheds, and it doesn't
fix any races with other scenarios.
v1.1: move export symbol line back up.
v2: okay I had to do a bit more, as the first patch showed a leak
on one of my tests, that I found using the dma-buf debugfs support,
the problem case is exporting a buffer twice with the same handle,
we'd add another export handle for it unnecessarily, however
we now fail if we try to export the same object with a different gem handle,
however I'm not sure if that is a case I want to support, and I've
gotten the code to WARN_ON if we hit something like that.
v2.1: rebase this patch, write better commit msg.
v3: cleanup error handling, track import vs export in linked list,
these two patches were separate previously, but seem to work better
like this.
v4: danvet is correct, this code is no longer useful, since the buffer
better exist, so remove it.
v5: always take a reference to the dma buf object, import or export.
(Imre Deak contributed this originally)
v6: square the circle, remove import vs export tracking now
that there is no difference
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-04-22 03:54:36 +04:00
goto out_have_obj ;
2011-11-25 19:21:02 +04:00
}
drm/prime: keep a reference from the handle to exported dma-buf (v6)
Currently we have a problem with this:
1. i915: create gem object
2. i915: export gem object to prime
3. radeon: import gem object
4. close prime fd
5. radeon: unref object
6. i915: unref object
i915 has an imported object reference in its file priv, that isn't
cleaned up properly until fd close. The reference gets added at step 2,
but at step 6 we don't have enough info to clean it up.
The solution is to take a reference on the dma-buf when we export it,
and drop the reference when the gem handle goes away.
So when we export a dma_buf from a gem object, we keep track of it
with the handle, we take a reference to the dma_buf. When we close
the handle (i.e. userspace is finished with the buffer), we drop
the reference to the dma_buf, and it gets collected.
This patch isn't meant to fix any other problem or bikesheds, and it doesn't
fix any races with other scenarios.
v1.1: move export symbol line back up.
v2: okay I had to do a bit more, as the first patch showed a leak
on one of my tests, that I found using the dma-buf debugfs support,
the problem case is exporting a buffer twice with the same handle,
we'd add another export handle for it unnecessarily, however
we now fail if we try to export the same object with a different gem handle,
however I'm not sure if that is a case I want to support, and I've
gotten the code to WARN_ON if we hit something like that.
v2.1: rebase this patch, write better commit msg.
v3: cleanup error handling, track import vs export in linked list,
these two patches were separate previously, but seem to work better
like this.
v4: danvet is correct, this code is no longer useful, since the buffer
better exist, so remove it.
v5: always take a reference to the dma buf object, import or export.
(Imre Deak contributed this originally)
v6: square the circle, remove import vs export tracking now
that there is no difference
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-04-22 03:54:36 +04:00
2013-08-15 02:02:46 +04:00
dmabuf = export_and_register_object ( dev , obj , flags ) ;
2013-08-15 02:02:41 +04:00
if ( IS_ERR ( dmabuf ) ) {
drm/prime: keep a reference from the handle to exported dma-buf (v6)
Currently we have a problem with this:
1. i915: create gem object
2. i915: export gem object to prime
3. radeon: import gem object
4. close prime fd
5. radeon: unref object
6. i915: unref object
i915 has an imported object reference in its file priv, that isn't
cleaned up properly until fd close. The reference gets added at step 2,
but at step 6 we don't have enough info to clean it up.
The solution is to take a reference on the dma-buf when we export it,
and drop the reference when the gem handle goes away.
So when we export a dma_buf from a gem object, we keep track of it
with the handle, we take a reference to the dma_buf. When we close
the handle (i.e. userspace is finished with the buffer), we drop
the reference to the dma_buf, and it gets collected.
This patch isn't meant to fix any other problem or bikesheds, and it doesn't
fix any races with other scenarios.
v1.1: move export symbol line back up.
v2: okay I had to do a bit more, as the first patch showed a leak
on one of my tests, that I found using the dma-buf debugfs support,
the problem case is exporting a buffer twice with the same handle,
we'd add another export handle for it unnecessarily, however
we now fail if we try to export the same object with a different gem handle,
however I'm not sure if that is a case I want to support, and I've
gotten the code to WARN_ON if we hit something like that.
v2.1: rebase this patch, write better commit msg.
v3: cleanup error handling, track import vs export in linked list,
these two patches were separate previously, but seem to work better
like this.
v4: danvet is correct, this code is no longer useful, since the buffer
better exist, so remove it.
v5: always take a reference to the dma buf object, import or export.
(Imre Deak contributed this originally)
v6: square the circle, remove import vs export tracking now
that there is no difference
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-04-22 03:54:36 +04:00
/* normally the created dma-buf takes ownership of the ref,
* but if that fails then drop the ref
*/
2013-08-15 02:02:41 +04:00
ret = PTR_ERR ( dmabuf ) ;
2013-08-15 02:02:49 +04:00
mutex_unlock ( & dev - > object_name_lock ) ;
drm/prime: keep a reference from the handle to exported dma-buf (v6)
Currently we have a problem with this:
1. i915: create gem object
2. i915: export gem object to prime
3. radeon: import gem object
4. close prime fd
5. radeon: unref object
6. i915: unref object
i915 has an imported object reference in its file priv, that isn't
cleaned up properly until fd close. The reference gets added at step 2,
but at step 6 we don't have enough info to clean it up.
The solution is to take a reference on the dma-buf when we export it,
and drop the reference when the gem handle goes away.
So when we export a dma_buf from a gem object, we keep track of it
with the handle, we take a reference to the dma_buf. When we close
the handle (i.e. userspace is finished with the buffer), we drop
the reference to the dma_buf, and it gets collected.
This patch isn't meant to fix any other problem or bikesheds, and it doesn't
fix any races with other scenarios.
v1.1: move export symbol line back up.
v2: okay I had to do a bit more, as the first patch showed a leak
on one of my tests, that I found using the dma-buf debugfs support,
the problem case is exporting a buffer twice with the same handle,
we'd add another export handle for it unnecessarily, however
we now fail if we try to export the same object with a different gem handle,
however I'm not sure if that is a case I want to support, and I've
gotten the code to WARN_ON if we hit something like that.
v2.1: rebase this patch, write better commit msg.
v3: cleanup error handling, track import vs export in linked list,
these two patches were separate previously, but seem to work better
like this.
v4: danvet is correct, this code is no longer useful, since the buffer
better exist, so remove it.
v5: always take a reference to the dma buf object, import or export.
(Imre Deak contributed this originally)
v6: square the circle, remove import vs export tracking now
that there is no difference
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-04-22 03:54:36 +04:00
goto out ;
}
2013-08-15 02:02:49 +04:00
out_have_obj :
/*
* If we ' ve exported this buffer then cheat and add it to the import list
* so we get the correct handle back . We must do this under the
* protection of dev - > object_name_lock to ensure that a racing gem close
* ioctl doesn ' t miss to remove this buffer handle from the cache .
2012-05-20 20:31:16 +04:00
*/
drm/prime: keep a reference from the handle to exported dma-buf (v6)
Currently we have a problem with this:
1. i915: create gem object
2. i915: export gem object to prime
3. radeon: import gem object
4. close prime fd
5. radeon: unref object
6. i915: unref object
i915 has an imported object reference in its file priv, that isn't
cleaned up properly until fd close. The reference gets added at step 2,
but at step 6 we don't have enough info to clean it up.
The solution is to take a reference on the dma-buf when we export it,
and drop the reference when the gem handle goes away.
So when we export a dma_buf from a gem object, we keep track of it
with the handle, we take a reference to the dma_buf. When we close
the handle (i.e. userspace is finished with the buffer), we drop
the reference to the dma_buf, and it gets collected.
This patch isn't meant to fix any other problem or bikesheds, and it doesn't
fix any races with other scenarios.
v1.1: move export symbol line back up.
v2: okay I had to do a bit more, as the first patch showed a leak
on one of my tests, that I found using the dma-buf debugfs support,
the problem case is exporting a buffer twice with the same handle,
we'd add another export handle for it unnecessarily, however
we now fail if we try to export the same object with a different gem handle,
however I'm not sure if that is a case I want to support, and I've
gotten the code to WARN_ON if we hit something like that.
v2.1: rebase this patch, write better commit msg.
v3: cleanup error handling, track import vs export in linked list,
these two patches were separate previously, but seem to work better
like this.
v4: danvet is correct, this code is no longer useful, since the buffer
better exist, so remove it.
v5: always take a reference to the dma buf object, import or export.
(Imre Deak contributed this originally)
v6: square the circle, remove import vs export tracking now
that there is no difference
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-04-22 03:54:36 +04:00
ret = drm_prime_add_buf_handle ( & file_priv - > prime ,
2013-08-15 02:02:46 +04:00
dmabuf , handle ) ;
2013-08-15 02:02:49 +04:00
mutex_unlock ( & dev - > object_name_lock ) ;
drm/prime: keep a reference from the handle to exported dma-buf (v6)
Currently we have a problem with this:
1. i915: create gem object
2. i915: export gem object to prime
3. radeon: import gem object
4. close prime fd
5. radeon: unref object
6. i915: unref object
i915 has an imported object reference in its file priv, that isn't
cleaned up properly until fd close. The reference gets added at step 2,
but at step 6 we don't have enough info to clean it up.
The solution is to take a reference on the dma-buf when we export it,
and drop the reference when the gem handle goes away.
So when we export a dma_buf from a gem object, we keep track of it
with the handle, we take a reference to the dma_buf. When we close
the handle (i.e. userspace is finished with the buffer), we drop
the reference to the dma_buf, and it gets collected.
This patch isn't meant to fix any other problem or bikesheds, and it doesn't
fix any races with other scenarios.
v1.1: move export symbol line back up.
v2: okay I had to do a bit more, as the first patch showed a leak
on one of my tests, that I found using the dma-buf debugfs support,
the problem case is exporting a buffer twice with the same handle,
we'd add another export handle for it unnecessarily, however
we now fail if we try to export the same object with a different gem handle,
however I'm not sure if that is a case I want to support, and I've
gotten the code to WARN_ON if we hit something like that.
v2.1: rebase this patch, write better commit msg.
v3: cleanup error handling, track import vs export in linked list,
these two patches were separate previously, but seem to work better
like this.
v4: danvet is correct, this code is no longer useful, since the buffer
better exist, so remove it.
v5: always take a reference to the dma buf object, import or export.
(Imre Deak contributed this originally)
v6: square the circle, remove import vs export tracking now
that there is no difference
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-04-22 03:54:36 +04:00
if ( ret )
2013-06-26 05:21:40 +04:00
goto fail_put_dmabuf ;
2012-05-20 20:31:16 +04:00
2013-08-15 02:02:49 +04:00
out_have_handle :
2013-08-15 02:02:41 +04:00
ret = dma_buf_fd ( dmabuf , flags ) ;
2013-08-15 02:02:49 +04:00
/*
* We must _not_ remove the buffer from the handle cache since the newly
* created dma buf is already linked in the global obj - > dma_buf pointer ,
* and that is invariant as long as a userspace gem handle exists .
* Closing the handle will clean out the cache anyway , so we don ' t leak .
*/
2013-07-02 11:18:39 +04:00
if ( ret < 0 ) {
2013-08-15 02:02:49 +04:00
goto fail_put_dmabuf ;
2013-07-02 11:18:39 +04:00
} else {
2013-06-26 05:21:42 +04:00
* prime_fd = ret ;
2013-07-02 11:18:39 +04:00
ret = 0 ;
}
2013-06-26 05:21:40 +04:00
goto out ;
fail_put_dmabuf :
2013-08-15 02:02:41 +04:00
dma_buf_put ( dmabuf ) ;
drm/prime: keep a reference from the handle to exported dma-buf (v6)
Currently we have a problem with this:
1. i915: create gem object
2. i915: export gem object to prime
3. radeon: import gem object
4. close prime fd
5. radeon: unref object
6. i915: unref object
i915 has an imported object reference in its file priv, that isn't
cleaned up properly until fd close. The reference gets added at step 2,
but at step 6 we don't have enough info to clean it up.
The solution is to take a reference on the dma-buf when we export it,
and drop the reference when the gem handle goes away.
So when we export a dma_buf from a gem object, we keep track of it
with the handle, we take a reference to the dma_buf. When we close
the handle (i.e. userspace is finished with the buffer), we drop
the reference to the dma_buf, and it gets collected.
This patch isn't meant to fix any other problem or bikesheds, and it doesn't
fix any races with other scenarios.
v1.1: move export symbol line back up.
v2: okay I had to do a bit more, as the first patch showed a leak
on one of my tests, that I found using the dma-buf debugfs support,
the problem case is exporting a buffer twice with the same handle,
we'd add another export handle for it unnecessarily, however
we now fail if we try to export the same object with a different gem handle,
however I'm not sure if that is a case I want to support, and I've
gotten the code to WARN_ON if we hit something like that.
v2.1: rebase this patch, write better commit msg.
v3: cleanup error handling, track import vs export in linked list,
these two patches were separate previously, but seem to work better
like this.
v4: danvet is correct, this code is no longer useful, since the buffer
better exist, so remove it.
v5: always take a reference to the dma buf object, import or export.
(Imre Deak contributed this originally)
v6: square the circle, remove import vs export tracking now
that there is no difference
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-04-22 03:54:36 +04:00
out :
2017-02-28 17:46:41 +03:00
drm_gem_object_put_unlocked ( obj ) ;
2013-08-15 02:02:49 +04:00
out_unlock :
mutex_unlock ( & file_priv - > prime . lock ) ;
drm/prime: keep a reference from the handle to exported dma-buf (v6)
Currently we have a problem with this:
1. i915: create gem object
2. i915: export gem object to prime
3. radeon: import gem object
4. close prime fd
5. radeon: unref object
6. i915: unref object
i915 has an imported object reference in its file priv, that isn't
cleaned up properly until fd close. The reference gets added at step 2,
but at step 6 we don't have enough info to clean it up.
The solution is to take a reference on the dma-buf when we export it,
and drop the reference when the gem handle goes away.
So when we export a dma_buf from a gem object, we keep track of it
with the handle, we take a reference to the dma_buf. When we close
the handle (i.e. userspace is finished with the buffer), we drop
the reference to the dma_buf, and it gets collected.
This patch isn't meant to fix any other problem or bikesheds, and it doesn't
fix any races with other scenarios.
v1.1: move export symbol line back up.
v2: okay I had to do a bit more, as the first patch showed a leak
on one of my tests, that I found using the dma-buf debugfs support,
the problem case is exporting a buffer twice with the same handle,
we'd add another export handle for it unnecessarily, however
we now fail if we try to export the same object with a different gem handle,
however I'm not sure if that is a case I want to support, and I've
gotten the code to WARN_ON if we hit something like that.
v2.1: rebase this patch, write better commit msg.
v3: cleanup error handling, track import vs export in linked list,
these two patches were separate previously, but seem to work better
like this.
v4: danvet is correct, this code is no longer useful, since the buffer
better exist, so remove it.
v5: always take a reference to the dma buf object, import or export.
(Imre Deak contributed this originally)
v6: square the circle, remove import vs export tracking now
that there is no difference
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-04-22 03:54:36 +04:00
return ret ;
2011-11-25 19:21:02 +04:00
}
EXPORT_SYMBOL ( drm_gem_prime_handle_to_fd ) ;
2018-11-10 17:56:44 +03:00
/**
* drm_gem_prime_mmap - PRIME mmap function for GEM drivers
* @ obj : GEM object
* @ vma : Virtual address range
*
* This function sets up a userspace mapping for PRIME exported buffers using
* the same codepath that is used for regular GEM buffer mapping on the DRM fd .
* The fake GEM offset is added to vma - > vm_pgoff and & drm_driver - > fops - > mmap is
* called to set up the mapping .
*
* Drivers can use this as their & drm_driver . gem_prime_mmap callback .
*/
int drm_gem_prime_mmap ( struct drm_gem_object * obj , struct vm_area_struct * vma )
{
/* Used by drm_gem_mmap() to lookup the GEM object */
struct drm_file priv = {
. minor = obj - > dev - > primary ,
} ;
struct file fil = {
. private_data = & priv ,
} ;
int ret ;
ret = drm_vma_node_allow ( & obj - > vma_node , & priv ) ;
if ( ret )
return ret ;
vma - > vm_pgoff + = drm_vma_node_start ( & obj - > vma_node ) ;
ret = obj - > dev - > driver - > fops - > mmap ( & fil , vma ) ;
drm_vma_node_revoke ( & obj - > vma_node , & priv ) ;
return ret ;
}
EXPORT_SYMBOL ( drm_gem_prime_mmap ) ;
2014-01-22 22:16:30 +04:00
/**
2017-05-04 21:45:47 +03:00
* drm_gem_prime_import_dev - core implementation of the import callback
2014-01-22 22:16:30 +04:00
* @ dev : drm_device to import into
* @ dma_buf : dma - buf object to import
2017-05-04 21:45:47 +03:00
* @ attach_dev : struct device to dma_buf attach
2014-01-22 22:16:30 +04:00
*
2017-05-04 21:45:47 +03:00
* This is the core of drm_gem_prime_import . It ' s designed to be called by
* drivers who want to use a different device structure than dev - > dev for
* attaching via dma_buf .
2014-01-22 22:16:30 +04:00
*/
2017-05-04 21:45:47 +03:00
struct drm_gem_object * drm_gem_prime_import_dev ( struct drm_device * dev ,
struct dma_buf * dma_buf ,
struct device * attach_dev )
2013-01-16 00:47:42 +04:00
{
struct dma_buf_attachment * attach ;
struct sg_table * sgt ;
struct drm_gem_object * obj ;
int ret ;
if ( dma_buf - > ops = = & drm_gem_prime_dmabuf_ops ) {
obj = dma_buf - > priv ;
if ( obj - > dev = = dev ) {
/*
* Importing dmabuf exported from out own gem increases
* refcount on gem itself instead of f_count of dmabuf .
*/
2017-02-28 17:46:41 +03:00
drm_gem_object_get ( obj ) ;
2013-01-16 00:47:42 +04:00
return obj ;
}
}
2015-05-08 11:13:45 +03:00
if ( ! dev - > driver - > gem_prime_import_sg_table )
return ERR_PTR ( - EINVAL ) ;
2017-05-04 21:45:47 +03:00
attach = dma_buf_attach ( dma_buf , attach_dev ) ;
2013-01-16 00:47:42 +04:00
if ( IS_ERR ( attach ) )
2013-06-01 14:09:27 +04:00
return ERR_CAST ( attach ) ;
2013-01-16 00:47:42 +04:00
2013-04-19 05:11:56 +04:00
get_dma_buf ( dma_buf ) ;
2013-01-16 00:47:42 +04:00
sgt = dma_buf_map_attachment ( attach , DMA_BIDIRECTIONAL ) ;
2013-12-21 04:43:50 +04:00
if ( IS_ERR ( sgt ) ) {
2013-01-16 00:47:42 +04:00
ret = PTR_ERR ( sgt ) ;
goto fail_detach ;
}
2014-01-09 14:03:14 +04:00
obj = dev - > driver - > gem_prime_import_sg_table ( dev , attach , sgt ) ;
2013-01-16 00:47:42 +04:00
if ( IS_ERR ( obj ) ) {
ret = PTR_ERR ( obj ) ;
goto fail_unmap ;
}
obj - > import_attach = attach ;
return obj ;
fail_unmap :
dma_buf_unmap_attachment ( attach , sgt , DMA_BIDIRECTIONAL ) ;
fail_detach :
dma_buf_detach ( dma_buf , attach ) ;
2013-04-19 05:11:56 +04:00
dma_buf_put ( dma_buf ) ;
2013-01-16 00:47:42 +04:00
return ERR_PTR ( ret ) ;
}
2017-05-04 21:45:47 +03:00
EXPORT_SYMBOL ( drm_gem_prime_import_dev ) ;
/**
* drm_gem_prime_import - helper library implementation of the import callback
* @ dev : drm_device to import into
* @ dma_buf : dma - buf object to import
*
* This is the implementation of the gem_prime_import functions for GEM drivers
* using the PRIME helpers .
*/
struct drm_gem_object * drm_gem_prime_import ( struct drm_device * dev ,
struct dma_buf * dma_buf )
{
return drm_gem_prime_import_dev ( dev , dma_buf , dev - > dev ) ;
}
2013-01-16 00:47:42 +04:00
EXPORT_SYMBOL ( drm_gem_prime_import ) ;
2014-01-22 22:16:30 +04:00
/**
* drm_gem_prime_fd_to_handle - PRIME import function for GEM drivers
* @ dev : dev to export the buffer from
* @ file_priv : drm file - private structure
* @ prime_fd : fd id of the dma - buf which should be imported
* @ handle : pointer to storage for the handle of the imported buffer object
*
* This is the PRIME import function which must be used mandatorily by GEM
* drivers to ensure correct lifetime management of the underlying GEM object .
* The actual importing of GEM object from the dma - buf is done through the
* gem_import_export driver callback .
*/
2011-11-25 19:21:02 +04:00
int drm_gem_prime_fd_to_handle ( struct drm_device * dev ,
2014-01-22 22:16:30 +04:00
struct drm_file * file_priv , int prime_fd ,
uint32_t * handle )
2011-11-25 19:21:02 +04:00
{
struct dma_buf * dma_buf ;
struct drm_gem_object * obj ;
int ret ;
dma_buf = dma_buf_get ( prime_fd ) ;
if ( IS_ERR ( dma_buf ) )
return PTR_ERR ( dma_buf ) ;
mutex_lock ( & file_priv - > prime . lock ) ;
drm/prime: keep a reference from the handle to exported dma-buf (v6)
Currently we have a problem with this:
1. i915: create gem object
2. i915: export gem object to prime
3. radeon: import gem object
4. close prime fd
5. radeon: unref object
6. i915: unref object
i915 has an imported object reference in its file priv, that isn't
cleaned up properly until fd close. The reference gets added at step 2,
but at step 6 we don't have enough info to clean it up.
The solution is to take a reference on the dma-buf when we export it,
and drop the reference when the gem handle goes away.
So when we export a dma_buf from a gem object, we keep track of it
with the handle, we take a reference to the dma_buf. When we close
the handle (i.e. userspace is finished with the buffer), we drop
the reference to the dma_buf, and it gets collected.
This patch isn't meant to fix any other problem or bikesheds, and it doesn't
fix any races with other scenarios.
v1.1: move export symbol line back up.
v2: okay I had to do a bit more, as the first patch showed a leak
on one of my tests, that I found using the dma-buf debugfs support,
the problem case is exporting a buffer twice with the same handle,
we'd add another export handle for it unnecessarily, however
we now fail if we try to export the same object with a different gem handle,
however I'm not sure if that is a case I want to support, and I've
gotten the code to WARN_ON if we hit something like that.
v2.1: rebase this patch, write better commit msg.
v3: cleanup error handling, track import vs export in linked list,
these two patches were separate previously, but seem to work better
like this.
v4: danvet is correct, this code is no longer useful, since the buffer
better exist, so remove it.
v5: always take a reference to the dma buf object, import or export.
(Imre Deak contributed this originally)
v6: square the circle, remove import vs export tracking now
that there is no difference
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-04-22 03:54:36 +04:00
ret = drm_prime_lookup_buf_handle ( & file_priv - > prime ,
2011-11-25 19:21:02 +04:00
dma_buf , handle ) ;
2013-08-15 02:02:43 +04:00
if ( ret = = 0 )
2011-11-25 19:21:02 +04:00
goto out_put ;
/* never seen this one, need to import */
2013-08-15 02:02:46 +04:00
mutex_lock ( & dev - > object_name_lock ) ;
2018-11-10 17:56:43 +03:00
if ( dev - > driver - > gem_prime_import )
obj = dev - > driver - > gem_prime_import ( dev , dma_buf ) ;
else
obj = drm_gem_prime_import ( dev , dma_buf ) ;
2011-11-25 19:21:02 +04:00
if ( IS_ERR ( obj ) ) {
ret = PTR_ERR ( obj ) ;
2013-08-15 02:02:46 +04:00
goto out_unlock ;
}
if ( obj - > dma_buf ) {
WARN_ON ( obj - > dma_buf ! = dma_buf ) ;
} else {
obj - > dma_buf = dma_buf ;
get_dma_buf ( dma_buf ) ;
2011-11-25 19:21:02 +04:00
}
2016-06-09 22:29:19 +03:00
/* _handle_create_tail unconditionally unlocks dev->object_name_lock. */
2013-08-15 02:02:46 +04:00
ret = drm_gem_handle_create_tail ( file_priv , obj , handle ) ;
2017-02-28 17:46:41 +03:00
drm_gem_object_put_unlocked ( obj ) ;
2011-11-25 19:21:02 +04:00
if ( ret )
goto out_put ;
drm/prime: keep a reference from the handle to exported dma-buf (v6)
Currently we have a problem with this:
1. i915: create gem object
2. i915: export gem object to prime
3. radeon: import gem object
4. close prime fd
5. radeon: unref object
6. i915: unref object
i915 has an imported object reference in its file priv, that isn't
cleaned up properly until fd close. The reference gets added at step 2,
but at step 6 we don't have enough info to clean it up.
The solution is to take a reference on the dma-buf when we export it,
and drop the reference when the gem handle goes away.
So when we export a dma_buf from a gem object, we keep track of it
with the handle, we take a reference to the dma_buf. When we close
the handle (i.e. userspace is finished with the buffer), we drop
the reference to the dma_buf, and it gets collected.
This patch isn't meant to fix any other problem or bikesheds, and it doesn't
fix any races with other scenarios.
v1.1: move export symbol line back up.
v2: okay I had to do a bit more, as the first patch showed a leak
on one of my tests, that I found using the dma-buf debugfs support,
the problem case is exporting a buffer twice with the same handle,
we'd add another export handle for it unnecessarily, however
we now fail if we try to export the same object with a different gem handle,
however I'm not sure if that is a case I want to support, and I've
gotten the code to WARN_ON if we hit something like that.
v2.1: rebase this patch, write better commit msg.
v3: cleanup error handling, track import vs export in linked list,
these two patches were separate previously, but seem to work better
like this.
v4: danvet is correct, this code is no longer useful, since the buffer
better exist, so remove it.
v5: always take a reference to the dma buf object, import or export.
(Imre Deak contributed this originally)
v6: square the circle, remove import vs export tracking now
that there is no difference
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
2013-04-22 03:54:36 +04:00
ret = drm_prime_add_buf_handle ( & file_priv - > prime ,
2011-11-25 19:21:02 +04:00
dma_buf , * handle ) ;
2016-06-09 22:29:19 +03:00
mutex_unlock ( & file_priv - > prime . lock ) ;
2011-11-25 19:21:02 +04:00
if ( ret )
goto fail ;
2013-04-19 05:11:56 +04:00
dma_buf_put ( dma_buf ) ;
2011-11-25 19:21:02 +04:00
return 0 ;
fail :
/* hmm, if driver attached, we are relying on the free-object path
* to detach . . which seems ok . .
*/
2013-08-15 02:02:38 +04:00
drm_gem_handle_delete ( file_priv , * handle ) ;
2016-06-09 22:29:19 +03:00
dma_buf_put ( dma_buf ) ;
return ret ;
2013-08-15 02:02:46 +04:00
out_unlock :
2013-08-24 00:46:02 +04:00
mutex_unlock ( & dev - > object_name_lock ) ;
2011-11-25 19:21:02 +04:00
out_put :
mutex_unlock ( & file_priv - > prime . lock ) ;
2016-06-09 22:29:19 +03:00
dma_buf_put ( dma_buf ) ;
2011-11-25 19:21:02 +04:00
return ret ;
}
EXPORT_SYMBOL ( drm_gem_prime_fd_to_handle ) ;
int drm_prime_handle_to_fd_ioctl ( struct drm_device * dev , void * data ,
struct drm_file * file_priv )
{
struct drm_prime_handle * args = data ;
if ( ! drm_core_check_feature ( dev , DRIVER_PRIME ) )
2018-09-13 22:20:50 +03:00
return - EOPNOTSUPP ;
2011-11-25 19:21:02 +04:00
if ( ! dev - > driver - > prime_handle_to_fd )
return - ENOSYS ;
/* check flags are valid */
2015-12-23 00:36:44 +03:00
if ( args - > flags & ~ ( DRM_CLOEXEC | DRM_RDWR ) )
2011-11-25 19:21:02 +04:00
return - EINVAL ;
return dev - > driver - > prime_handle_to_fd ( dev , file_priv ,
2015-12-23 00:36:44 +03:00
args - > handle , args - > flags , & args - > fd ) ;
2011-11-25 19:21:02 +04:00
}
int drm_prime_fd_to_handle_ioctl ( struct drm_device * dev , void * data ,
struct drm_file * file_priv )
{
struct drm_prime_handle * args = data ;
if ( ! drm_core_check_feature ( dev , DRIVER_PRIME ) )
2018-09-13 22:20:50 +03:00
return - EOPNOTSUPP ;
2011-11-25 19:21:02 +04:00
if ( ! dev - > driver - > prime_fd_to_handle )
return - ENOSYS ;
return dev - > driver - > prime_fd_to_handle ( dev , file_priv ,
args - > fd , & args - > handle ) ;
}
2014-01-22 22:16:30 +04:00
/**
* drm_prime_pages_to_sg - converts a page array into an sg list
* @ pages : pointer to the array of page pointers to convert
* @ nr_pages : length of the page vector
2011-11-25 19:21:02 +04:00
*
2014-01-22 22:16:30 +04:00
* This helper creates an sg table object from a set of pages
2011-11-25 19:21:02 +04:00
* the driver is responsible for mapping the pages into the
2014-01-22 22:16:30 +04:00
* importers address space for use with dma_buf itself .
2011-11-25 19:21:02 +04:00
*/
2014-06-04 11:18:29 +04:00
struct sg_table * drm_prime_pages_to_sg ( struct page * * pages , unsigned int nr_pages )
2011-11-25 19:21:02 +04:00
{
struct sg_table * sg = NULL ;
int ret ;
sg = kmalloc ( sizeof ( struct sg_table ) , GFP_KERNEL ) ;
2013-06-24 11:40:53 +04:00
if ( ! sg ) {
ret = - ENOMEM ;
2011-11-25 19:21:02 +04:00
goto out ;
2013-06-24 11:40:53 +04:00
}
2011-11-25 19:21:02 +04:00
2013-01-28 17:38:48 +04:00
ret = sg_alloc_table_from_pages ( sg , pages , nr_pages , 0 ,
nr_pages < < PAGE_SHIFT , GFP_KERNEL ) ;
2011-11-25 19:21:02 +04:00
if ( ret )
goto out ;
return sg ;
out :
kfree ( sg ) ;
2013-06-24 11:40:53 +04:00
return ERR_PTR ( ret ) ;
2011-11-25 19:21:02 +04:00
}
EXPORT_SYMBOL ( drm_prime_pages_to_sg ) ;
2014-01-22 22:16:30 +04:00
/**
* drm_prime_sg_to_page_addr_arrays - convert an sg table into a page array
* @ sgt : scatter - gather table to convert
2018-02-27 14:49:57 +03:00
* @ pages : optional array of page pointers to store the page array in
2014-01-22 22:16:30 +04:00
* @ addrs : optional array to store the dma bus address of each page
2018-02-27 14:49:57 +03:00
* @ max_entries : size of both the passed - in arrays
2014-01-22 22:16:30 +04:00
*
* Exports an sg table into an array of pages and addresses . This is currently
* required by the TTM driver in order to do correct fault handling .
*/
2012-05-18 18:40:33 +04:00
int drm_prime_sg_to_page_addr_arrays ( struct sg_table * sgt , struct page * * pages ,
2018-02-27 14:49:57 +03:00
dma_addr_t * addrs , int max_entries )
2012-05-18 18:40:33 +04:00
{
unsigned count ;
struct scatterlist * sg ;
struct page * page ;
2018-02-27 14:49:57 +03:00
u32 len , index ;
2012-05-18 18:40:33 +04:00
dma_addr_t addr ;
2018-02-27 14:49:57 +03:00
index = 0 ;
2012-05-18 18:40:33 +04:00
for_each_sg ( sgt - > sgl , sg , sgt - > nents , count ) {
len = sg - > length ;
page = sg_page ( sg ) ;
addr = sg_dma_address ( sg ) ;
while ( len > 0 ) {
2018-02-27 14:49:57 +03:00
if ( WARN_ON ( index > = max_entries ) )
2012-05-18 18:40:33 +04:00
return - 1 ;
2018-02-27 14:49:57 +03:00
if ( pages )
pages [ index ] = page ;
2012-05-18 18:40:33 +04:00
if ( addrs )
2018-02-27 14:49:57 +03:00
addrs [ index ] = addr ;
2012-05-18 18:40:33 +04:00
page + + ;
addr + = PAGE_SIZE ;
len - = PAGE_SIZE ;
2018-02-27 14:49:57 +03:00
index + + ;
2012-05-18 18:40:33 +04:00
}
}
return 0 ;
}
EXPORT_SYMBOL ( drm_prime_sg_to_page_addr_arrays ) ;
2014-01-22 22:16:30 +04:00
/**
* drm_prime_gem_destroy - helper to clean up a PRIME - imported GEM object
* @ obj : GEM object which was created from a dma - buf
* @ sg : the sg - table which was pinned at import time
*
* This is the cleanup functions which GEM drivers need to call when they use
* @ drm_gem_prime_import to import dma - bufs .
*/
2011-11-25 19:21:02 +04:00
void drm_prime_gem_destroy ( struct drm_gem_object * obj , struct sg_table * sg )
{
struct dma_buf_attachment * attach ;
struct dma_buf * dma_buf ;
attach = obj - > import_attach ;
if ( sg )
dma_buf_unmap_attachment ( attach , sg , DMA_BIDIRECTIONAL ) ;
dma_buf = attach - > dmabuf ;
dma_buf_detach ( attach - > dmabuf , attach ) ;
/* remove the reference */
dma_buf_put ( dma_buf ) ;
}
EXPORT_SYMBOL ( drm_prime_gem_destroy ) ;
void drm_prime_init_file_private ( struct drm_prime_file_private * prime_fpriv )
{
mutex_init ( & prime_fpriv - > lock ) ;
2016-09-26 23:44:14 +03:00
prime_fpriv - > dmabufs = RB_ROOT ;
prime_fpriv - > handles = RB_ROOT ;
2011-11-25 19:21:02 +04:00
}
void drm_prime_destroy_file_private ( struct drm_prime_file_private * prime_fpriv )
{
2013-04-24 20:04:57 +04:00
/* by now drm_gem_release should've made sure the list is empty */
2016-09-26 23:44:14 +03:00
WARN_ON ( ! RB_EMPTY_ROOT ( & prime_fpriv - > dmabufs ) ) ;
2011-11-25 19:21:02 +04:00
}