Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b464e9a2 authored by Rob Clark's avatar Rob Clark Committed by Dave Airlie
Browse files

drm/i915: use common functions for mmap offset creation



Signed-off-by: default avatarRob Clark <rob@ti.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 75ef8b3b
Loading
Loading
Loading
Loading
+2 −83
Original line number Diff line number Diff line
@@ -1264,74 +1264,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
	}
}

/**
 * i915_gem_create_mmap_offset - create a fake mmap offset for an object
 * @obj: obj in question
 *
 * GEM memory mapping works by handing back to userspace a fake mmap offset
 * it can use in a subsequent mmap(2) call.  The DRM core code then looks
 * up the object based on the offset and sets up the various memory mapping
 * structures.
 *
 * This routine allocates and attaches a fake offset for @obj.
 */
static int
i915_gem_create_mmap_offset(struct drm_i915_gem_object *obj)
{
	struct drm_device *dev = obj->base.dev;
	struct drm_gem_mm *mm = dev->mm_private;
	struct drm_map_list *list;
	struct drm_local_map *map;
	int ret = 0;

	/* Set the object up for mmap'ing */
	list = &obj->base.map_list;
	list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
	if (!list->map)
		return -ENOMEM;

	map = list->map;
	map->type = _DRM_GEM;
	map->size = obj->base.size;
	map->handle = obj;

	/* Get a DRM GEM mmap offset allocated... */
	list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
						    obj->base.size / PAGE_SIZE,
						    0, 0);
	if (!list->file_offset_node) {
		DRM_ERROR("failed to allocate offset for bo %d\n",
			  obj->base.name);
		ret = -ENOSPC;
		goto out_free_list;
	}

	list->file_offset_node = drm_mm_get_block(list->file_offset_node,
						  obj->base.size / PAGE_SIZE,
						  0);
	if (!list->file_offset_node) {
		ret = -ENOMEM;
		goto out_free_list;
	}

	list->hash.key = list->file_offset_node->start;
	ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
	if (ret) {
		DRM_ERROR("failed to add to map hash\n");
		goto out_free_mm;
	}

	return 0;

out_free_mm:
	drm_mm_put_block(list->file_offset_node);
out_free_list:
	kfree(list->map);
	list->map = NULL;

	return ret;
}

/**
 * i915_gem_release_mmap - remove physical page mappings
 * @obj: obj in question
@@ -1360,19 +1292,6 @@ i915_gem_release_mmap(struct drm_i915_gem_object *obj)
	obj->fault_mappable = false;
}

static void
i915_gem_free_mmap_offset(struct drm_i915_gem_object *obj)
{
	struct drm_device *dev = obj->base.dev;
	struct drm_gem_mm *mm = dev->mm_private;
	struct drm_map_list *list = &obj->base.map_list;

	drm_ht_remove_item(&mm->offset_hash, &list->hash);
	drm_mm_put_block(list->file_offset_node);
	kfree(list->map);
	list->map = NULL;
}

static uint32_t
i915_gem_get_gtt_size(struct drm_device *dev, uint32_t size, int tiling_mode)
{
@@ -1485,7 +1404,7 @@ i915_gem_mmap_gtt(struct drm_file *file,
	}

	if (!obj->base.map_list.map) {
		ret = i915_gem_create_mmap_offset(obj);
		ret = drm_gem_create_mmap_offset(&obj->base);
		if (ret)
			goto out;
	}
@@ -3752,7 +3671,7 @@ static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj)
	trace_i915_gem_object_destroy(obj);

	if (obj->base.map_list.map)
		i915_gem_free_mmap_offset(obj);
		drm_gem_free_mmap_offset(&obj->base);

	drm_gem_object_release(&obj->base);
	i915_gem_info_remove_obj(dev_priv, obj->base.size);