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>
2012-10-02 21:01:07 +04:00
# include <drm/drmP.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
* the dma_buf priv . This reference is released when the dma_buf
* object goes away in the driver . release function .
*
* 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 .
*
* 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 .
2011-11-25 19:21:02 +04:00
*/
struct drm_prime_member {
struct list_head entry ;
struct dma_buf * dma_buf ;
uint32_t handle ;
} ;
2013-06-19 10:03:05 +04:00
struct drm_prime_attachment {
struct sg_table * sgt ;
enum dma_data_direction dir ;
} ;
2013-06-26 05:21:41 +04:00
static int drm_prime_add_buf_handle ( struct drm_prime_file_private * prime_fpriv , struct dma_buf * dma_buf , uint32_t handle )
{
struct drm_prime_member * member ;
member = kmalloc ( sizeof ( * member ) , GFP_KERNEL ) ;
if ( ! member )
return - ENOMEM ;
get_dma_buf ( dma_buf ) ;
member - > dma_buf = dma_buf ;
member - > handle = handle ;
list_add ( & member - > entry , & prime_fpriv - > head ) ;
return 0 ;
}
2011-11-25 19:21:02 +04:00
2013-04-09 11:52:54 +04:00
static int drm_gem_map_attach ( struct dma_buf * dma_buf ,
struct device * target_dev ,
struct dma_buf_attachment * attach )
{
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 ) ;
}
static void drm_gem_map_detach ( struct dma_buf * dma_buf ,
struct dma_buf_attachment * attach )
{
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 ;
2013-06-19 10:03:05 +04:00
struct sg_table * sgt ;
2013-04-09 11:52:54 +04:00
if ( dev - > driver - > gem_prime_unpin )
dev - > driver - > gem_prime_unpin ( obj ) ;
2013-06-19 10:03:05 +04:00
if ( ! prime_attach )
return ;
sgt = prime_attach - > sgt ;
2013-07-04 11:19:12 +04:00
if ( sgt ) {
if ( prime_attach - > dir ! = DMA_NONE )
dma_unmap_sg ( attach - > dev , sgt - > sgl , sgt - > nents ,
prime_attach - > dir ) ;
sg_free_table ( sgt ) ;
}
2013-06-19 10:03:05 +04:00
kfree ( sgt ) ;
kfree ( prime_attach ) ;
attach - > priv = NULL ;
2013-04-09 11:52:54 +04:00
}
2013-06-26 05:21:42 +04:00
static void drm_prime_remove_buf_handle_locked (
struct drm_prime_file_private * prime_fpriv ,
struct dma_buf * dma_buf )
{
struct drm_prime_member * member , * safe ;
list_for_each_entry_safe ( member , safe , & prime_fpriv - > head , entry ) {
if ( member - > dma_buf = = dma_buf ) {
dma_buf_put ( dma_buf ) ;
list_del ( & member - > entry ) ;
kfree ( member ) ;
}
}
}
2013-01-16 00:47:42 +04:00
static struct sg_table * drm_gem_map_dma_buf ( struct dma_buf_attachment * attach ,
enum dma_data_direction dir )
{
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 ) ) {
2013-06-24 10:34:21 +04:00
if ( ! dma_map_sg ( attach - > dev , sgt - > sgl , sgt - > nents , dir ) ) {
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 ;
}
static void drm_gem_unmap_dma_buf ( struct dma_buf_attachment * attach ,
struct sg_table * sgt , enum dma_data_direction dir )
{
2013-06-19 10:03:05 +04:00
/* nothing to be done here */
2013-01-16 00:47:42 +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 ;
if ( obj - > export_dma_buf = = dma_buf ) {
/* drop the reference on the export fd holds */
obj - > export_dma_buf = NULL ;
drm_gem_object_unreference_unlocked ( obj ) ;
}
}
2013-08-15 02:02:30 +04:00
EXPORT_SYMBOL ( drm_gem_dmabuf_release ) ;
2013-01-16 00:47:42 +04:00
static void * drm_gem_dmabuf_vmap ( struct dma_buf * dma_buf )
{
struct drm_gem_object * obj = dma_buf - > priv ;
struct drm_device * dev = obj - > dev ;
return dev - > driver - > gem_prime_vmap ( obj ) ;
}
static void drm_gem_dmabuf_vunmap ( struct dma_buf * dma_buf , void * vaddr )
{
struct drm_gem_object * obj = dma_buf - > priv ;
struct drm_device * dev = obj - > dev ;
dev - > driver - > gem_prime_vunmap ( obj , vaddr ) ;
}
static void * drm_gem_dmabuf_kmap_atomic ( struct dma_buf * dma_buf ,
unsigned long page_num )
{
return NULL ;
}
static void drm_gem_dmabuf_kunmap_atomic ( struct dma_buf * dma_buf ,
unsigned long page_num , void * addr )
{
}
static void * drm_gem_dmabuf_kmap ( struct dma_buf * dma_buf ,
unsigned long page_num )
{
return NULL ;
}
static void drm_gem_dmabuf_kunmap ( struct dma_buf * dma_buf ,
unsigned long page_num , void * addr )
{
}
static int drm_gem_dmabuf_mmap ( struct dma_buf * dma_buf ,
struct vm_area_struct * vma )
{
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
}
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 ,
. kmap = drm_gem_dmabuf_kmap ,
. kmap_atomic = drm_gem_dmabuf_kmap_atomic ,
. kunmap = drm_gem_dmabuf_kunmap ,
. kunmap_atomic = drm_gem_dmabuf_kunmap_atomic ,
. 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
* five lower - level driver callbacks :
*
* Export callbacks :
*
* - @ 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
*
* Import callback :
*
* - @ gem_prime_import_sg_table ( import ) : produce a GEM object from another
* driver ' s scatter / gather table
*/
struct dma_buf * drm_gem_prime_export ( struct drm_device * dev ,
struct drm_gem_object * obj , int flags )
{
2013-06-19 05:14:20 +04:00
return dma_buf_export ( obj , & drm_gem_prime_dmabuf_ops , obj - > size , flags ) ;
2013-01-16 00:47:42 +04:00
}
EXPORT_SYMBOL ( drm_gem_prime_export ) ;
2011-11-25 19:21:02 +04:00
int drm_gem_prime_handle_to_fd ( struct drm_device * dev ,
struct drm_file * file_priv , uint32_t handle , uint32_t flags ,
int * prime_fd )
{
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
obj = drm_gem_object_lookup ( dev , file_priv , handle ) ;
if ( ! obj )
return - ENOENT ;
/* 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 ;
goto out_have_obj ;
2011-11-25 19:21:02 +04:00
}
if ( obj - > export_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
dmabuf = obj - > export_dma_buf ;
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:41 +04:00
dmabuf = dev - > driver - > gem_prime_export ( dev , obj , flags ) ;
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 ) ;
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:41 +04:00
obj - > export_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
2013-08-15 02:02:42 +04:00
mutex_lock ( & file_priv - > prime . lock ) ;
2012-05-20 20:31:16 +04:00
/* if we've exported this buffer the cheat and add it to the import list
* so we get the correct handle back
*/
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 ,
obj - > export_dma_buf , handle ) ;
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:41 +04:00
ret = dma_buf_fd ( dmabuf , flags ) ;
2013-06-26 05:21:42 +04:00
if ( ret < 0 )
goto fail_rm_handle ;
* prime_fd = ret ;
2011-11-25 19:21:02 +04:00
mutex_unlock ( & file_priv - > prime . lock ) ;
return 0 ;
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_have_obj :
get_dma_buf ( dmabuf ) ;
2013-06-26 05:21:42 +04:00
ret = dma_buf_fd ( dmabuf , flags ) ;
2013-07-02 11:18:39 +04:00
if ( ret < 0 ) {
2013-06-26 05:21:42 +04:00
dma_buf_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 ;
2013-06-26 05:21:42 +04:00
fail_rm_handle :
2013-08-15 02:02:41 +04:00
drm_prime_remove_buf_handle_locked ( & file_priv - > prime ,
dmabuf ) ;
2013-08-15 02:02:42 +04:00
mutex_unlock ( & file_priv - > prime . lock ) ;
2013-06-26 05:21:40 +04:00
fail_put_dmabuf :
/* clear NOT to be checked when releasing dma_buf */
obj - > export_dma_buf = NULL ;
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 :
drm_gem_object_unreference_unlocked ( obj ) ;
return ret ;
2011-11-25 19:21:02 +04:00
}
EXPORT_SYMBOL ( drm_gem_prime_handle_to_fd ) ;
2013-01-16 00:47:42 +04:00
struct drm_gem_object * drm_gem_prime_import ( struct drm_device * dev ,
struct dma_buf * dma_buf )
{
struct dma_buf_attachment * attach ;
struct sg_table * sgt ;
struct drm_gem_object * obj ;
int ret ;
if ( ! dev - > driver - > gem_prime_import_sg_table )
return ERR_PTR ( - EINVAL ) ;
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 .
*/
drm_gem_object_reference ( obj ) ;
return obj ;
}
}
attach = dma_buf_attach ( dma_buf , dev - > dev ) ;
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 ) ;
if ( IS_ERR_OR_NULL ( sgt ) ) {
ret = PTR_ERR ( sgt ) ;
goto fail_detach ;
}
obj = dev - > driver - > gem_prime_import_sg_table ( dev , dma_buf - > size , sgt ) ;
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 ) ;
}
EXPORT_SYMBOL ( drm_gem_prime_import ) ;
2011-11-25 19:21:02 +04:00
int drm_gem_prime_fd_to_handle ( struct drm_device * dev ,
struct drm_file * file_priv , int prime_fd , uint32_t * handle )
{
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 */
obj = dev - > driver - > gem_prime_import ( dev , dma_buf ) ;
if ( IS_ERR ( obj ) ) {
ret = PTR_ERR ( obj ) ;
goto out_put ;
}
ret = drm_gem_handle_create ( file_priv , obj , handle ) ;
drm_gem_object_unreference_unlocked ( obj ) ;
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 ) ;
if ( ret )
goto fail ;
mutex_unlock ( & file_priv - > prime . lock ) ;
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 ) ;
2011-11-25 19:21:02 +04:00
out_put :
dma_buf_put ( dma_buf ) ;
mutex_unlock ( & file_priv - > prime . lock ) ;
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 ;
uint32_t flags ;
if ( ! drm_core_check_feature ( dev , DRIVER_PRIME ) )
return - EINVAL ;
if ( ! dev - > driver - > prime_handle_to_fd )
return - ENOSYS ;
/* check flags are valid */
if ( args - > flags & ~ DRM_CLOEXEC )
return - EINVAL ;
/* we only want to pass DRM_CLOEXEC which is == O_CLOEXEC */
flags = args - > flags & DRM_CLOEXEC ;
return dev - > driver - > prime_handle_to_fd ( dev , file_priv ,
args - > handle , flags , & args - > fd ) ;
}
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 ) )
return - EINVAL ;
if ( ! dev - > driver - > prime_fd_to_handle )
return - ENOSYS ;
return dev - > driver - > prime_fd_to_handle ( dev , file_priv ,
args - > fd , & args - > handle ) ;
}
/*
* drm_prime_pages_to_sg
*
* this helper creates an sg table object from a set of pages
* the driver is responsible for mapping the pages into the
* importers address space
*/
struct sg_table * drm_prime_pages_to_sg ( struct page * * pages , int nr_pages )
{
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 ) ;
2012-05-18 18:40:33 +04:00
/* export 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 */
int drm_prime_sg_to_page_addr_arrays ( struct sg_table * sgt , struct page * * pages ,
dma_addr_t * addrs , int max_pages )
{
unsigned count ;
struct scatterlist * sg ;
struct page * page ;
u32 len , offset ;
int pg_index ;
dma_addr_t addr ;
pg_index = 0 ;
for_each_sg ( sgt - > sgl , sg , sgt - > nents , count ) {
len = sg - > length ;
offset = sg - > offset ;
page = sg_page ( sg ) ;
addr = sg_dma_address ( sg ) ;
while ( len > 0 ) {
if ( WARN_ON ( pg_index > = max_pages ) )
return - 1 ;
pages [ pg_index ] = page ;
if ( addrs )
addrs [ pg_index ] = addr ;
page + + ;
addr + = PAGE_SIZE ;
len - = PAGE_SIZE ;
pg_index + + ;
}
}
return 0 ;
}
EXPORT_SYMBOL ( drm_prime_sg_to_page_addr_arrays ) ;
2011-11-25 19:21:02 +04:00
/* helper function to cleanup a GEM/prime object */
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 )
{
INIT_LIST_HEAD ( & prime_fpriv - > head ) ;
mutex_init ( & prime_fpriv - > lock ) ;
}
EXPORT_SYMBOL ( drm_prime_init_file_private ) ;
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 */
WARN_ON ( ! list_empty ( & prime_fpriv - > head ) ) ;
2011-11-25 19:21:02 +04:00
}
EXPORT_SYMBOL ( drm_prime_destroy_file_private ) ;
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 drm_prime_lookup_buf_handle ( struct drm_prime_file_private * prime_fpriv , struct dma_buf * dma_buf , uint32_t * handle )
2011-11-25 19:21:02 +04:00
{
struct drm_prime_member * member ;
list_for_each_entry ( member , & prime_fpriv - > head , entry ) {
if ( member - > dma_buf = = dma_buf ) {
* handle = member - > handle ;
return 0 ;
}
}
return - ENOENT ;
}
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
EXPORT_SYMBOL ( drm_prime_lookup_buf_handle ) ;
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
void drm_prime_remove_buf_handle ( struct drm_prime_file_private * prime_fpriv , struct dma_buf * dma_buf )
2011-11-25 19:21:02 +04:00
{
mutex_lock ( & prime_fpriv - > lock ) ;
2013-06-26 05:21:42 +04:00
drm_prime_remove_buf_handle_locked ( prime_fpriv , dma_buf ) ;
2011-11-25 19:21:02 +04:00
mutex_unlock ( & prime_fpriv - > 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
EXPORT_SYMBOL ( drm_prime_remove_buf_handle ) ;