aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-01-08 05:53:14 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-01-17 16:08:01 -0500
commit3b96eff447b4ca34ca8ccd42e2651be2955f34b4 (patch)
treefd93c20b96673370f68d28df9ee7602265e67db3
parent419fa72a1973c9ba2fd2c2505dc889f54b857459 (diff)
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.c86
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 986eb98f0d25..da103c179e3f 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)
69 &eb->buckets[obj->exec_handle & eb->and]); 69 &eb->buckets[obj->exec_handle & eb->and]);
70} 70}
71 71
72static int
73eb_lookup_objects(struct eb_objects *eb,
74 struct drm_i915_gem_exec_object2 *exec,
75 int count,
76 struct drm_file *file,
77 struct list_head *objects)
78{
79 int i;
80
81 spin_lock(&file->table_lock);
82 for (i = 0; i < count; i++) {
83 struct drm_i915_gem_object *obj;
84
85 obj = to_intel_bo(idr_find(&file->object_idr, exec[i].handle));
86 if (obj == NULL) {
87 spin_unlock(&file->table_lock);
88 DRM_DEBUG("Invalid object handle %d at index %d\n",
89 exec[i].handle, i);
90 return -ENOENT;
91 }
92
93 if (!list_empty(&obj->exec_list)) {
94 spin_unlock(&file->table_lock);
95 DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n",
96 obj, exec[i].handle, i);
97 return -EINVAL;
98 }
99
100 drm_gem_object_reference(&obj->base);
101 list_add_tail(&obj->exec_list, objects);
102
103 obj->exec_handle = exec[i].handle;
104 obj->exec_entry = &exec[i];
105 eb_add_object(eb, obj);
106 }
107 spin_unlock(&file->table_lock);
108
109 return 0;
110}
111
72static struct drm_i915_gem_object * 112static struct drm_i915_gem_object *
73eb_get_object(struct eb_objects *eb, unsigned long handle) 113eb_get_object(struct eb_objects *eb, unsigned long handle)
74{ 114{
@@ -550,21 +590,9 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev,
550 590
551 /* reacquire the objects */ 591 /* reacquire the objects */
552 eb_reset(eb); 592 eb_reset(eb);
553 for (i = 0; i < count; i++) { 593 ret = eb_lookup_objects(eb, exec, count, file, objects);
554 obj = to_intel_bo(drm_gem_object_lookup(dev, file, 594 if (ret)
555 exec[i].handle)); 595 goto err;
556 if (&obj->base == NULL) {
557 DRM_DEBUG("Invalid object handle %d at index %d\n",
558 exec[i].handle, i);
559 ret = -ENOENT;
560 goto err;
561 }
562
563 list_add_tail(&obj->exec_list, objects);
564 obj->exec_handle = exec[i].handle;
565 obj->exec_entry = &exec[i];
566 eb_add_object(eb, obj);
567 }
568 596
569 ret = i915_gem_execbuffer_reserve(ring, file, objects); 597 ret = i915_gem_execbuffer_reserve(ring, file, objects);
570 if (ret) 598 if (ret)
@@ -872,31 +900,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
872 900
873 /* Look up object handles */ 901 /* Look up object handles */
874 INIT_LIST_HEAD(&objects); 902 INIT_LIST_HEAD(&objects);
875 for (i = 0; i < args->buffer_count; i++) { 903 ret = eb_lookup_objects(eb, exec, args->buffer_count, file, &objects);
876 struct drm_i915_gem_object *obj; 904 if (ret)
877 905 goto err;
878 obj = to_intel_bo(drm_gem_object_lookup(dev, file,
879 exec[i].handle));
880 if (&obj->base == NULL) {
881 DRM_DEBUG("Invalid object handle %d at index %d\n",
882 exec[i].handle, i);
883 /* prevent error path from reading uninitialized data */
884 ret = -ENOENT;
885 goto err;
886 }
887
888 if (!list_empty(&obj->exec_list)) {
889 DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n",
890 obj, exec[i].handle, i);
891 ret = -EINVAL;
892 goto err;
893 }
894
895 list_add_tail(&obj->exec_list, &objects);
896 obj->exec_handle = exec[i].handle;
897 obj->exec_entry = &exec[i];
898 eb_add_object(eb, obj);
899 }
900 906
901 /* take note of the batch buffer before we might reorder the lists */ 907 /* take note of the batch buffer before we might reorder the lists */
902 batch_obj = list_entry(objects.prev, 908 batch_obj = list_entry(objects.prev,