struct dma_buf *dma_buf;
uint32_t handle;
};
+static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle);
-bool drm_prime_check_dmabuf_valid(struct dma_buf *dmabuf)
+static int drm_gem_map_attach(struct dma_buf *dma_buf,
+ struct device *target_dev,
+ struct dma_buf_attachment *attach)
{
- struct file *file = dmabuf->file;
-
- /*
- * There could be a race when drm_gem_prime_handle_to_fd() is requested
- * during __fput() is executed with same dmabuf.
- * Let's suppose that there are process A and B. A creates a gem obj
- * and exports it to dmabuf, B opens gem name which comes from A.
- * And A is closing dmabuf and B tries to import dmabuf at that time.
- * In this case, the dmabuf is in obj->export_dma_buf cache, because
- * gem obj is still valid, and B could get dmabuf from this cache,
- * but this dmabuf is invalid already, so B has to get a new dmabuf
- * directly.
- */
- if (!atomic_long_read(&file->f_count))
- return false;
+ struct drm_gem_object *obj = dma_buf->priv;
+ struct drm_device *dev = obj->dev;
- return true;
+ 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)
+{
+ struct drm_gem_object *obj = dma_buf->priv;
+ struct drm_device *dev = obj->dev;
+
+ if (dev->driver->gem_prime_unpin)
+ dev->driver->gem_prime_unpin(obj);
}
-EXPORT_SYMBOL(drm_prime_check_dmabuf_valid);
static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
enum dma_data_direction dir)
}
static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
+ .attach = drm_gem_map_attach,
+ .detach = drm_gem_map_detach,
.map_dma_buf = drm_gem_map_dma_buf,
.unmap_dma_buf = drm_gem_unmap_dma_buf,
.release = drm_gem_dmabuf_release,
struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj, int flags)
{
- if (dev->driver->gem_prime_pin) {
- int ret = dev->driver->gem_prime_pin(obj);
- if (ret)
- return ERR_PTR(ret);
- }
return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, flags);
}
EXPORT_SYMBOL(drm_gem_prime_export);
}
EXPORT_SYMBOL(drm_prime_destroy_file_private);
-int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t handle)
+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;
list_add(&member->entry, &prime_fpriv->head);
return 0;
}
-EXPORT_SYMBOL(drm_prime_add_buf_handle);
int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpriv, struct dma_buf *dma_buf, uint32_t *handle)
{