diff options
| author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-08 10:53:14 +0000 | 
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-01-17 22:08:01 +0100 | 
| commit | 3b96eff447b4ca34ca8ccd42e2651be2955f34b4 (patch) | |
| tree | fd93c20b96673370f68d28df9ee7602265e67db3 | |
| parent | 419fa72a1973c9ba2fd2c2505dc889f54b857459 (diff) | |
| download | olio-linux-3.10-3b96eff447b4ca34ca8ccd42e2651be2955f34b4.tar.xz olio-linux-3.10-3b96eff447b4ca34ca8ccd42e2651be2955f34b4.zip  | |
drm/i915: Take the handle idr spinlock once for looking up the exec objects
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 86 | 
1 files changed, 46 insertions, 40 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 986eb98f0d2..da103c179e3 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -69,6 +69,46 @@ eb_add_object(struct eb_objects *eb, struct drm_i915_gem_object *obj)  		       &eb->buckets[obj->exec_handle & eb->and]);  } +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) +{ +	int i; + +	spin_lock(&file->table_lock); +	for (i = 0; i < count; i++) { +		struct drm_i915_gem_object *obj; + +		obj = to_intel_bo(idr_find(&file->object_idr, exec[i].handle)); +		if (obj == NULL) { +			spin_unlock(&file->table_lock); +			DRM_DEBUG("Invalid object handle %d at index %d\n", +				   exec[i].handle, i); +			return -ENOENT; +		} + +		if (!list_empty(&obj->exec_list)) { +			spin_unlock(&file->table_lock); +			DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", +				   obj, exec[i].handle, i); +			return -EINVAL; +		} + +		drm_gem_object_reference(&obj->base); +		list_add_tail(&obj->exec_list, objects); + +		obj->exec_handle = exec[i].handle; +		obj->exec_entry = &exec[i]; +		eb_add_object(eb, obj); +	} +	spin_unlock(&file->table_lock); + +	return 0; +} +  static struct drm_i915_gem_object *  eb_get_object(struct eb_objects *eb, unsigned long handle)  { @@ -550,21 +590,9 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,  	/* reacquire the objects */  	eb_reset(eb); -	for (i = 0; i < count; i++) { -		obj = to_intel_bo(drm_gem_object_lookup(dev, file, -							exec[i].handle)); -		if (&obj->base == NULL) { -			DRM_DEBUG("Invalid object handle %d at index %d\n", -				   exec[i].handle, i); -			ret = -ENOENT; -			goto err; -		} - -		list_add_tail(&obj->exec_list, objects); -		obj->exec_handle = exec[i].handle; -		obj->exec_entry = &exec[i]; -		eb_add_object(eb, obj); -	} +	ret = eb_lookup_objects(eb, exec, count, file, objects); +	if (ret) +		goto err;  	ret = i915_gem_execbuffer_reserve(ring, file, objects);  	if (ret) @@ -872,31 +900,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,  	/* Look up object handles */  	INIT_LIST_HEAD(&objects); -	for (i = 0; i < args->buffer_count; i++) { -		struct drm_i915_gem_object *obj; - -		obj = to_intel_bo(drm_gem_object_lookup(dev, file, -							exec[i].handle)); -		if (&obj->base == NULL) { -			DRM_DEBUG("Invalid object handle %d at index %d\n", -				   exec[i].handle, i); -			/* prevent error path from reading uninitialized data */ -			ret = -ENOENT; -			goto err; -		} - -		if (!list_empty(&obj->exec_list)) { -			DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", -				   obj, exec[i].handle, i); -			ret = -EINVAL; -			goto err; -		} - -		list_add_tail(&obj->exec_list, &objects); -		obj->exec_handle = exec[i].handle; -		obj->exec_entry = &exec[i]; -		eb_add_object(eb, obj); -	} +	ret = eb_lookup_objects(eb, exec, args->buffer_count, file, &objects); +	if (ret) +		goto err;  	/* take note of the batch buffer before we might reorder the lists */  	batch_obj = list_entry(objects.prev,  |