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

Commit bcffc3fa authored by Chris Wilson's avatar Chris Wilson Committed by Daniel Vetter
Browse files

drm/i915: Move the execbuffer objects list from the stack into the tracker



Instead of passing around the eb-objects hashtable and a separate object
list, we can include the object list into the eb-objects structure for
convenience.

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarImre Deak <imre.deak@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 3b96eff4
Loading
Loading
Loading
Loading
+27 −31
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@
#include <linux/dma_remapping.h>

struct eb_objects {
	struct list_head objects;
	int and;
	struct hlist_head buckets[0];
};
@@ -53,6 +54,7 @@ eb_create(int size)
		return eb;

	eb->and = count - 1;
	INIT_LIST_HEAD(&eb->objects);
	return eb;
}

@@ -73,8 +75,7 @@ static int
eb_lookup_objects(struct eb_objects *eb,
		  struct drm_i915_gem_exec_object2 *exec,
		  int count,
		  struct drm_file *file,
		  struct list_head *objects)
		  struct drm_file *file)
{
	int i;

@@ -98,7 +99,7 @@ eb_lookup_objects(struct eb_objects *eb,
		}

		drm_gem_object_reference(&obj->base);
		list_add_tail(&obj->exec_list, objects);
		list_add_tail(&obj->exec_list, &eb->objects);

		obj->exec_handle = exec[i].handle;
		obj->exec_entry = &exec[i];
@@ -129,6 +130,15 @@ eb_get_object(struct eb_objects *eb, unsigned long handle)
static void
eb_destroy(struct eb_objects *eb)
{
	while (!list_empty(&eb->objects)) {
		struct drm_i915_gem_object *obj;

		obj = list_first_entry(&eb->objects,
				       struct drm_i915_gem_object,
				       exec_list);
		list_del_init(&obj->exec_list);
		drm_gem_object_unreference(&obj->base);
	}
	kfree(eb);
}

@@ -328,8 +338,7 @@ i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj,

static int
i915_gem_execbuffer_relocate(struct drm_device *dev,
			     struct eb_objects *eb,
			     struct list_head *objects)
			     struct eb_objects *eb)
{
	struct drm_i915_gem_object *obj;
	int ret = 0;
@@ -342,7 +351,7 @@ i915_gem_execbuffer_relocate(struct drm_device *dev,
	 * lockdep complains vehemently.
	 */
	pagefault_disable();
	list_for_each_entry(obj, objects, exec_list) {
	list_for_each_entry(obj, &eb->objects, exec_list) {
		ret = i915_gem_execbuffer_relocate_object(obj, eb);
		if (ret)
			break;
@@ -531,7 +540,6 @@ static int
i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
				  struct drm_file *file,
				  struct intel_ring_buffer *ring,
				  struct list_head *objects,
				  struct eb_objects *eb,
				  struct drm_i915_gem_exec_object2 *exec,
				  int count)
@@ -542,8 +550,8 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
	int i, total, ret;

	/* We may process another execbuffer during the unlock... */
	while (!list_empty(objects)) {
		obj = list_first_entry(objects,
	while (!list_empty(&eb->objects)) {
		obj = list_first_entry(&eb->objects,
				       struct drm_i915_gem_object,
				       exec_list);
		list_del_init(&obj->exec_list);
@@ -590,15 +598,15 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,

	/* reacquire the objects */
	eb_reset(eb);
	ret = eb_lookup_objects(eb, exec, count, file, objects);
	ret = eb_lookup_objects(eb, exec, count, file);
	if (ret)
		goto err;

	ret = i915_gem_execbuffer_reserve(ring, file, objects);
	ret = i915_gem_execbuffer_reserve(ring, file, &eb->objects);
	if (ret)
		goto err;

	list_for_each_entry(obj, objects, exec_list) {
	list_for_each_entry(obj, &eb->objects, exec_list) {
		int offset = obj->exec_entry - exec;
		ret = i915_gem_execbuffer_relocate_object_slow(obj, eb,
							       reloc + reloc_offset[offset]);
@@ -756,7 +764,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
		       struct drm_i915_gem_exec_object2 *exec)
{
	drm_i915_private_t *dev_priv = dev->dev_private;
	struct list_head objects;
	struct eb_objects *eb;
	struct drm_i915_gem_object *batch_obj;
	struct drm_clip_rect *cliprects = NULL;
@@ -899,28 +906,26 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
	}

	/* Look up object handles */
	INIT_LIST_HEAD(&objects);
	ret = eb_lookup_objects(eb, exec, args->buffer_count, file, &objects);
	ret = eb_lookup_objects(eb, exec, args->buffer_count, file);
	if (ret)
		goto err;

	/* take note of the batch buffer before we might reorder the lists */
	batch_obj = list_entry(objects.prev,
	batch_obj = list_entry(eb->objects.prev,
			       struct drm_i915_gem_object,
			       exec_list);

	/* Move the objects en-masse into the GTT, evicting if necessary. */
	ret = i915_gem_execbuffer_reserve(ring, file, &objects);
	ret = i915_gem_execbuffer_reserve(ring, file, &eb->objects);
	if (ret)
		goto err;

	/* The objects are in their final locations, apply the relocations. */
	ret = i915_gem_execbuffer_relocate(dev, eb, &objects);
	ret = i915_gem_execbuffer_relocate(dev, eb);
	if (ret) {
		if (ret == -EFAULT) {
			ret = i915_gem_execbuffer_relocate_slow(dev, file, ring,
								&objects, eb,
								exec,
								eb, exec,
								args->buffer_count);
			BUG_ON(!mutex_is_locked(&dev->struct_mutex));
		}
@@ -943,7 +948,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
	if (flags & I915_DISPATCH_SECURE && !batch_obj->has_global_gtt_mapping)
		i915_gem_gtt_bind_object(batch_obj, batch_obj->cache_level);

	ret = i915_gem_execbuffer_move_to_gpu(ring, &objects);
	ret = i915_gem_execbuffer_move_to_gpu(ring, &eb->objects);
	if (ret)
		goto err;

@@ -997,20 +1002,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,

	trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags);

	i915_gem_execbuffer_move_to_active(&objects, ring);
	i915_gem_execbuffer_move_to_active(&eb->objects, ring);
	i915_gem_execbuffer_retire_commands(dev, file, ring);

err:
	eb_destroy(eb);
	while (!list_empty(&objects)) {
		struct drm_i915_gem_object *obj;

		obj = list_first_entry(&objects,
				       struct drm_i915_gem_object,
				       exec_list);
		list_del_init(&obj->exec_list);
		drm_gem_object_unreference(&obj->base);
	}

	mutex_unlock(&dev->struct_mutex);