Commit 6619ccf1 authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

dma-buf: Use struct dma_buf_map in dma_buf_vmap() interfaces



This patch updates dma_buf_vmap() and dma-buf's vmap callback to use
struct dma_buf_map.

The interfaces used to return a buffer address. This address now gets
stored in an instance of the structure that is given as an additional
argument. The functions return an errno code on errors.

Users of the functions are updated accordingly. This is only an interface
change. It is currently expected that dma-buf memory can be accessed with
system memory load/store operations.

v3:
	* update fastrpc driver (kernel test robot)
v2:
	* always clear map parameter in dma_buf_vmap() (Daniel)
	* include dma-buf-heaps and i915 selftests (kernel test robot)

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Acked-by: default avatarSumit Semwal <sumit.semwal@linaro.org>
Acked-by: default avatarChristian König <christian.koenig@amd.com>
Acked-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: default avatarTomasz Figa <tfiga@chromium.org>
Acked-by: default avatarSam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200925115601.23955-3-tzimmermann@suse.de
parent 01fd30da
Loading
Loading
Loading
Loading
+16 −12
Original line number Diff line number Diff line
@@ -1186,46 +1186,50 @@ EXPORT_SYMBOL_GPL(dma_buf_mmap);
 * dma_buf_vmap - Create virtual mapping for the buffer object into kernel
 * address space. Same restrictions as for vmap and friends apply.
 * @dmabuf:	[in]	buffer to vmap
 * @map:	[out]	returns the vmap pointer
 *
 * This call may fail due to lack of virtual mapping address space.
 * These calls are optional in drivers. The intended use for them
 * is for mapping objects linear in kernel space for high use objects.
 * Please attempt to use kmap/kunmap before thinking about these interfaces.
 *
 * Returns NULL on error.
 * Returns 0 on success, or a negative errno code otherwise.
 */
void *dma_buf_vmap(struct dma_buf *dmabuf)
int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
{
	void *ptr;
	struct dma_buf_map ptr;
	int ret = 0;

	dma_buf_map_clear(map);

	if (WARN_ON(!dmabuf))
		return NULL;
		return -EINVAL;

	if (!dmabuf->ops->vmap)
		return NULL;
		return -EINVAL;

	mutex_lock(&dmabuf->lock);
	if (dmabuf->vmapping_counter) {
		dmabuf->vmapping_counter++;
		BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr));
		ptr = dmabuf->vmap_ptr.vaddr;
		*map = dmabuf->vmap_ptr;
		goto out_unlock;
	}

	BUG_ON(dma_buf_map_is_set(&dmabuf->vmap_ptr));

	ptr = dmabuf->ops->vmap(dmabuf);
	if (WARN_ON_ONCE(IS_ERR(ptr)))
		ptr = NULL;
	if (!ptr)
	ret = dmabuf->ops->vmap(dmabuf, &ptr);
	if (WARN_ON_ONCE(ret))
		goto out_unlock;

	dmabuf->vmap_ptr.vaddr = ptr;
	dmabuf->vmap_ptr = ptr;
	dmabuf->vmapping_counter = 1;

	*map = dmabuf->vmap_ptr;

out_unlock:
	mutex_unlock(&dmabuf->lock);
	return ptr;
	return ret;
}
EXPORT_SYMBOL_GPL(dma_buf_vmap);

+6 −2
Original line number Diff line number Diff line
@@ -236,7 +236,7 @@ static int dma_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
	return 0;
}

static void *dma_heap_dma_buf_vmap(struct dma_buf *dmabuf)
static int dma_heap_dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
{
	struct heap_helper_buffer *buffer = dmabuf->priv;
	void *vaddr;
@@ -245,7 +245,11 @@ static void *dma_heap_dma_buf_vmap(struct dma_buf *dmabuf)
	vaddr = dma_heap_buffer_vmap_get(buffer);
	mutex_unlock(&buffer->lock);

	return vaddr;
	if (!vaddr)
		return -ENOMEM;
	dma_buf_map_set_vaddr(map, vaddr);

	return 0;
}

static void dma_heap_dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr)
+7 −6
Original line number Diff line number Diff line
@@ -634,22 +634,23 @@ drm_gem_cma_prime_import_sg_table_vmap(struct drm_device *dev,
{
	struct drm_gem_cma_object *cma_obj;
	struct drm_gem_object *obj;
	void *vaddr;
	struct dma_buf_map map;
	int ret;

	vaddr = dma_buf_vmap(attach->dmabuf);
	if (!vaddr) {
	ret = dma_buf_vmap(attach->dmabuf, &map);
	if (ret) {
		DRM_ERROR("Failed to vmap PRIME buffer\n");
		return ERR_PTR(-ENOMEM);
		return ERR_PTR(ret);
	}

	obj = drm_gem_cma_prime_import_sg_table(dev, attach, sgt);
	if (IS_ERR(obj)) {
		dma_buf_vunmap(attach->dmabuf, vaddr);
		dma_buf_vunmap(attach->dmabuf, map.vaddr);
		return obj;
	}

	cma_obj = to_drm_gem_cma_obj(obj);
	cma_obj->vaddr = vaddr;
	cma_obj->vaddr = map.vaddr;

	return obj;
}
+9 −5
Original line number Diff line number Diff line
@@ -261,13 +261,16 @@ EXPORT_SYMBOL(drm_gem_shmem_unpin);
static void *drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem)
{
	struct drm_gem_object *obj = &shmem->base;
	int ret;
	struct dma_buf_map map;
	int ret = 0;

	if (shmem->vmap_use_count++ > 0)
		return shmem->vaddr;

	if (obj->import_attach) {
		shmem->vaddr = dma_buf_vmap(obj->import_attach->dmabuf);
		ret = dma_buf_vmap(obj->import_attach->dmabuf, &map);
		if (!ret)
			shmem->vaddr = map.vaddr;
	} else {
		pgprot_t prot = PAGE_KERNEL;

@@ -279,11 +282,12 @@ static void *drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem)
			prot = pgprot_writecombine(prot);
		shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT,
				    VM_MAP, prot);
		if (!shmem->vaddr)
			ret = -ENOMEM;
	}

	if (!shmem->vaddr) {
		DRM_DEBUG_KMS("Failed to vmap pages\n");
		ret = -ENOMEM;
	if (ret) {
		DRM_DEBUG_KMS("Failed to vmap pages, error %d\n", ret);
		goto err_put_pages;
	}

+6 −3
Original line number Diff line number Diff line
@@ -662,22 +662,25 @@ EXPORT_SYMBOL(drm_gem_unmap_dma_buf);
/**
 * drm_gem_dmabuf_vmap - dma_buf vmap implementation for GEM
 * @dma_buf: buffer to be mapped
 * @map: the virtual address of the buffer
 *
 * Sets up a kernel virtual mapping. This can be used as the &dma_buf_ops.vmap
 * callback. Calls into &drm_gem_object_funcs.vmap for device specific handling.
 *
 * Returns the kernel virtual address or NULL on failure.
 */
void *drm_gem_dmabuf_vmap(struct dma_buf *dma_buf)
int drm_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map)
{
	struct drm_gem_object *obj = dma_buf->priv;
	void *vaddr;

	vaddr = drm_gem_vmap(obj);
	if (IS_ERR(vaddr))
		vaddr = NULL;
		return PTR_ERR(vaddr);

	return vaddr;
	dma_buf_map_set_vaddr(map, vaddr);

	return 0;
}
EXPORT_SYMBOL(drm_gem_dmabuf_vmap);

Loading