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>
This commit is contained in:

committed by
Daniel Vetter

parent
419fa72a19
commit
3b96eff447
@@ -69,6 +69,46 @@ eb_add_object(struct eb_objects *eb, struct drm_i915_gem_object *obj)
|
|||||||
&eb->buckets[obj->exec_handle & eb->and]);
|
&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 *
|
static struct drm_i915_gem_object *
|
||||||
eb_get_object(struct eb_objects *eb, unsigned long handle)
|
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 */
|
/* reacquire the objects */
|
||||||
eb_reset(eb);
|
eb_reset(eb);
|
||||||
for (i = 0; i < count; i++) {
|
ret = eb_lookup_objects(eb, exec, count, file, objects);
|
||||||
obj = to_intel_bo(drm_gem_object_lookup(dev, file,
|
if (ret)
|
||||||
exec[i].handle));
|
goto err;
|
||||||
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 = i915_gem_execbuffer_reserve(ring, file, objects);
|
ret = i915_gem_execbuffer_reserve(ring, file, objects);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -872,31 +900,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
|
|||||||
|
|
||||||
/* Look up object handles */
|
/* Look up object handles */
|
||||||
INIT_LIST_HEAD(&objects);
|
INIT_LIST_HEAD(&objects);
|
||||||
for (i = 0; i < args->buffer_count; i++) {
|
ret = eb_lookup_objects(eb, exec, args->buffer_count, file, &objects);
|
||||||
struct drm_i915_gem_object *obj;
|
if (ret)
|
||||||
|
goto err;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* take note of the batch buffer before we might reorder the lists */
|
/* take note of the batch buffer before we might reorder the lists */
|
||||||
batch_obj = list_entry(objects.prev,
|
batch_obj = list_entry(objects.prev,
|
||||||
|
Reference in New Issue
Block a user